package bndtools.utils;

import org.eclipse.jface.action.IAction;
import org.eclipse.jface.dialogs.Dialog;
import org.eclipse.jface.dialogs.IMessageProvider;
import org.eclipse.jface.dialogs.PopupDialog;
import org.eclipse.jface.preference.JFacePreferences;
import org.eclipse.jface.resource.JFaceResources;
import org.eclipse.swt.SWT;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.graphics.Rectangle;
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.Label;
import org.eclipse.ui.IWorkbenchPart;
import org.eclipse.ui.forms.HyperlinkGroup;
import org.eclipse.ui.forms.HyperlinkSettings;
import org.eclipse.ui.forms.IMessage;
import org.eclipse.ui.forms.events.HyperlinkAdapter;
import org.eclipse.ui.forms.events.HyperlinkEvent;
import org.eclipse.ui.forms.widgets.Hyperlink;
import org.eclipse.ui.plugin.AbstractUIPlugin;

import bndtools.Plugin;

public class MessagesPopupDialog extends PopupDialog {

	private final Control			controlAttachment;
	private final IMessage[]		messages;
	private final IWorkbenchPart	part;
	private final HyperlinkGroup	hyperlinkGroup;

	private final Image				bulletImg	= AbstractUIPlugin
		.imageDescriptorFromPlugin(Plugin.PLUGIN_ID, "/icons/bullet_go.png")
		.createImage();

	public MessagesPopupDialog(Control controlAttachment, IMessage[] messages, IWorkbenchPart part) {
		super(null, PopupDialog.INFOPOPUP_SHELLSTYLE, true, false, false, false, false, null, null);
		this.controlAttachment = controlAttachment;
		this.messages = messages;
		this.part = part;

		this.hyperlinkGroup = new HyperlinkGroup(controlAttachment.getDisplay());
		this.hyperlinkGroup.setHyperlinkUnderlineMode(HyperlinkSettings.UNDERLINE_ALWAYS);

	}

	@Override
	public boolean close() {
		boolean result = super.close();
		bulletImg.dispose();
		return result;
	}

	@SuppressWarnings("unused")
	@Override
	protected Control createDialogArea(Composite parent) {
		Composite composite = (Composite) super.createDialogArea(parent);
		composite.setLayout(new GridLayout(1, false));

		for (int i = 0; i < messages.length; i++) {
			if (i > 0) {
				Label separator = new Label(composite, SWT.SEPARATOR | SWT.HORIZONTAL);
				separator.setLayoutData(new GridData(SWT.FILL, SWT.TOP, false, false, 2, 1));
			}

			// Message Type Image Label
			Composite pnlTitle = new Composite(composite, SWT.NONE);
			pnlTitle.setLayout(new GridLayout(2, false));
			Label lblImage = new Label(pnlTitle, SWT.NONE);
			lblImage.setImage(getMessageImage(messages[i].getMessageType()));

			// Message Label
			StringBuilder builder = new StringBuilder();
			if (messages[i].getPrefix() != null) {
				builder.append(messages[i].getPrefix());
			}
			builder.append(messages[i].getMessage());
			Label lblText = new Label(pnlTitle, SWT.WRAP);
			lblText.setText(builder.toString());
			lblText.setFont(JFaceResources.getFontRegistry()
				.getItalic(JFaceResources.DIALOG_FONT));
			lblText.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));

			// Fix actions, if present
			Object data = messages[i].getData();
			IAction[] fixes;
			if (data instanceof IAction) {
				fixes = new IAction[] {
					(IAction) data
				};
			} else if (data instanceof IAction[]) {
				fixes = (IAction[]) data;
			} else {
				fixes = null;
			}

			if (fixes != null) {
				// new Label(composite, SWT.SEPARATOR | SWT.HORIZONTAL);
				Composite pnlFixes = new Composite(composite, SWT.NONE);
				pnlFixes.setLayout(new GridLayout(3, false));

				Label lblFixes = new Label(pnlFixes, SWT.NONE);
				lblFixes.setText("Available Fixes:");
				lblFixes.setForeground(JFaceResources.getColorRegistry()
					.get(JFacePreferences.QUALIFIER_COLOR));

				for (int j = 0; j < fixes.length; j++) {
					if (j > 0)
						new Label(pnlFixes, SWT.NONE); // Spacer

					new Label(pnlFixes, SWT.NONE).setImage(bulletImg);

					final IAction fix = fixes[j];
					Hyperlink fixLink = new Hyperlink(pnlFixes, SWT.NONE);
					hyperlinkGroup.add(fixLink);
					fixLink.setText(fix.getText());
					fixLink.setHref(fix);
					fixLink.addHyperlinkListener(new HyperlinkAdapter() {
						@Override
						public void linkActivated(HyperlinkEvent e) {
							fix.run();
							close();
							// part.getSite().getPage().activate(part);
							part.setFocus();
						}
					});
					fixLink.setLayoutData(new GridData(SWT.LEFT, SWT.TOP, false, false));
				}
			}
		}

		return composite;
	}

	@Override
	protected Point getInitialSize() {
		return super.getInitialSize();
	}

	@Override
	protected Point getInitialLocation(Point initialSize) {
		Rectangle linkBounds = controlAttachment.getBounds();
		linkBounds = controlAttachment.getDisplay()
			.map(controlAttachment.getParent(), null, linkBounds);
		return new Point(linkBounds.x, linkBounds.y + linkBounds.height);
	}

	static Image getMessageImage(int messageType) {
		switch (messageType) {
			case IMessageProvider.INFORMATION :
				return JFaceResources.getImage(Dialog.DLG_IMG_MESSAGE_INFO);
			case IMessageProvider.WARNING :
				return JFaceResources.getImage(Dialog.DLG_IMG_MESSAGE_WARNING);
			case IMessageProvider.ERROR :
				return JFaceResources.getImage(Dialog.DLG_IMG_MESSAGE_ERROR);
			default :
				return null;
		}
	}

}
