/*******************************************************************************
 * Copyright (c) 2000, 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.jface.wizard;

import java.util.ArrayList;
import java.util.List;

import org.eclipse.jface.dialogs.IDialogSettings;
import org.eclipse.jface.resource.ImageDescriptor;
import org.eclipse.jface.resource.JFaceResources;
import org.eclipse.jface.util.Assert;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.graphics.RGB;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Shell;

/**
 * An abstract base implementation of a wizard. A typical client subclasses
 * <code>Wizard</code> to implement a particular wizard.
 * <p>
 * Subclasses may call the following methods to configure the wizard:
 * <ul>
 * <li><code>addPage</code></li>
 * <li><code>setHelpAvailable</code></li>
 * <li><code>setDefaultPageImageDescriptor</code></li>
 * <li><code>setDialogSettings</code></li>
 * <li><code>setNeedsProgressMonitor</code></li>
 * <li><code>setTitleBarColor</code></li>
 * <li><code>setWindowTitle</code></li>
 * </ul>
 * </p>
 * <p>
 * Subclasses may override these methods if required:
 * <ul>
 * <li>reimplement <code>createPageControls</code></li>
 * <li>reimplement <code>performCancel</code></li>
 * <li>extend <code>addPages</code></li>
 * <li>reimplement <code>performFinish</code></li>
 * <li>extend <code>dispose</code></li>
 * </ul>
 * </p>
 * <p>
 * Note that clients are free to implement <code>IWizard</code> from scratch
 * instead of subclassing <code>Wizard</code>. Correct implementations of
 * <code>IWizard</code> will work with any correct implementation of
 * <code>IWizardPage</code>.
 * </p>
 */
public abstract class Wizard implements IWizard {
    /**
     * Image registry key of the default image for wizard pages (value
     * <code>"org.eclipse.jface.wizard.Wizard.pageImage"</code>).
     */
    public static final String DEFAULT_IMAGE = "org.eclipse.jface.wizard.Wizard.pageImage";//$NON-NLS-1$
    /*
     * Register the default page image
     */
    static {
        JFaceResources.getImageRegistry()
                .put(
                        DEFAULT_IMAGE,
                        ImageDescriptor.createFromFile(Wizard.class,
                                "images/page.gif"));//$NON-NLS-1$
    }

    /**
     * The wizard container this wizard belongs to; <code>null</code> if none.
     */
    private IWizardContainer container = null;

    /**
     * This wizard's list of pages (element type: <code>IWizardPage</code>).
     */
    private List pages = new ArrayList();

    /**
     * Indicates whether this wizard needs a progress monitor.
     */
    private boolean needsProgressMonitor = false;

    /**
     * Indicates whether this wizard needs previous and next buttons even if the
     * wizard has only one page.
     */
    private boolean forcePreviousAndNextButtons = false;

    /**
     * Indicates whether this wizard supports help.
     */
    private boolean isHelpAvailable = false;

    /**
     * The default page image for pages without one of their one;
     * <code>null</code> if none.
     */
    private Image defaultImage = null;

    /**
     * The default page image descriptor, used for creating a default page image
     * if required; <code>null</code> if none.
     */
    private ImageDescriptor defaultImageDescriptor = JFaceResources.getImageRegistry().getDescriptor(DEFAULT_IMAGE);

    /**
     * The color of the wizard title bar; <code>null</code> if none.
     */
    private RGB titleBarColor = null;

    /**
     * The window title string for this wizard; <code>null</code> if none.
     */
    private String windowTitle = null;

    /**
     * The dialog settings for this wizard; <code>null</code> if none.
     */
    private IDialogSettings dialogSettings = null;

    /**
     * Creates a new empty wizard.
     */
    protected Wizard() {
        super();
    }

    /**
     * Adds a new page to this wizard. The page is inserted at the end of the
     * page list.
     * 
     * @param page
     *            the new page
     */
    public void addPage(IWizardPage page) {
        pages.add(page);
        page.setWizard(this);
    }

    /**
     * The <code>Wizard</code> implementation of this <code>IWizard</code>
     * method does nothing. Subclasses should extend if extra pages need to be
     * added before the wizard opens. New pages should be added by calling
     * <code>addPage</code>.
     */
    public void addPages() {
    }

    /*
     * (non-Javadoc) Method declared on IWizard.
     */
    public boolean canFinish() {
        // Default implementation is to check if all pages are complete.
        for (int i = 0; i < pages.size(); i++) {
            if (!((IWizardPage) pages.get(i)).isPageComplete())
                return false;
        }
        return true;
    }

    /**
     * The <code>Wizard</code> implementation of this <code>IWizard</code>
     * method creates all the pages controls using
     * <code>IDialogPage.createControl</code>. Subclasses should reimplement
     * this method if they want to delay creating one or more of the pages
     * lazily. The framework ensures that the contents of a page will be created
     * before attempting to show it.
     */
    public void createPageControls(Composite pageContainer) {
        // the default behavior is to create all the pages controls
        for (int i = 0; i < pages.size(); i++) {
            IWizardPage page = (IWizardPage) pages.get(i);
            page.createControl(pageContainer);
            // page is responsible for ensuring the created control is
            // accessable
            // via getControl.
            Assert.isNotNull(page.getControl());
        }
    }

    /**
     * The <code>Wizard</code> implementation of this <code>IWizard</code>
     * method disposes all the pages controls using
     * <code>DialogPage.dispose</code>. Subclasses should extend this method
     * if the wizard instance maintains addition SWT resource that need to be
     * disposed.
     */
    public void dispose() {
        // notify pages
        for (int i = 0; i < pages.size(); i++) {
            ((IWizardPage) pages.get(i)).dispose();
        }
        // dispose of image
        if (defaultImage != null) {
            JFaceResources.getResources().destroyImage(defaultImageDescriptor);
            defaultImage = null;
        }
    }

    /*
     * (non-Javadoc) Method declared on IWizard.
     */
    public IWizardContainer getContainer() {
        return container;
    }

    /*
     * (non-Javadoc) Method declared on IWizard.
     */
    public Image getDefaultPageImage() {
        if (defaultImage == null) {
            defaultImage = JFaceResources.getResources().createImageWithDefault(defaultImageDescriptor);
        }
        return defaultImage;
    }

    /*
     * (non-Javadoc) Method declared on IWizard.
     */
    public IDialogSettings getDialogSettings() {
        return dialogSettings;
    }

    /*
     * (non-Javadoc) Method declared on IWizard. The default behavior is to
     * return the page that was added to this wizard after the given page.
     */
    public IWizardPage getNextPage(IWizardPage page) {
        int index = pages.indexOf(page);
        if (index == pages.size() - 1 || index == -1)
            // last page or page not found
            return null;
        return (IWizardPage) pages.get(index + 1);
    }

    /*
     * (non-Javadoc) Method declared on IWizard.
     */
    public IWizardPage getPage(String name) {
        for (int i = 0; i < pages.size(); i++) {
            IWizardPage page = (IWizardPage) pages.get(i);
            String pageName = page.getName();
            if (pageName.equals(name))
                return page;
        }
        return null;
    }

    /*
     * (non-Javadoc) Method declared on IWizard.
     */
    public int getPageCount() {
        return pages.size();
    }

    /*
     * (non-Javadoc) Method declared on IWizard.
     */
    public IWizardPage[] getPages() {
        return (IWizardPage[]) pages.toArray(new IWizardPage[pages.size()]);
    }

    /*
     * (non-Javadoc) Method declared on IWizard. The default behavior is to
     * return the page that was added to this wizard before the given page.
     */
    public IWizardPage getPreviousPage(IWizardPage page) {
        int index = pages.indexOf(page);
        if (index == 0 || index == -1)
            // first page or page not found
            return null;
        else
            return (IWizardPage) pages.get(index - 1);
    }

    /**
     * Returns the wizard's shell if the wizard is visible. Otherwise
     * <code>null</code> is returned.
     * 
     * @return Shell
     */
    public Shell getShell() {
        if (container == null)
            return null;
        return container.getShell();
    }

    /*
     * (non-Javadoc) Method declared on IWizard. By default this is the first
     * page inserted into the wizard.
     */
    public IWizardPage getStartingPage() {
        if (pages.size() == 0)
            return null;
        return (IWizardPage) pages.get(0);
    }

    /*
     * (non-Javadoc) Method declared on IWizard.
     */
    public RGB getTitleBarColor() {
        return titleBarColor;
    }

    /*
     * (non-Javadoc) Method declared on IWizard.
     */
    public String getWindowTitle() {
        return windowTitle;
    }

    /*
     * (non-Javadoc) Method declared on IWizard.
     */
    public boolean isHelpAvailable() {
        return isHelpAvailable;
    }

    /*
     * (non-Javadoc) Method declared on IWizard.
     */
    public boolean needsPreviousAndNextButtons() {
        return forcePreviousAndNextButtons || pages.size() > 1;
    }

    /*
     * (non-Javadoc) Method declared on IWizard.
     */
    public boolean needsProgressMonitor() {
        return needsProgressMonitor;
    }

    /**
     * The <code>Wizard</code> implementation of this <code>IWizard</code>
     * method does nothing and returns <code>true</code>. Subclasses should
     * reimplement this method if they need to perform any special cancel
     * processing for their wizard.
     */
    public boolean performCancel() {
        return true;
    }

    /**
     * Subclasses must implement this <code>IWizard</code> method to perform
     * any special finish processing for their wizard.
     */
    public abstract boolean performFinish();

    /*
     * (non-Javadoc) Method declared on IWizard.
     */
    public void setContainer(IWizardContainer wizardContainer) {
        container = wizardContainer;
    }

    /**
     * Sets the default page image descriptor for this wizard.
     * <p>
     * This image descriptor will be used to generate an image for a page with
     * no image of its own; the image will be computed once and cached.
     * </p>
     * 
     * @param imageDescriptor
     *            the default page image descriptor
     */
    public void setDefaultPageImageDescriptor(ImageDescriptor imageDescriptor) {
        defaultImageDescriptor = imageDescriptor;
    }

    /**
     * Sets the dialog settings for this wizard.
     * <p>
     * The dialog settings is used to record state between wizard invocations
     * (for example, radio button selection, last import directory, etc.)
     * </p>
     * 
     * @param settings
     *            the dialog settings, or <code>null</code> if none
     * @see #getDialogSettings
     *  
     */
    public void setDialogSettings(IDialogSettings settings) {
        dialogSettings = settings;
    }

    /**
     * Controls whether the wizard needs Previous and Next buttons even if it
     * currently contains only one page.
     * <p>
     * This flag should be set on wizards where the first wizard page adds
     * follow-on wizard pages based on user input.
     * </p>
     * 
     * @param b
     *            <code>true</code> to always show Next and Previous buttons,
     *            and <code>false</code> to suppress Next and Previous buttons
     *            for single page wizards
     */
    public void setForcePreviousAndNextButtons(boolean b) {
        forcePreviousAndNextButtons = b;
    }

    /**
     * Sets whether help is available for this wizard.
     * <p>
     * The result of this method is typically used by the container to show or
     * hide the Help button.
     * </p>
     * 
     * @param b
     *            <code>true</code> if help is available, and
     *            <code>false</code> if this wizard is helpless
     * @see #isHelpAvailable
     */
    public void setHelpAvailable(boolean b) {
        isHelpAvailable = b;
    }

    /**
     * Sets whether this wizard needs a progress monitor.
     * 
     * @param b
     *            <code>true</code> if a progress monitor is required, and
     *            <code>false</code> if none is needed
     * @see #needsProgressMonitor()
     */
    public void setNeedsProgressMonitor(boolean b) {
        needsProgressMonitor = b;
    }

    /**
     * Sets the title bar color for this wizard.
     * 
     * @param color
     *            the title bar color
     */
    public void setTitleBarColor(RGB color) {
        titleBarColor = color;
    }

    /**
     * Sets the window title for the container that hosts this page to the given
     * string.
     * 
     * @param newTitle
     *            the window title for the container
     */
    public void setWindowTitle(String newTitle) {
        windowTitle = newTitle;
        if (container != null)
            container.updateWindowTitle();
    }
}
