package bndtools.release.ui;

import java.util.List;

import org.eclipse.jface.dialogs.Dialog;
import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.SashForm;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.events.SelectionListener;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.TableItem;

import bndtools.release.Activator;
import bndtools.release.ProjectDiff;
import bndtools.release.ReleaseHelper;
import bndtools.release.ReleaseHelper.MacroInfo;
import bndtools.release.api.ReleaseOption;
import bndtools.release.nl.Messages;

public class WorkspaceReleaseDialog extends Dialog implements SelectionListener {

	private List<ProjectDiff>	projectDiffs;
	private ProjectListControl	projectListControl;
	private BundleTree			bundleRelease;
	protected SashForm			sashForm;

	private final boolean		showMessage;
	private ReleaseOption		releaseOption;

	public WorkspaceReleaseDialog(Shell parentShell, List<ProjectDiff> projectDiffs, boolean showMessage) {
		super(parentShell);
		super.setShellStyle(SWT.DIALOG_TRIM | SWT.RESIZE | SWT.MAX | SWT.MIN);
		this.projectDiffs = projectDiffs;
		this.showMessage = showMessage;
	}

	@Override
	protected void configureShell(Shell newShell) {
		super.configureShell(newShell);
		newShell.setText(Messages.releaseDialogTitle);
		newShell.setImage(Activator.getImageDescriptor("icons/lorry.png")
			.createImage());

		int width = 640, height = 480;
		int top = -1, left = -1;

		Shell parent = (Shell) newShell.getParent();

		if (parent != null) {
			Point parentSize = parent.getSize();
			Point parentLocation = parent.getLocation();

			width = Math.max(Double.valueOf(parentSize.x * 0.8)
				.intValue(), 640);
			height = Math.max(Double.valueOf(parentSize.y * 0.8)
				.intValue(), 480);

			top = parentLocation.y + ((parentSize.y - height) / 2);
			left = parentLocation.x + ((parentSize.x - width) / 2);
		}

		newShell.setSize(width, height);

		if (top != -1 && left != -1) {
			newShell.setLocation(left, top);
		}
	}

	@Override
	protected Control createDialogArea(Composite parent) {
		Composite composite = (Composite) super.createDialogArea(parent);

		GridData gridData = createFillGridData();

		sashForm = new SashForm(composite, SWT.HORIZONTAL);
		sashForm.setLayout(createGridLayout());
		sashForm.setLayoutData(gridData);

		Composite left = new Composite(sashForm, SWT.NONE);
		left.setLayout(createGridLayout());
		left.setLayoutData(createFillGridData());

		Composite right = new Composite(sashForm, SWT.NONE);
		right.setLayout(createGridLayout());
		right.setLayoutData(createFillGridData());

		String[] items = ReleaseHelper.getReleaseRepositories();

		projectListControl = new ProjectListControl(this, items);
		projectListControl.createControl(left);

		bundleRelease = new BundleTree(right);

		projectListControl.setInput(projectDiffs);

		sashForm.setWeights(new int[] {
			40, 60
		});

		sashForm.pack();

		return sashForm;
	}

	public void setSelected(int index) {

		ProjectDiff projectDiff = null;
		if (projectDiffs.size() > 0) {
			projectListControl.setSelected(index);
			projectDiff = projectDiffs.get(index);
		}

		if (projectDiff != null) {
			bundleRelease.setInput(projectDiff.getBaselines());
			bundleRelease.setVisible(true);
		} else {
			bundleRelease.setVisible(false);
		}

	}

	@Override
	public void widgetSelected(SelectionEvent e) {

		if (e.item == null || e.item.isDisposed()) {
			return;
		}

		ProjectDiff projectDiff = (ProjectDiff) ((TableItem) e.item).getData();
		if (projectDiff != null) {
			if (e.detail > 0) {
				int checkedIndex = -1;
				TableItem[] items = projectListControl.getTable()
					.getItems();
				for (int i = 0; i < items.length; i++) {
					if (items[i] == e.item) {
						checkedIndex = i;
						break;
					}
				}
				TableItem ti = projectListControl.getTable()
					.getItem(checkedIndex);
				boolean checked = ti.getChecked();
				projectDiff.setRelease(checked);

				if (checkedIndex > -1) {
					projectListControl.getTable()
						.deselectAll();
					projectListControl.setSelected(checkedIndex);
				}
			}

			bundleRelease.setInput(projectDiff.getBaselines());
			bundleRelease.setVisible(true);
		} else {
			bundleRelease.setVisible(false);
		}

	}

	@Override
	public void widgetDefaultSelected(SelectionEvent e) {}

	public ReleaseOption getReleaseOption() {
		return releaseOption;
	}

	public boolean isShowMessage() {
		return showMessage;
	}

	private static GridLayout createGridLayout() {
		GridLayout gridLayout = new GridLayout();
		gridLayout.numColumns = 1;
		gridLayout.horizontalSpacing = 0;
		gridLayout.verticalSpacing = 0;
		gridLayout.marginWidth = 0;
		gridLayout.marginHeight = 0;
		return gridLayout;
	}

	private static GridData createFillGridData() {
		return new GridData(GridData.FILL, GridData.FILL, true, true);
	}

	@Override
	protected void okPressed() {
		if (bundleRelease.getReleaseOption() == null) {
			for (ProjectDiff diff : projectDiffs) {
				if (diff.isRelease()) {
					Activator.message(Messages.releaseOptionMustBeSpecified);
					return;
				}
			}
		}
		releaseOption = bundleRelease.getReleaseOption();

		if (releaseOption != ReleaseOption.RELEASE) {
			// Find bundles with macros as Bundle-Version:
			List<MacroInfo> bsns = ReleaseHelper.getBsnsWithBundleVersionMacro(projectDiffs);
			if (bsns.size() > 0) {
				StringBuilder sb = new StringBuilder();
				sb.append(Messages.macrosWillBeOverwritten1);
				sb.append("\n\n");
				for (MacroInfo info : bsns) {
					sb.append("\t");
					sb.append(info.projectDiff.getProject()
						.getName());
					if (!info.projectDiff.getProject()
						.getName()
						.equals(info.bsn)) {
						sb.append(" (");
						sb.append(info.bsn);
						sb.append(")");
					}
					sb.append("    ");
					sb.append(info.macro);
					sb.append("\n");
				}
				sb.append("\n");
				sb.append(Messages.macrosWillBeOverwritten2);

				if (!Activator.confirmationMessage(sb.toString())) {
					return;
				}
			}
		}
		super.okPressed();
	}

	@Override
	public boolean close() {
		if (projectListControl != null) {
			projectListControl.dispose();
		}
		return super.close();
	}
}
