package bndtools.editor.workspace;

import java.util.Collections;

import org.bndtools.core.ui.icons.Icons;
import org.eclipse.core.resources.IContainer;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IFolder;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.Path;
import org.eclipse.jface.dialogs.ErrorDialog;
import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.StackLayout;
import org.eclipse.swt.graphics.Color;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.layout.FillLayout;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Label;
import org.eclipse.ui.IWorkbenchPage;
import org.eclipse.ui.PartInitException;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.forms.IManagedForm;
import org.eclipse.ui.forms.SectionPart;
import org.eclipse.ui.forms.events.HyperlinkAdapter;
import org.eclipse.ui.forms.events.HyperlinkEvent;
import org.eclipse.ui.forms.widgets.FormToolkit;
import org.eclipse.ui.forms.widgets.ImageHyperlink;
import org.eclipse.ui.forms.widgets.Section;
import org.eclipse.ui.part.FileEditorInput;

import bndtools.Plugin;
import bndtools.central.Central;

public class WorkspaceMainPart extends SectionPart {

	private final boolean	mainFile;

	private final Color			warningColor;
	private static final Image	bndFileImg	= Icons.image("icons/bndtools-logo-16x16.png");
	private static final Image	extFileImg	= Icons.image("icons/bullet_go.png");
	private static final Image	warningImg	= Icons.image("icons/warning_obj.gif");

	public WorkspaceMainPart(boolean mainFile, Composite parent, FormToolkit toolkit, int style) {
		super(parent, toolkit, style);
		this.mainFile = mainFile;

		warningColor = new Color(parent.getDisplay(), 255, 215, 210);
		createSection(getSection(), toolkit);
	}

	private void createSection(Section section, FormToolkit toolkit) {
		section.setText("Workspace");
		if (mainFile) {
			section.setDescription(
				"This file is used to define your specific settings. Default settings are defined in the files linked below.");
		} else {
			section.setDescription(
				"This file is part of the default Bnd workspace settings. It should not be edited, instead define overrides in the main build.bnd file.");
			section.setTitleBarBackground(warningColor);
		}

		Composite composite = toolkit.createComposite(section, SWT.NONE);
		section.setClient(composite);

		composite.setLayout(new GridLayout(1, false));
	}

	private class FileOpenLinkListener extends HyperlinkAdapter {

		private final IPath path;

		public FileOpenLinkListener(IPath path) {
			this.path = path;
		}

		@Override
		public void linkActivated(HyperlinkEvent e) {
			IFile file = ResourcesPlugin.getWorkspace()
				.getRoot()
				.getFile(path);
			FileEditorInput input = new FileEditorInput(file);

			try {
				IWorkbenchPage page = PlatformUI.getWorkbench()
					.getActiveWorkbenchWindow()
					.getActivePage();
				page.openEditor(input, "bndtools.bndWorkspaceConfigEditor", true);
			} catch (PartInitException ex) {
				ErrorDialog.openError(getSection().getShell(), "Error", "Unable to open editor", ex.getStatus());
			}
		}
	}

	@Override
	public void initialize(final IManagedForm form) {
		super.initialize(form);

		final Composite container = (Composite) getSection().getClient();

		// create a layout stack and the first visible component will be an
		// empty component with "waiting" message
		// this will be replaced by real composite once workspace completes
		final StackLayout stackLayout = new StackLayout();
		container.setLayout(stackLayout);

		Composite labelParent = new Composite(container, SWT.NONE);
		FillLayout fillLayout = new FillLayout();
		fillLayout.marginHeight = fillLayout.marginWidth = 10;
		labelParent.setLayout(fillLayout);

		if (!Central.hasAnyWorkspace()) {
			Label label = new Label(labelParent, SWT.NONE);
			label.setText("Workspace is loading, please wait...");
			label.setBackground(container.getBackground());
			label.setForeground(container.getForeground());
		}

		stackLayout.topControl = labelParent;
		container.layout();

		Central.onAnyWorkspaceAsync(workspace -> {
			IFile buildFile = Central.getWorkspaceBuildFile();
			if (buildFile == null)
				return;

			Composite contents = new Composite(container, SWT.NONE);

			if (!mainFile) {
				ImageHyperlink link = form.getToolkit()
					.createImageHyperlink(contents, SWT.CENTER);
				link.setText("Open main build.bnd file.");
				link.setImage(bndFileImg);
				link.addHyperlinkListener(new FileOpenLinkListener(buildFile.getFullPath()));
			} else {
				IResource[] extFiles;

				IContainer cnfDir = buildFile.getParent();
				IFolder extDir = cnfDir.getFolder(new Path("ext"));
				if (extDir.exists())
					extFiles = extDir.members();
				else
					extFiles = new IResource[0];

				if (extFiles.length > 0) {
					for (IResource extFile : extFiles) {
						if (extFile.getType() == IResource.FILE && "bnd".equalsIgnoreCase(extFile.getFileExtension())) {
							ImageHyperlink link = form.getToolkit()
								.createImageHyperlink(contents, SWT.CENTER);
							link.setText("Open " + extFile.getName());
							link.setImage(extFileImg);
							link.addHyperlinkListener(new FileOpenLinkListener(extFile.getFullPath()));
						}
					}
				} else {
					createMissingExtsWarningPanel(contents, form.getToolkit(), extDir.getFullPath());
				}
			}

			stackLayout.topControl = contents;
			container.layout();
		})
			.onFailure(e -> Plugin.error(Collections.singletonList(e.getMessage())));
	}

	private void createMissingExtsWarningPanel(Composite parent, FormToolkit tk, IPath extPath) {
		Composite composite = tk.createComposite(parent);

		GridLayout layout = new GridLayout(2, false);
		layout.marginHeight = 0;
		layout.marginWidth = 0;
		composite.setLayout(layout);

		Label l1 = tk.createLabel(composite, "image");
		l1.setImage(warningImg);
		Label l2 = tk.createLabel(composite, String.format("No default configuration files found under %s", extPath));
		l2.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false));
	}

	@Override
	public void dispose() {
		super.dispose();
		warningColor.dispose();
	}

}
