/*******************************************************************************
 * Copyright (c) 2004, 2005 Sybase, Inc. and others.
 *
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *
 * Contributors:
 *     Sybase, Inc. - initial API and implementation
 *******************************************************************************/

package org.eclipse.jst.jsf.common.ui.internal.guiutils;

import org.eclipse.core.runtime.IConfigurationElement;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.Path;
import org.eclipse.core.runtime.Platform;
import org.eclipse.help.HelpSystem;
import org.eclipse.help.IContext;
import org.eclipse.help.IHelpResource;
import org.eclipse.jface.action.IAction;
import org.eclipse.jface.resource.ImageDescriptor;
import org.eclipse.jface.resource.ImageRegistry;
import org.eclipse.jface.resource.JFaceResources;
import org.eclipse.jst.jsf.common.ui.JSFUICommonPlugin;
import org.eclipse.jst.jsf.common.ui.internal.logging.Logger;
import org.eclipse.swt.SWT;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.layout.RowLayout;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Label;
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.ExpandableComposite;
import org.eclipse.ui.forms.widgets.FormText;
import org.eclipse.ui.forms.widgets.FormToolkit;
import org.eclipse.ui.forms.widgets.Hyperlink;
import org.eclipse.ui.forms.widgets.ImageHyperlink;
import org.eclipse.ui.forms.widgets.Section;
import org.eclipse.ui.forms.widgets.TableWrapData;
import org.eclipse.ui.forms.widgets.TableWrapLayout;
import org.eclipse.ui.plugin.AbstractUIPlugin;

/**
 * Provides a standard looking introduction section for a intro page for the
 * editors. This was taken and is suppose to look like the standard Sybase
 * workspace service editors intro page.
 * 
 * this was original written by Collinsc
 * 
 * TODO: Should this be moved into the facesconfig ui plugin since it is only
 * really used there?
 * 
 * @author collinsc,jchoi
 */
public class IntroductionSection extends SectionPart {
	private static Logger _log = JSFUICommonPlugin
			.getLogger(IntroductionSection.class);

	private String _editorId;

	private FormToolkit _toolkit;

	// private ImageHyperlink _helpImage;
	private Composite _textClient;

	private String _helpContextId;

	private String _helpTooltip;

	/**
	 * Basic constructor - no help with this one.
	 * 
	 * @param editorId
	 *            id of the editor this page is for.
	 * @param managedForm
	 * @param toolkit
	 */
	public IntroductionSection(String editorId, IManagedForm managedForm,
			FormToolkit toolkit) {
		this(editorId, managedForm, toolkit, null, null);
	}

	/**
	 * Constructor with help option.
	 * 
	 * @param editorId
	 *            id of the editor this page is for.
	 * @param managedForm
	 * @param toolkit
	 * @param contextId 
	 * @param helpTooltip
	 */
	public IntroductionSection(String editorId, IManagedForm managedForm,
			FormToolkit toolkit, final String contextId, String helpTooltip) {
		super(managedForm.getForm().getBody(), toolkit,
				ExpandableComposite.TITLE_BAR | Section.DESCRIPTION);
		super.initialize(managedForm);
		this._editorId = editorId;
		this._toolkit = toolkit;
		this._helpContextId = contextId;
		this._helpTooltip = helpTooltip;

		this._textClient = this._toolkit.createComposite(getSection(), SWT.NONE);
		this._textClient.setSize(32, 16);

		RowLayout rowLayout = new RowLayout();
		rowLayout.wrap = false;
		rowLayout.pack = false;
		rowLayout.justify = true;
		rowLayout.type = SWT.HORIZONTAL;
		rowLayout.marginLeft = 0;
		rowLayout.marginTop = 0;
		rowLayout.marginRight = 0;
		rowLayout.marginBottom = 0;
		rowLayout.spacing = 0;
		this._textClient.setLayout(rowLayout);

		this._toolkit.adapt(this._textClient, true, true);
		getSection().setTextClient(this._textClient);

		if (this._helpContextId != null) {
			// setup the help image.
			ImageHyperlink helpImage = new ImageHyperlink(this._textClient,
					SWT.NONE);
			this._toolkit.adapt(helpImage, true, true);
			helpImage.setImage(JSFUICommonPlugin.getDefault().getImage("help.gif"));
			if (this._helpTooltip != null) {
				helpImage.setToolTipText(this._helpTooltip);
			}
			helpImage.setBackground(getSection()
					.getTitleBarGradientBackground());
			helpImage.addHyperlinkListener(new HyperlinkAdapter() {
				public void linkActivated(HyperlinkEvent e) {
					IContext context = HelpSystem.getContext(_helpContextId);
					if (context != null) {
						IHelpResource[] topics = context.getRelatedTopics();
						if (topics != null && topics.length == 1) {
                            PlatformUI.getWorkbench().getHelpSystem().displayHelpResource(topics[0]
									.getHref());
						} else {
                            PlatformUI.getWorkbench().getHelpSystem().displayHelp(_helpContextId);
						}
					}
				}
			});
		}

		Composite client = this._toolkit.createComposite(getSection());
		createClient(client, this._toolkit);
		getSection().setClient(client);
	}

	private Composite createClient(Composite container, FormToolkit factory) {
		TableWrapLayout layout = new TableWrapLayout();
		layout.numColumns = 2;
		layout.makeColumnsEqualWidth = false;
		layout.horizontalSpacing = 20;
		layout.verticalSpacing = 20;
		container.setLayout(layout);

		IConfigurationElement element = getExtensions();

		if (element != null) {
			setPageDetails(element);

			IConfigurationElement[] children = element.getChildren();
			for (int ii = 0; ii < children.length; ii++) {
				processItems(container, factory, children[ii]);
			}
		} else {
			setText("No Introduction");

			setDescription("No Introduction page configuration found in the plugin.xml");
		}

		factory.paintBordersFor(container);
        PlatformUI.getWorkbench().getHelpSystem().setHelp(container, _helpContextId);
		return container;
	}

	/**
	 * set the page details from the extensionpoint
	 * 
	 * @param element
	 */
	private void setPageDetails(IConfigurationElement element) {
		setText(element.getAttribute("name")); //$NON-NLS-1$
		setDescription(element.getAttribute("description")); //$NON-NLS-1$
	}

	/**
	 * add the extension elements to the page
	 * 
	 * @param parent
	 * @param toolkit_
	 * @param element
	 */
	private void processItems(Composite parent, FormToolkit toolkit_,
			IConfigurationElement element) {
		String hyperlink = element.getAttribute("hyperlink"); //$NON-NLS-1$
		String iconPath = element.getAttribute("icon"); //$NON-NLS-1$
		String text = element.getAttribute("text"); //$NON-NLS-1$
		String heading = element.getAttribute("heading"); //$NON-NLS-1$
		String action = element.getAttribute("hyperlinkaction"); //$NON-NLS-1$
		//String actionparameters = element.getAttribute("actionparameters"); //$NON-NLS-1$

		if (iconPath != null && iconPath.length() > 0) {
			// add an icon to the page
			String iconName;
			if (iconPath.indexOf(IPath.SEPARATOR) != -1) {
				iconName = new Path(iconPath).lastSegment();
			} else {
				iconName = iconPath;
			}

			ImageDescriptor imageDescriptor = AbstractUIPlugin
					.imageDescriptorFromPlugin(
							element.getDeclaringExtension()
									.getContributor().getName(), iconPath);
			
			if (imageDescriptor != null)
			{
				ImageRegistry imageRegistry =
					JSFUICommonPlugin.getDefault().getImageRegistry();
				
				
				Image image = imageRegistry.get(iconName);
				
				if (image == null)
				{
					image = imageDescriptor.createImage();
					
					if (image != null)
					{
						imageRegistry.put(iconName, image);
					}
					else
					{
						image = ImageDescriptor.getMissingImageDescriptor().createImage();
					}
				}
				
				if (image != null)
				{
					ImageContainer img = new ImageContainer(parent);
					img.setImage(image);
					TableWrapData td = new TableWrapData();
					td.rowspan = 2;
					img.setLayoutData(td);
				}
				else
				{
					JSFUICommonPlugin.getLogger(this.getClass()).error(new Throwable("Image not created for "+element));
				}
			}
			else
			{
				JSFUICommonPlugin.getLogger(this.getClass()).error(new Throwable("Image Descriptor not found for "+element));
			}
		}

		if (heading != null && heading.length() > 0) {
			// add a header
			Label lbl = toolkit_.createLabel(parent, heading);
			lbl.setFont(JFaceResources.getHeaderFont());
		}

		if (hyperlink != null && hyperlink.length() > 0) {
			Hyperlink hypr = toolkit_.createHyperlink(parent, hyperlink,
					SWT.NONE);
			if (action != null && action.length() > 0) {
				try {
					final IAction thisAction = (IAction) element
							.createExecutableExtension("hyperlinkaction"); //$NON-NLS-1$
					hypr.addHyperlinkListener(new HyperlinkAdapter() {
						public void linkActivated(HyperlinkEvent e) {
							thisAction.run();
						}
					});
				} catch (Exception ee) {
					// log.IntroductionSection.action.error=Failed to launch the
					// link {0}.
					_log.error("log.IntroductionSection.action.error",
							hyperlink, ee);
					JSFUICommonPlugin.getAlerts().detailError(hyperlink,
							"log.IntroductionSection.action.error", hyperlink,
							ee);
				}
			}
		}

		if (text != null && text.length() > 0) {
			FormText form = toolkit_.createFormText(parent, false);
			form.setText(text, false, false);
		}
	}

	/**
	 * Get the extension elements for the Introduction pages
	 */
	private IConfigurationElement getExtensions() {
		// find all service editor page extensions
		IConfigurationElement element = null;

		// find all service editor parameter dialog extensions
		IConfigurationElement[] elements = Platform
				.getExtensionRegistry()
				.getConfigurationElementsFor(
						"org.eclipse.jst.jsf.common.ui.introductionPage");
		if (elements.length > 0) {
			for (int ii = 0; ii < elements.length; ii++) {
				// get extensions for this dialog
				// String extPluginId =
				// elements[ii].getDeclaringExtension().getNamespace();
				String editorId1 = elements[ii].getDeclaringExtension()
						.getSimpleIdentifier();

				// see if we have any contributuins of dialogs
				if (this._editorId.equals(editorId1)) {
					element = elements[ii];
					break;
				}
			}
		}
		return element;
	}

	private void setText(String text) {
		getSection().setText(text);
	}

	private void setDescription(String text) {
		getSection().setDescription(text);
	}

	/**
	 * Set this section's layout data
	 * @param layoutData
	 */
	public void setLayoutData(Object layoutData) {
		getSection().setLayoutData(layoutData);
	}
}