/*******************************************************************************
 * Copyright (c) 2004, 2016 IBM Corporation 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:
 *     IBM Corporation - initial API and implementation
 *******************************************************************************/
package org.eclipse.ui.internal.intro.impl.swt;

import org.eclipse.swt.SWT;
import org.eclipse.swt.graphics.Color;
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.swt.widgets.Layout;
import org.eclipse.ui.forms.IFormColors;
import org.eclipse.ui.forms.events.HyperlinkAdapter;
import org.eclipse.ui.forms.events.HyperlinkEvent;
import org.eclipse.ui.forms.widgets.Form;
import org.eclipse.ui.forms.widgets.FormToolkit;
import org.eclipse.ui.forms.widgets.ImageHyperlink;
import org.eclipse.ui.forms.widgets.ScrolledPageBook;
import org.eclipse.ui.internal.intro.impl.IIntroConstants;
import org.eclipse.ui.internal.intro.impl.Messages;
import org.eclipse.ui.internal.intro.impl.model.AbstractBaseIntroElement;
import org.eclipse.ui.internal.intro.impl.model.AbstractIntroElement;
import org.eclipse.ui.internal.intro.impl.model.IntroContentProvider;
import org.eclipse.ui.internal.intro.impl.model.IntroGroup;
import org.eclipse.ui.internal.intro.impl.model.IntroHomePage;
import org.eclipse.ui.internal.intro.impl.model.IntroLink;
import org.eclipse.ui.internal.intro.impl.model.IntroModelRoot;
import org.eclipse.ui.internal.intro.impl.model.url.IntroURLParser;
import org.eclipse.ui.internal.intro.impl.util.DialogUtil;
import org.eclipse.ui.internal.intro.impl.util.ImageUtil;
import org.eclipse.ui.internal.intro.impl.util.StringUtil;
import org.eclipse.ui.internal.intro.impl.util.Util;
import org.eclipse.ui.intro.config.IIntroContentProviderSite;

/**
 * A Composite that represents the Root Page. It is swapped in the main page
 * book in the FormIntroPartImplementation class.
 */
public class RootPageForm implements IIntroConstants {

    private FormToolkit toolkit;
    private IntroHomePage rootPage;
    private Form parentForm;
    protected Label descriptionLabel;
    private PageStyleManager rootPageStyleManager;
    private IIntroContentProviderSite site;
	private PageWidgetFactory factory;

    class PageComposite extends Composite {

        public PageComposite(Composite parent, int style) {
            super(parent, style);
        }

        // Do not allow composite to take wHint as-is - layout manager
        // can reject the hint and compute larger width.
        @Override
		public Point computeSize(int wHint, int hHint, boolean changed) {
            return ((RootPageLayout) getLayout()).computeSize(this, wHint,
                hHint, changed);
        }
    }

    class RootPageLayout extends Layout {

        // gap between link composite and description label.
        private int VERTICAL_SPACING = 20;

        private int LABEL_MARGIN_WIDTH = 5;

        /*
         * Custom layout for Root Page Composite.
         */
        @Override
		protected Point computeSize(Composite composite, int wHint, int hHint,
                boolean flushCache) {
            int innerWHint = wHint;
            if (wHint != SWT.DEFAULT)
                innerWHint -= LABEL_MARGIN_WIDTH + LABEL_MARGIN_WIDTH;
            Control[] children = composite.getChildren();
            Point s1 = children[0].computeSize(SWT.DEFAULT, SWT.DEFAULT);
            Point s2 = children[1].computeSize(innerWHint, SWT.DEFAULT);
            s2.x += LABEL_MARGIN_WIDTH;
            int height = 2 * (s2.y + VERTICAL_SPACING + s1.y / 2);
            Point size = new Point(Math.max(s1.x, s2.x), height + 5);
            return size;
        }

        @Override
		protected void layout(Composite composite, boolean flushCache) {
            Control[] children = composite.getChildren();
            Rectangle carea = composite.getClientArea();
            Control content = children[0];
            Control label = children[1];
            Point contentSize = content.computeSize(SWT.DEFAULT, SWT.DEFAULT);
            Point labelSize = label.computeSize(carea.width - 2
                    - LABEL_MARGIN_WIDTH * 2, SWT.DEFAULT);
            content.setBounds(carea.width / 2 - contentSize.x / 2, carea.height
                    / 2 - contentSize.y / 2, contentSize.x, contentSize.y);
            label.setBounds(LABEL_MARGIN_WIDTH, content.getLocation().y
                    + contentSize.y + VERTICAL_SPACING, carea.width
                    - LABEL_MARGIN_WIDTH * 2, labelSize.y);
        }
    }

    private HyperlinkAdapter hyperlinkAdapter = new HyperlinkAdapter() {

        @Override
		public void linkActivated(HyperlinkEvent e) {
            ImageHyperlink imageLink = (ImageHyperlink) e.getSource();
            IntroLink introLink = (IntroLink) imageLink.getData(INTRO_LINK);
            IntroURLParser parser = new IntroURLParser(introLink.getUrl());
            if (parser.hasIntroUrl()) {
                // execute the action embedded in the IntroURL
                parser.getIntroURL().execute();
                return;
            } else if (parser.hasProtocol()) {
                Util.openBrowser(introLink.getUrl());
                return;
            }
            DialogUtil.displayInfoMessage(imageLink.getShell(),
                Messages.HyperlinkAdapter_urlIs + introLink.getUrl());
        }

        @Override
		public void linkEntered(HyperlinkEvent e) {
            ImageHyperlink imageLink = (ImageHyperlink) e.getSource();
            IntroLink introLink = (IntroLink) imageLink.getData(INTRO_LINK);
            updateDescription(introLink.getText());
        }

        @Override
		public void linkExited(HyperlinkEvent e) {
            // empty text on exit.
            updateDescription(""); //$NON-NLS-1$
        }

        private void updateDescription(String text) {
            if (text == null)
                text = ""; //$NON-NLS-1$
            descriptionLabel.setText(text);
            descriptionLabel.getParent().layout();
        }
    };

    /**
     *
     */
    public RootPageForm(FormToolkit toolkit, IntroModelRoot modelRoot,
            Form parentForm) {
        this.toolkit = toolkit;
        this.rootPage = modelRoot.getRootPage();
        this.parentForm = parentForm;
    }

    /**
     * Create the form for the root page. Number of columns there is equal to
     * the number of links.
     *
     * @param pageBook
     */
    public void createPartControl(ScrolledPageBook mainPageBook,
            SharedStyleManager shardStyleManager) {
        // first, create the root page style manager from shared style manager.
        rootPageStyleManager = new PageStyleManager(rootPage, shardStyleManager
            .getProperties());

        // Set title of Main form from root page title.
        parentForm.setText(rootPage.getTitle());

        // Composite for full root page. It has custom layout, and two
        // children: the content composite and the description label.
        Composite rootPageComposite = new PageComposite(mainPageBook
            .getContainer(), SWT.NULL);
        toolkit.adapt(rootPageComposite);

        mainPageBook.registerPage(rootPage.getId(), rootPageComposite);
        rootPageComposite.setLayout(new RootPageLayout());
        // Util.highlight(pageComposite, SWT.COLOR_DARK_CYAN);

        // create the contents composite in the center of the root page.
        createRootPageContent(rootPageComposite);

        // create description label for links description.
        descriptionLabel = createHoverLabel(rootPageComposite);

        // Clear memory. No need for style manager any more.
        rootPageStyleManager = null;
    }

    /**
     * Creates content of the root page.
     */
    private void createRootPageContent(Composite rootPageComposite) {
        // setup page composite/layout
        Composite contentComposite = toolkit.createComposite(rootPageComposite);
        GridData gd = new GridData(GridData.HORIZONTAL_ALIGN_CENTER);
        contentComposite.setLayoutData(gd);
        AbstractIntroElement[] children = (AbstractIntroElement[]) rootPage
            .getChildrenOfType(AbstractIntroElement.GROUP
                    | AbstractIntroElement.LINK | AbstractIntroElement.CONTENT_PROVIDER);
        int numChildren = children.length;
        GridLayout layout = new GridLayout();
        // separate links a bit more.
        layout.horizontalSpacing = rootPageStyleManager
            .getPageHorizantalSpacing();
        layout.verticalSpacing = rootPageStyleManager.getPageVerticalSpacing();
        // set number of columns.
        int numColumns = rootPageStyleManager.getPageNumberOfColumns();
        numColumns = numColumns == 0 ? numChildren : numColumns;
        layout.numColumns = numColumns;
        layout.horizontalSpacing = rootPageStyleManager
            .getPageHorizantalSpacing();
        layout.verticalSpacing = rootPageStyleManager.getPageVerticalSpacing();
        contentComposite.setLayout(layout);
        for (int i = 0; i < children.length; i++) {
            if (((AbstractBaseIntroElement) children[i]).isFiltered())
                continue;
            if (children[i].getType() == AbstractIntroElement.GROUP)
                createGroupContent(contentComposite, (IntroGroup) children[i]);
            else if (children[i].getType() == AbstractIntroElement.LINK)
                createImageHyperlink(contentComposite, (IntroLink) children[i]);
            else if (children[i].getType() == AbstractIntroElement.CONTENT_PROVIDER)
            	createContentProvider(contentComposite, (IntroContentProvider)children[i]);
        }
    }

    /**
     * Creates content of the root page.
     */
    private void createGroupContent(Composite parent, IntroGroup group) {
        AbstractIntroElement[] children = (AbstractIntroElement[]) group
            .getChildrenOfType(AbstractIntroElement.GROUP
                    | AbstractIntroElement.LINK |
                    AbstractIntroElement.CONTENT_PROVIDER);
        int numChildren = children.length;
        // setup page composite/layout
        Composite contentComposite = toolkit.createComposite(parent);
        GridData gd = new GridData(GridData.HORIZONTAL_ALIGN_CENTER);
        gd.horizontalSpan = rootPageStyleManager.getColSpan(group);
        gd.verticalSpan = rootPageStyleManager.getRowSpan(group);
        contentComposite.setLayoutData(gd);
        GridLayout layout = new GridLayout();
        // separate links a bit more.
        layout.horizontalSpacing = 20;
        // set number of columns.
        int numColumns = rootPageStyleManager.getNumberOfColumns(group);
        numColumns = numColumns < 1 ? numChildren : numColumns;
        layout.numColumns = numColumns;
        layout.verticalSpacing = rootPageStyleManager.getVerticalSpacing(group);
        layout.horizontalSpacing = rootPageStyleManager
            .getHorizantalSpacing(group);
        contentComposite.setLayout(layout);
        for (int i = 0; i < children.length; i++) {
            if (((AbstractBaseIntroElement) children[i]).isFiltered())
                continue;
            if (children[i].getType() == AbstractIntroElement.GROUP)
                createGroupContent(contentComposite, (IntroGroup) children[i]);
            else if (children[i].getType() == AbstractIntroElement.LINK)
                createImageHyperlink(contentComposite, (IntroLink) children[i]);
            else if (children[i].getType() == AbstractIntroElement.CONTENT_PROVIDER)
            	createContentProvider(contentComposite, (IntroContentProvider)children[i]);
        }
    }

    /**
     * Creates an Image Hyperlink from an IntroLink. Model object is cached in
     * link.
     *
     * @param body
     * @param link
     */
    private void createImageHyperlink(Composite parent, IntroLink link) {
        // create the container composite that will hold the imageHyperLink and
        // the label for the description.
        Composite container = toolkit.createComposite(parent);
        // Util.highlight(container, SWT.COLOR_CYAN);
        GridData gd = new GridData(GridData.HORIZONTAL_ALIGN_CENTER);
        gd.horizontalSpan = rootPageStyleManager.getColSpan(link);
        gd.verticalSpan = rootPageStyleManager.getRowSpan(link);
        container.setLayoutData(gd);

        GridLayout layout = new GridLayout();
        layout.marginWidth = 0;
        layout.marginHeight = 0;
        container.setLayout(layout);
        ImageHyperlink imageLink = toolkit.createImageHyperlink(container,
            SWT.NULL);
        imageLink.setImage(rootPageStyleManager.getImage(link, "link-icon", //$NON-NLS-1$
            ImageUtil.DEFAULT_ROOT_LINK));
        imageLink.setHoverImage(rootPageStyleManager.getImage(link,
            "hover-icon", null)); //$NON-NLS-1$
        // each link is centered in cell.
        gd = new GridData(GridData.HORIZONTAL_ALIGN_CENTER);
        imageLink.setLayoutData(gd);
        // cache the intro link model object for description and URL.
        imageLink.setData(INTRO_LINK, link);
        imageLink.addHyperlinkListener(hyperlinkAdapter);

        // description label.
        Label linkLabel = toolkit.createLabel(container, link.getLabel());
        gd = new GridData(GridData.HORIZONTAL_ALIGN_CENTER);
        linkLabel.setFont(PageStyleManager.getBannerFont());
        linkLabel.setLayoutData(gd);
    }

    /**
     * Creates a label to display the link description when you hover over a
     * hyperlink.
     *
     * @param body
     */
    private Label createHoverLabel(Composite body) {
        Label label = toolkit.createLabel(body, "", SWT.WRAP); //$NON-NLS-1$
        String key = StringUtil.concat(rootPage.getId(), ".", "hover-text.fg") //$NON-NLS-1$ //$NON-NLS-2$
            .toString();
        Color fg = rootPageStyleManager.getColor(toolkit, key);
        if (fg == null)
            fg = toolkit.getColors().getColor(IFormColors.TITLE);
        label.setForeground(fg);
        label.setAlignment(SWT.CENTER);
        label.setFont(PageStyleManager.getBannerFont());
        return label;
    }

    private void createContentProvider(Composite parent, IntroContentProvider providerElement) {
    	if (factory==null) {
    		factory = new PageWidgetFactory(toolkit, rootPageStyleManager);
    		factory.setContentProviderSite(site);
    	}
        factory.createContentProvider(parent, providerElement);
    }
    public void setContentProviderSite(IIntroContentProviderSite site) {
        this.site = site;
    }
}
