/*******************************************************************************
 * Copyright (c) 2004 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.parts;

import java.util.Enumeration;
import java.util.Hashtable;

import org.eclipse.osgi.util.NLS;
import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.StackLayout;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.graphics.Rectangle;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Layout;
import org.eclipse.ui.IMemento;
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.internal.intro.impl.IIntroConstants;
import org.eclipse.ui.internal.intro.impl.IntroPlugin;
import org.eclipse.ui.internal.intro.impl.Messages;
import org.eclipse.ui.internal.intro.impl.model.AbstractIntroPage;
import org.eclipse.ui.internal.intro.impl.model.IntroModelRoot;
import org.eclipse.ui.internal.intro.impl.model.IntroStandbyContentPart;
import org.eclipse.ui.internal.intro.impl.model.loader.ExtensionPointManager;
import org.eclipse.ui.internal.intro.impl.model.loader.ModelLoaderUtil;
import org.eclipse.ui.internal.intro.impl.util.ImageUtil;
import org.eclipse.ui.internal.intro.impl.util.Log;
import org.eclipse.ui.internal.intro.impl.util.StringUtil;
import org.eclipse.ui.intro.IIntroPart;
import org.eclipse.ui.intro.config.CustomizableIntroPart;
import org.eclipse.ui.intro.config.IStandbyContentPart;

/**
 * Standby part is responsible for managing and creating IStandbycontent parts.
 * It knows how to create and cache content parts. It also handles saving and
 * restoring its own state. It does that by caching the id of the last content
 * part viewed and recreating that part on startup. It also manages the life
 * cycle of content parts by creating and initializing them at the right
 * moments. It also passes the momento at appropriate times to these content
 * parts to enable storing and retrieving of state by content parts. Content
 * parts are responsible for recreating there own state, including input, from
 * the passed momemnto. When the Return to Introduction link is clicked, the
 * Intro goes out of standby content mode, and the standby content parts are not
 * shown anymore until the user explicitly asks for a part again. This is
 * accomplished through a data flag on the CustomizableIntroPart control.
 * 
 */
public class StandbyPart implements IIntroConstants {

    private FormToolkit toolkit;
    private IntroModelRoot model;
    protected ImageHyperlink returnLink;
    protected Control separator;
    private Composite container;
    protected Composite content;
    private IIntroPart introPart;
    private EmptyStandbyContentPart emptyPart;
    private IMemento memento;

    // hastable has partIds as keys, and ControlKeys are values.
    private Hashtable cachedContentParts = new Hashtable();

    private ControlKey cachedControlKey;

    class StandbyLayout extends Layout {

        private int VGAP = 9;
        private int VMARGIN = 5;
        private int HMARGIN = 5;
        private int SEPARATOR_HEIGHT = 1;

        /*
         * (non-Javadoc)
         * 
         * @see org.eclipse.swt.widgets.Layout#computeSize(org.eclipse.swt.widgets.Composite,
         *      int, int, boolean)
         */
        protected Point computeSize(Composite composite, int wHint, int hHint,
                boolean flushCache) {
            Point lsize = returnLink.computeSize(SWT.DEFAULT, SWT.DEFAULT,
                flushCache);
            Point csize = content.computeSize(SWT.DEFAULT, SWT.DEFAULT,
                flushCache);
            int width = Math.max(lsize.x + 2 * HMARGIN, csize.x);
            int height = VMARGIN + lsize.y + VGAP + SEPARATOR_HEIGHT + csize.y;
            return new Point(width, height);
        }

        /*
         * (non-Javadoc)
         * 
         * @see org.eclipse.swt.widgets.Layout#layout(org.eclipse.swt.widgets.Composite,
         *      boolean)
         */
        protected void layout(Composite composite, boolean flushCache) {
            Rectangle carea = composite.getClientArea();
            int lwidth = carea.width - HMARGIN * 2;
            Point lsize = returnLink.computeSize(lwidth, SWT.DEFAULT,
                flushCache);
            int x = HMARGIN;
            int y = VMARGIN;
            returnLink.setBounds(x, y, lsize.x, lsize.y);
            x = 0;
            y += lsize.y + VGAP;
            separator.setBounds(x, y, carea.width, SEPARATOR_HEIGHT);
            y += SEPARATOR_HEIGHT;
            content.setBounds(x, y, carea.width, carea.height - VMARGIN
                    - lsize.y - VGAP - SEPARATOR_HEIGHT);
        }
    }

    /**
     * @param parent
     */
    public StandbyPart(IntroModelRoot model) {
        this.model = model;
    }


    public void init(IIntroPart introPart, IMemento memento) {
        this.introPart = introPart;
        this.memento = memento;
    }

    /*
     * (non-Javadoc)
     * 
     * @see org.eclipse.ui.intro.IIntroPart#saveState(org.eclipse.ui.IMemento)
     */
    private IMemento getMemento(IMemento memento, String key) {
        if (memento == null)
            return null;
        return memento.getChild(key);
    }

    public void createPartControl(Composite parent) {
        toolkit = new FormToolkit(parent.getDisplay());
        // parent container. Has custom layout. Has return link and content
        // stack composite.
        container = toolkit.createComposite(parent);
        container.setLayout(new StandbyLayout());

        // return hyper link.
        ImageUtil.registerImage(ImageUtil.BACK, "full/elcl16/home_nav.gif"); //$NON-NLS-1$
        returnLink = toolkit.createImageHyperlink(container, SWT.WRAP
                | SWT.CENTER);
        returnLink.setImage(ImageUtil.getImage(ImageUtil.BACK));
        returnLink.addHyperlinkListener(new HyperlinkAdapter() {

            public void linkActivated(HyperlinkEvent e) {
                doReturn();
            }
        });

        // create horizontal separator
        separator = toolkit.createCompositeSeparator(container);
        // content stack container
        content = toolkit.createComposite(container);
        StackLayout slayout = new StackLayout();
        slayout.marginWidth = slayout.marginHeight = 0;
        content.setLayout(slayout);

        boolean success = false;
        if (memento != null) {
            success = restoreState(memento);
            if (!success)
                // add empty standby content.
                addAndShowEmptyPart(Messages.StandbyPart_canNotRestore);
        }

        updateReturnLinkLabel();
    }

    /**
     * Empty content part used as backup for failures.
     * 
     */
    private void addAndShowEmptyPart(String message) {
        if (emptyPart == null)
            emptyPart = new EmptyStandbyContentPart();
        addStandbyContentPart(EMPTY_STANDBY_CONTENT_PART, emptyPart);
        emptyPart.setMessage(message);
        setTopControl(EMPTY_STANDBY_CONTENT_PART);
    }

    /**
     * Tries to create the last content part viewed, based on content part id..
     * 
     * @param memento
     * @return
     */
    private boolean restoreState(IMemento memento) {
        String contentPartId = memento
            .getString(MEMENTO_STANDBY_CONTENT_PART_ID_ATT);
        if (contentPartId == null)
            return false;
        // create the cached content part. Content parts are responsible for
        // storing and reading their input state.
        return showContentPart(contentPartId, null);
    }


    /**
     * Sets the into part to standby, and shows the passed standby part, with
     * the given input.
     * 
     * @param partId
     * @param input
     */
    public boolean showContentPart(String partId, String input) {
        // Get the IntroStandbyContentPart that maps to the given partId.
        IntroStandbyContentPart standbyPartContent = ExtensionPointManager
            .getInst().getSharedConfigExtensionsManager()
            .getStandbyPart(partId);

        if (standbyPartContent != null) {
            String standbyContentClassName = standbyPartContent.getClassName();
            String pluginId = standbyPartContent.getPluginId();

            Object standbyContentObject = ModelLoaderUtil.createClassInstance(
                pluginId, standbyContentClassName);
            if (standbyContentObject instanceof IStandbyContentPart) {
                IStandbyContentPart contentPart = (IStandbyContentPart) standbyContentObject;
                Control c = addStandbyContentPart(partId, contentPart);
                if (c != null) {
                    try {
                        setTopControl(partId);
                        setInput(input);
                        return true;
                    } catch (Exception e) {
                        Log.error("Failed to set the input: " + input //$NON-NLS-1$
                                + " on standby part: " + partId, e); //$NON-NLS-1$
                    }
                }

                // failed to create the standby part, show empty part and signal
                // failure.
                String message = NLS.bind(Messages.StandbyPart_failedToCreate,
                    partId);
                addAndShowEmptyPart(message);
                return false;

            }
        }

        // no content part defined with the passed partId, show empty part and
        // signal failure.
        String message = NLS.bind(Messages.StandbyPart_nonDefined, partId);
        addAndShowEmptyPart(message);
        return false;
    }

    /**
     * Creates a standbyContent part in the stack only if one is not already
     * created. The partId is used as tke key in the cache. The value is an
     * instance of ControlKey that wraps a control/StandbyPart pair along with
     * the corresponding part id. This is needed to retrive the control of a
     * given standby part. The IMemento should be passed to the StandbyPart when
     * it is initialized.
     * 
     * @param standbyContent
     */
    public Control addStandbyContentPart(String partId,
            IStandbyContentPart standbyContent) {

        ControlKey controlKey = getCachedContent(partId);
        if (controlKey == null) {

            try {
                standbyContent.init(introPart, getMemento(memento,
                    MEMENTO_STANDBY_CONTENT_PART_TAG));
                standbyContent.createPartControl(content, toolkit);
            } catch (Exception e) {
                // a standby content part throws a PartInitException, log fact.
                Log.error(
                    "Failed to create part for standby part: " + partId, e); //$NON-NLS-1$
                return null;
            }

            Control control = standbyContent.getControl();
            controlKey = new ControlKey(control, standbyContent, partId);
            cachedContentParts.put(partId, controlKey);
            if (partId.equals(EMPTY_STANDBY_CONTENT_PART))
                // just in case it was created explicity, reuse it.
                emptyPart = (EmptyStandbyContentPart) standbyContent;

            if (controlKey.getControl() == null) {
                // control is null. This means that interface was not
                // implemented properly. log fact.
                String message = StringUtil
                    .concat("Standby Content part: ", partId,
                        " has a null Control defined. This prevents the part from being displayed.")
                    .toString();
                Log.error(message, null);
                return null;
            }
        }

        return controlKey.getControl();
    }



    public void setInput(Object input) {
        IStandbyContentPart standbyContent = cachedControlKey.getContentPart();
        standbyContent.setInput(input);
        updateReturnLinkLabel();
        container.layout();
    }


    public void setTopControl(String key) {
        cachedControlKey = getCachedContent(key);
        if (cachedControlKey != null) {
            setTopControl(cachedControlKey.getControl());
        }
    }

    private void setTopControl(Control c) {
        StackLayout layout = (StackLayout) content.getLayout();
        layout.topControl = c;
        if (c instanceof Composite)
            ((Composite) c).layout();
        content.layout();
        container.layout();
    }

    private void updateReturnLinkLabel() {
        String linkText = Messages.StandbyPart_returnToIntro;
        returnLink.setText(linkText);
        AbstractIntroPage page = model.getCurrentPage();
        if (page == null)
            // page will be null in static intro.
            return;

        String toolTip = Messages.StandbyPart_returnTo;
        if (page.getTitle() != null)
            toolTip += " " + page.getTitle(); //$NON-NLS-1$

        returnLink.setToolTipText(toolTip);
    }

    protected void doReturn() {
        // remove the flag to indicate that standbypart is no longer needed.
        ((CustomizableIntroPart) introPart).getControl().setData(
            IIntroConstants.SHOW_STANDBY_PART, null);
        IntroPlugin.setIntroStandby(false);
    }

    /**
     * Calls dispose on all cached IStandbyContentParts.
     * 
     */
    public void dispose() {
        Enumeration values = cachedContentParts.elements();
        while (values.hasMoreElements()) {
            ControlKey controlKey = (ControlKey) values.nextElement();
            controlKey.getContentPart().dispose();
        }
        toolkit.dispose();
    }

    /**
     * Save the current state of the standby part. It stores the cached content
     * part id for later creating it on restart. It also creates another
     * subclass momento to also give the standby content part its own name
     * space. This was momentos saved by different content parts will not
     * conflict.
     * 
     * @param memento
     *            the memento in which to store state information
     */
    public void saveState(IMemento memento) {
        // save cached content part id.
        if (cachedControlKey != null) {
            String contentPartId = cachedControlKey.getContentPartId();
            if (contentPartId == EMPTY_STANDBY_CONTENT_PART)
                // do not create memento for empty standby.
                return;
            memento.putString(MEMENTO_STANDBY_CONTENT_PART_ID_ATT,
                contentPartId);
            // give standby part its own child to create a name space for
            // IStandbyPartContent contribution momentos.
            IMemento standbyContentPartMemento = memento
                .createChild(MEMENTO_STANDBY_CONTENT_PART_TAG);
            // pass new memento to correct standby part.
            IStandbyContentPart standbyContentpart = cachedControlKey
                .getContentPart();
            if (standbyContentpart != null)
                standbyContentpart.saveState(standbyContentPartMemento);
        }
    }


    /*
     * Set focus on the IStandbyContentPart that corresponds to the top control
     * in the stack.
     * 
     * @see org.eclipse.ui.internal.intro.impl.parts.IStandbyContentPart#setFocus()
     */
    public void setFocus() {
        // grab foxus first, then delegate. This way if content part does
        // nothing on focus, part still works.
        returnLink.setFocus();
        if (cachedControlKey != null)
            cachedControlKey.getContentPart().setFocus();
    }



    /**
     * Checks the standby cache stack if we have already created a similar
     * IStandbyContentPart. If not, returns null.
     * 
     * @param standbyContent
     * @return
     */
    private ControlKey getCachedContent(String key) {
        if (cachedContentParts.containsKey(key))
            return (ControlKey) cachedContentParts.get(key);
        return null;
    }

    /*
     * Model class to wrap Control and IStandbyContentPart pairs, along with the
     * representing ID..
     */
    class ControlKey {

        Control c;
        IStandbyContentPart part;
        String contentPartId;

        ControlKey(Control c, IStandbyContentPart part, String contentPartId) {
            this.c = c;
            this.part = part;
            this.contentPartId = contentPartId;
        }

        /**
         * @return Returns the c.
         */
        public Control getControl() {
            return c;
        }

        /**
         * @return Returns the content part.
         */
        public IStandbyContentPart getContentPart() {
            return part;
        }

        /**
         * @return Returns the part id.
         */
        public String getContentPartId() {
            return contentPartId;
        }
    }


}
