/*******************************************************************************
 * 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.dialogs;

import org.eclipse.jface.preference.IPreferenceStore;
import org.eclipse.jface.resource.JFaceResources;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Shell;

/**
 * <p>
 * A message dialog which also allows the user to adjust a toggle setting. If a
 * preference store is provided and the user selects the toggle, then the user's
 * answer (yes/ok or no) will be persisted in the store. If no store is
 * provided, then this information can be queried after the dialog closes.
 * </p>
 * <p>
 * This type of dialog should be used whenever you want to user to be able to
 * avoid being prompted in the future. It is <strong>strongly </strong>
 * recommended that a cancel option be provided, so that the user has the option
 * of making the decision at a later point in time. The semantic for a cancel
 * button should be to cancel the operation (if it has not yet started), or stop
 * the operation (if it has already started).
 * </p>
 * <p>
 * It is the responsibility of the developer to provide a mechanism for the user
 * to change this preference at some later point in time (e.g., through a
 * preference page).
 * </p>
 * 
 * @since 3.0
 */
public class MessageDialogWithToggle extends MessageDialog {

    /**
     * The value of the preference when the user has asked that the answer to
     * the question always be "okay" or "yes".
     */
    public static final String ALWAYS = "always"; //$NON-NLS-1$

    /**
     * The value of the preference when the user has asked that the answer to
     * the question always be "no".
     */
    public static final String NEVER = "never"; //$NON-NLS-1$

    /**
     * The value of the preference when the user wishes to prompted for an
     * answer every time the question is to be asked.
     */
    public static final String PROMPT = "prompt"; //$NON-NLS-1$

    /**
     * Convenience method to open a standard error dialog.
     * 
     * @param parent
     *            the parent shell of the dialog, or <code>null</code> if none
     * @param title
     *            the dialog's title, or <code>null</code> if none
     * @param message
     *            the message
     * @param toggleMessage
     *            the message for the toggle control, or <code>null</code> for
     *            the default message
     * @param toggleState
     *            the initial state for the toggle
     * @param store
     *            the IPreference store in which the user's preference should be
     *            persisted; <code>null</code> if you don't want it persisted
     *            automatically.
     * @param key
     *            the key to use when persisting the user's preference;
     *            <code>null</code> if you don't want it persisted.
     * @return the dialog, after being closed by the user, which the client can
     *         only call <code>getReturnCode()</code> or
     *         <code>getToggleState()</code>
     */
    public static MessageDialogWithToggle openError(Shell parent, String title,
            String message, String toggleMessage, boolean toggleState,
            IPreferenceStore store, String key) {
        MessageDialogWithToggle dialog = new MessageDialogWithToggle(parent,
                title, null, // accept the default window icon
                message, ERROR, new String[] { IDialogConstants.OK_LABEL }, 0, // ok
                // is
                // the
                // default
                toggleMessage, toggleState);
        dialog.prefStore = store;
        dialog.prefKey = key;
        dialog.open();
        return dialog;
    }

    /**
     * Convenience method to open a standard information dialog.
     * 
     * @param parent
     *            the parent shell of the dialog, or <code>null</code> if none
     * @param title
     *            the dialog's title, or <code>null</code> if none
     * @param message
     *            the message
     * @param toggleMessage
     *            the message for the toggle control, or <code>null</code> for
     *            the default message
     * @param toggleState
     *            the initial state for the toggle
     * @param store
     *            the IPreference store in which the user's preference should be
     *            persisted; <code>null</code> if you don't want it persisted
     *            automatically.
     * @param key
     *            the key to use when persisting the user's preference;
     *            <code>null</code> if you don't want it persisted.
     * 
     * @return the dialog, after being closed by the user, which the client can
     *         only call <code>getReturnCode()</code> or
     *         <code>getToggleState()</code>
     */
    public static MessageDialogWithToggle openInformation(Shell parent,
            String title, String message, String toggleMessage,
            boolean toggleState, IPreferenceStore store, String key) {
        MessageDialogWithToggle dialog = new MessageDialogWithToggle(parent,
                title, null, // accept the default window icon
                message, INFORMATION,
                new String[] { IDialogConstants.OK_LABEL }, 0, // ok is the
                // default
                toggleMessage, toggleState);
        dialog.prefStore = store;
        dialog.prefKey = key;
        dialog.open();
        return dialog;
    }

    /**
     * Convenience method to open a simple confirm (OK/Cancel) dialog.
     * 
     * @param parent
     *            the parent shell of the dialog, or <code>null</code> if none
     * @param title
     *            the dialog's title, or <code>null</code> if none
     * @param message
     *            the message
     * @param toggleMessage
     *            the message for the toggle control, or <code>null</code> for
     *            the default message
     * @param toggleState
     *            the initial state for the toggle
     * @param store
     *            the IPreference store in which the user's preference should be
     *            persisted; <code>null</code> if you don't want it persisted
     *            automatically.
     * @param key
     *            the key to use when persisting the user's preference;
     *            <code>null</code> if you don't want it persisted.
     * @return the dialog, after being closed by the user, which the client can
     *         only call <code>getReturnCode()</code> or
     *         <code>getToggleState()</code>
     */
    public static MessageDialogWithToggle openOkCancelConfirm(Shell parent,
            String title, String message, String toggleMessage,
            boolean toggleState, IPreferenceStore store, String key) {
        MessageDialogWithToggle dialog = new MessageDialogWithToggle(parent,
                title, null, // accept the default window icon
                message, QUESTION, new String[] { IDialogConstants.OK_LABEL,
                        IDialogConstants.CANCEL_LABEL }, 0, // OK is the default
                toggleMessage, toggleState);
        dialog.prefStore = store;
        dialog.prefKey = key;
        dialog.open();
        return dialog;
    }

    /**
     * Convenience method to open a standard warning dialog.
     * 
     * @param parent
     *            the parent shell of the dialog, or <code>null</code> if none
     * @param title
     *            the dialog's title, or <code>null</code> if none
     * @param message
     *            the message
     * @param toggleMessage
     *            the message for the toggle control, or <code>null</code> for
     *            the default message
     * @param toggleState
     *            the initial state for the toggle
     * @param store
     *            the IPreference store in which the user's preference should be
     *            persisted; <code>null</code> if you don't want it persisted
     *            automatically.
     * @param key
     *            the key to use when persisting the user's preference;
     *            <code>null</code> if you don't want it persisted.
     * @return the dialog, after being closed by the user, which the client can
     *         only call <code>getReturnCode()</code> or
     *         <code>getToggleState()</code>
     */
    public static MessageDialogWithToggle openWarning(Shell parent,
            String title, String message, String toggleMessage,
            boolean toggleState, IPreferenceStore store, String key) {
        MessageDialogWithToggle dialog = new MessageDialogWithToggle(parent,
                title, null, // accept the default window icon
                message, WARNING, new String[] { IDialogConstants.OK_LABEL },
                0, // ok is the default
                toggleMessage, toggleState);
        dialog.prefStore = store;
        dialog.prefKey = key;
        dialog.open();
        return dialog;
    }

    /**
     * Convenience method to open a simple question Yes/No/Cancel dialog.
     * 
     * @param parent
     *            the parent shell of the dialog, or <code>null</code> if none
     * @param title
     *            the dialog's title, or <code>null</code> if none
     * @param message
     *            the message
     * @param toggleMessage
     *            the message for the toggle control, or <code>null</code> for
     *            the default message
     * @param toggleState
     *            the initial state for the toggle
     * @param store
     *            the IPreference store in which the user's preference should be
     *            persisted; <code>null</code> if you don't want it persisted
     *            automatically.
     * @param key
     *            the key to use when persisting the user's preference;
     *            <code>null</code> if you don't want it persisted.
     * @return the dialog, after being closed by the user, which the client can
     *         only call <code>getReturnCode()</code> or
     *         <code>getToggleState()</code>
     */
    public static MessageDialogWithToggle openYesNoCancelQuestion(Shell parent,
            String title, String message, String toggleMessage,
            boolean toggleState, IPreferenceStore store, String key) {
        MessageDialogWithToggle dialog = new MessageDialogWithToggle(parent,
                title, null, // accept the default window icon
                message, QUESTION, new String[] { IDialogConstants.YES_LABEL,
                        IDialogConstants.NO_LABEL,
                        IDialogConstants.CANCEL_LABEL }, 0, // YES is the
                // default
                toggleMessage, toggleState);
        dialog.prefStore = store;
        dialog.prefKey = key;
        dialog.open();
        return dialog;
    }

    /**
     * Convenience method to open a simple Yes/No question dialog.
     * 
     * @param parent
     *            the parent shell of the dialog, or <code>null</code> if none
     * @param title
     *            the dialog's title, or <code>null</code> if none
     * @param message
     *            the message
     * @param toggleMessage
     *            the message for the toggle control, or <code>null</code> for
     *            the default message
     * @param toggleState
     *            the initial state for the toggle
     * @param store
     *            the IPreference store in which the user's preference should be
     *            persisted; <code>null</code> if you don't want it persisted
     *            automatically.
     * @param key
     *            the key to use when persisting the user's preference;
     *            <code>null</code> if you don't want it persisted.
     * 
     * @return the dialog, after being closed by the user, which the client can
     *         only call <code>getReturnCode()</code> or
     *         <code>getToggleState()</code>
     */
    public static MessageDialogWithToggle openYesNoQuestion(Shell parent,
            String title, String message, String toggleMessage,
            boolean toggleState, IPreferenceStore store, String key) {
        MessageDialogWithToggle dialog = new MessageDialogWithToggle(parent,
                title, null, // accept the default window icon
                message, QUESTION, new String[] { IDialogConstants.YES_LABEL,
                        IDialogConstants.NO_LABEL }, 0, // yes is the default
                toggleMessage, toggleState);
        dialog.prefStore = store;
        dialog.prefKey = key;
        dialog.open();
        return dialog;
    }

    /**
     * The key at which the toggle state should be stored within the
     * preferences. This value may be <code>null</code>, which indicates that
     * no preference should be updated automatically. It is then the
     * responsibility of the user of this API to use the information from the
     * toggle. Note: a <code>prefStore</code> is also needed.
     */
    private String prefKey = null;

    /**
     * The preference store which will be affected by the toggle button. This
     * value may be <code>null</code>, which indicates that no preference
     * should be updated automatically. It is then the responsibility of the
     * user of this API to use the information from the toggle. Note: a
     * <code>prefKey</code> is also needed.
     */
    private IPreferenceStore prefStore = null;

    /**
     * The toggle button (widget). This value is <code>null</code> until the
     * dialog is created.
     */
    private Button toggleButton = null;

    /**
     * The message displayed to the user, with the toggle button. This is the
     * text besides the toggle. If it is <code>null</code>, this means that
     * the default text for the toggle should be used.
     */
    private String toggleMessage;

    /**
     * The initial selected state of the toggle.
     */
    private boolean toggleState;

    /**
     * Creates a message dialog with a toggle. See the superclass constructor
     * for info on the other parameters.
     * 
     * @param parentShell
     *            the parent shell
     * @param dialogTitle
     *            the dialog title, or <code>null</code> if none
     * @param image
     *            the dialog title image, or <code>null</code> if none
     * @param message
     *            the dialog message
     * @param dialogImageType
     *            one of the following values:
     *            <ul>
     *            <li><code>MessageDialog.NONE</code> for a dialog with no
     *            image</li>
     *            <li><code>MessageDialog.ERROR</code> for a dialog with an
     *            error image</li>
     *            <li><code>MessageDialog.INFORMATION</code> for a dialog
     *            with an information image</li>
     *            <li><code>MessageDialog.QUESTION </code> for a dialog with a
     *            question image</li>
     *            <li><code>MessageDialog.WARNING</code> for a dialog with a
     *            warning image</li>
     *            </ul>
     * @param dialogButtonLabels
     *            an array of labels for the buttons in the button bar
     * @param defaultIndex
     *            the index in the button label array of the default button
     * @param toggleMessage
     *            the message for the toggle control, or <code>null</code> for
     *            the default message
     * @param toggleState
     *            the initial state for the toggle
     *  
     */
    public MessageDialogWithToggle(Shell parentShell, String dialogTitle,
            Image image, String message, int dialogImageType,
            String[] dialogButtonLabels, int defaultIndex,
            String toggleMessage, boolean toggleState) {
        super(parentShell, dialogTitle, image, message, dialogImageType,
                dialogButtonLabels, defaultIndex);
        this.toggleMessage = toggleMessage;
        this.toggleState = toggleState;
        setButtonLabels(dialogButtonLabels);
    }

    /**
     * @see org.eclipse.jface.dialogs.Dialog#buttonPressed(int)
     */
    protected void buttonPressed(int buttonId) {
        super.buttonPressed(buttonId);

        if (buttonId != IDialogConstants.CANCEL_ID && toggleState
                && prefStore != null && prefKey != null) {
            switch (buttonId) {
            case IDialogConstants.YES_ID:
            case IDialogConstants.YES_TO_ALL_ID:
            case IDialogConstants.PROCEED_ID:
            case IDialogConstants.OK_ID:
                prefStore.setValue(prefKey, ALWAYS);
                break;
            case IDialogConstants.NO_ID:
            case IDialogConstants.NO_TO_ALL_ID:
                prefStore.setValue(prefKey, NEVER);
                break;
            }
        }
    }

    /**
     * @see Dialog#createButtonBar(Composite)
     */
    protected void createButtonsForButtonBar(Composite parent) {
        final String[] buttonLabels = getButtonLabels();
        final Button[] buttons = new Button[buttonLabels.length];
        final int defaultButtonIndex = getDefaultButtonIndex();

        int suggestedId = IDialogConstants.INTERNAL_ID;
        for (int i = 0; i < buttonLabels.length; i++) {
            String label = buttonLabels[i];
            // get the JFace button ID that matches the label, or use the specified
            // id if there is no match.
            int id = mapButtonLabelToButtonID(label, suggestedId);
            
            // if the suggested id was used, increment the default for next use
            if (id == suggestedId)
            	suggestedId++;
 
            Button button = createButton(parent, id, label,
                    defaultButtonIndex == i);
            buttons[i] = button;
 
        }
        setButtons(buttons);
    }

    /**
     * @see Dialog#createDialogArea(Composite)
     */
    protected Control createDialogArea(Composite parent) {
        Composite dialogAreaComposite = (Composite) super
                .createDialogArea(parent);
        setToggleButton(createToggleButton(dialogAreaComposite));
        return dialogAreaComposite;
    }

    /**
     * Creates a toggle button without any text or state.  The text and state
     * will be created by <code>createDialogArea</code>. 
     * 
     * @param parent
     *            The composite in which the toggle button should be placed;
     *            must not be <code>null</code>.
     * @return The added toggle button; never <code>null</code>.
     */
    protected Button createToggleButton(Composite parent) {
        final Button button = new Button(parent, SWT.CHECK | SWT.LEFT);

        GridData data = new GridData(SWT.NONE);
        data.horizontalSpan = 2;
        button.setLayoutData(data);
        button.setFont(parent.getFont());

        button.addSelectionListener(new SelectionAdapter() {

            public void widgetSelected(SelectionEvent e) {
                toggleState = button.getSelection();
            }

        });

        return button;
    }

    /**
     * Returns the toggle button.
     * 
     * @return the toggle button
     */
    protected Button getToggleButton() {
        return toggleButton;
    }

    /**
     * An accessor for the current preference store for this dialog.
     * 
     * @return The preference store; this value may be <code>null</code> if no
     *         preference is being used.
     */
    public IPreferenceStore getPrefStore() {
        return prefStore;
    }

    /**
     * An accessor for the current key of the toggle preference.
     * 
     * @return The preference key; this value may be <code>null</code> if no
     *         preference is being used.
     */
    public String getPrefKey() {
        return prefKey;
    }

    /**
     * Returns the toggle state. This can be called even after the dialog is
     * closed.
     * 
     * @return <code>true</code> if the toggle button is checked,
     *         <code>false</code> if not
     */
    public boolean getToggleState() {
        return toggleState;
    }

    /**
     * A mutator for the key of the preference to be modified by the toggle
     * button.
     * 
     * @param prefKey
     *            The prefKey to set. If this value is <code>null</code>,
     *            then no preference will be modified.
     */
    public void setPrefKey(String prefKey) {
        this.prefKey = prefKey;
    }

    /**
     * A mutator for the preference store to be modified by the toggle button.
     * 
     * @param prefStore
     *            The prefStore to set. If this value is <code>null</code>,
     *            then no preference will be modified.
     */
    public void setPrefStore(IPreferenceStore prefStore) {
        this.prefStore = prefStore;
    }

    /**
     * A mutator for the button providing the toggle option. If the button
     * exists, then it will automatically get the text set to the current toggle
     * message, and its selection state set to the current selection state.
     * 
     * @param button
     *            The button to use; must not be <code>null</code>.
     */
    protected void setToggleButton(Button button) {
        if (button == null) {
            throw new NullPointerException(
                    "A message dialog with toggle may not have a null toggle button.");} //$NON-NLS-1$

        if (!button.isDisposed()) {
            final String text;
            if (toggleMessage == null) {
                text = JFaceResources
                        .getString("MessageDialogWithToggle.defaultToggleMessage"); //$NON-NLS-1$
            } else {
                text = toggleMessage;
            }
            button.setText(text);
            button.setSelection(toggleState);
        }

        this.toggleButton = button;
    }

    /**
     * A mutator for the text on the toggle button. The button will
     * automatically get updated with the new text, if it exists.
     * 
     * @param message
     *            The new text of the toggle button; if it is <code>null</code>,
     *            then used the default toggle message.
     */
    protected void setToggleMessage(String message) {
        this.toggleMessage = message;

        if ((toggleButton != null) && (!toggleButton.isDisposed())) {
            final String text;
            if (toggleMessage == null) {
                text = JFaceResources
                        .getString("MessageDialogWithToggle.defaultToggleMessage"); //$NON-NLS-1$
            } else {
                text = toggleMessage;
            }
            toggleButton.setText(text);
        }
    }

    /**
     * A mutator for the state of the toggle button. This method will update the
     * button, if it exists.
     * 
     * @param toggleState
     *            The desired state of the toggle button (<code>true</code>
     *            means the toggle should be selected).
     */
    public void setToggleState(boolean toggleState) {
        this.toggleState = toggleState;

        // Update the button, if it exists.
        if ((toggleButton != null) && (!toggleButton.isDisposed())) {
            toggleButton.setSelection(toggleState);
        }
    }
    
    /**
     * Attempt to find a standard JFace button id that matches the specified button
     * label.  If no match can be found, use the default id provided.
     * 
     * @param buttonLabel the button label whose id is sought
     * @param defaultId the id to use for the button if there is no standard id
     * @return the id for the specified button label
     */
    private int mapButtonLabelToButtonID(String buttonLabel, int defaultId) {
    	// Not pretty but does the job...
    	if (IDialogConstants.OK_LABEL.equals(buttonLabel)) 
    		return IDialogConstants.OK_ID;
    	
	    if (IDialogConstants.YES_LABEL.equals(buttonLabel))
	        return IDialogConstants.YES_ID;
	    
	    if (IDialogConstants.NO_LABEL.equals(buttonLabel)) 
	        return IDialogConstants.NO_ID;
	    
	    if (IDialogConstants.CANCEL_LABEL.equals(buttonLabel))
	         return IDialogConstants.CANCEL_ID;
	    
	    if (IDialogConstants.YES_TO_ALL_LABEL.equals(buttonLabel))
	    	return IDialogConstants.YES_TO_ALL_ID;
	    
	    if (IDialogConstants.SKIP_LABEL.equals(buttonLabel))
	    	return IDialogConstants.SKIP_ID;
	    
	    if (IDialogConstants.STOP_LABEL.equals(buttonLabel))
	    	return IDialogConstants.STOP_ID;
	    
	    if (IDialogConstants.ABORT_LABEL.equals(buttonLabel))
	    	return IDialogConstants.ABORT_ID;
	    
	    if (IDialogConstants.RETRY_LABEL.equals(buttonLabel))
	    	return IDialogConstants.RETRY_ID;
	    
	    if (IDialogConstants.IGNORE_LABEL.equals(buttonLabel))
	    	return IDialogConstants.IGNORE_ID;
	    
	    if (IDialogConstants.PROCEED_LABEL.equals(buttonLabel))
	    	return IDialogConstants.PROCEED_ID;
	    
	    if (IDialogConstants.OPEN_LABEL.equals(buttonLabel))
	    	return IDialogConstants.OPEN_ID;
	    
	    if (IDialogConstants.CLOSE_LABEL.equals(buttonLabel))
	    	return IDialogConstants.CLOSE_ID;
	    
	    if (IDialogConstants.BACK_LABEL.equals(buttonLabel))
	    	return IDialogConstants.BACK_ID;
	    
	    if (IDialogConstants.NEXT_LABEL.equals(buttonLabel))
	    	return IDialogConstants.NEXT_ID;
	    
	    if (IDialogConstants.FINISH_LABEL.equals(buttonLabel))
	    	return IDialogConstants.FINISH_ID;
	    
	    if (IDialogConstants.HELP_LABEL.equals(buttonLabel))
	    	return IDialogConstants.HELP_ID;
	    
	    if (IDialogConstants.NO_TO_ALL_LABEL.equals(buttonLabel))
	        return IDialogConstants.NO_TO_ALL_ID;
        
        //          No XXX_LABEL in IDialogConstants for these. Unlikely
        //            they would be used in a message dialog though.
        //        	public int DETAILS_ID = 13;
        //        	public int SELECT_ALL_ID = 18;
        //        	public int DESELECT_ALL_ID = 19;
        //        	public int SELECT_TYPES_ID = 20;

	    return defaultId;
    }
}
