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

import java.util.ArrayList;

import org.eclipse.jface.dialogs.Dialog;
import org.eclipse.jface.dialogs.IDialogConstants;
import org.eclipse.jface.dialogs.IDialogSettings;
import org.eclipse.swt.SWT;
import org.eclipse.swt.graphics.Cursor;
import org.eclipse.swt.graphics.Font;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Event;
import org.eclipse.swt.widgets.FileDialog;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Listener;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.Table;
import org.eclipse.swt.widgets.TableItem;
import org.eclipse.ui.IEditorDescriptor;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.internal.IWorkbenchHelpContextIds;
import org.eclipse.ui.internal.WorkbenchMessages;
import org.eclipse.ui.internal.WorkbenchPlugin;
import org.eclipse.ui.internal.registry.EditorDescriptor;
import org.eclipse.ui.internal.registry.EditorRegistry;

/**
 * This class is used to allow the user to select a dialog from the set of
 * internal and external editors.
 *
 * @private
 *      This class is internal to the workbench and must not be called outside the workbench
 */

public class EditorSelectionDialog extends Dialog implements Listener {
    private EditorDescriptor selectedEditor;

    private Button externalButton;

    private Table editorTable;

    private Button browseExternalEditorsButton;

    private Button internalButton;

    private Button okButton;

    private static final String STORE_ID_INTERNAL_EXTERNAL = "EditorSelectionDialog.STORE_ID_INTERNAL_EXTERNAL";//$NON-NLS-1$

    private String message = WorkbenchMessages.EditorSelection_chooseAnEditor; 

    // collection of IEditorDescriptor
    private IEditorDescriptor[] externalEditors;

    private IEditorDescriptor[] internalEditors;

    private Image[] externalEditorImages;

    private Image[] internalEditorImages;

    private IEditorDescriptor[] editorsToFilter;

    private static final String[] Executable_Filters;

    private static final int TABLE_WIDTH = 200;
    static {
        if (SWT.getPlatform().equals("win32")) {//$NON-NLS-1$
            Executable_Filters = new String[] { "*.exe", "*.bat", "*.*" };//$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
        } else {
            Executable_Filters = new String[] { "*" }; //$NON-NLS-1$
        }
    }

    /**
     * Create an instance of this class.
     * 
     * @param parentShell the parent shell
     */
    public EditorSelectionDialog(Shell parentShell) {
        super(parentShell);
    }

    /**
     * This method is called if a button has been pressed.
     */
    protected void buttonPressed(int buttonId) {
        if (buttonId == IDialogConstants.OK_ID) {
			saveWidgetValues();
		}
        super.buttonPressed(buttonId);
    }

    /**
     * Close the window.
     */
    public boolean close() {
        if (internalEditorImages != null) {
            for (int i = 0; i < internalEditorImages.length; i++) {
                internalEditorImages[i].dispose();
            }
            internalEditorImages = null;
        }
        if (externalEditorImages != null) {
            for (int i = 0; i < externalEditorImages.length; i++) {
                externalEditorImages[i].dispose();
            }
            externalEditorImages = null;
        }
        return super.close();
    }

    /* (non-Javadoc)
     * Method declared in Window.
     */
    protected void configureShell(Shell shell) {
        super.configureShell(shell);
        shell.setText(WorkbenchMessages.EditorSelection_title);
        PlatformUI.getWorkbench().getHelpSystem().setHelp(shell,
				IWorkbenchHelpContextIds.EDITOR_SELECTION_DIALOG);
    }

    /**
     * Creates and returns the contents of the upper part 
     * of the dialog (above the button bar).
     *
     * Subclasses should overide.
     *
     * @param parent the parent composite to contain the dialog area
     * @return the dialog area control
     */
    protected Control createDialogArea(Composite parent) {
        Font font = parent.getFont();
        // create main group
        Composite contents = (Composite) super.createDialogArea(parent);
        ((GridLayout) contents.getLayout()).numColumns = 2;

        // begin the layout
        Label textLabel = new Label(contents, SWT.NONE);
        textLabel.setText(message);
        GridData data = new GridData();
        data.horizontalSpan = 2;
        textLabel.setLayoutData(data);
        textLabel.setFont(font);

        internalButton = new Button(contents, SWT.RADIO | SWT.LEFT);
        internalButton.setText(WorkbenchMessages.EditorSelection_internal);
        internalButton.addListener(SWT.Selection, this);
        data = new GridData();
        data.horizontalSpan = 1;
        internalButton.setLayoutData(data);
        internalButton.setFont(font);

        externalButton = new Button(contents, SWT.RADIO | SWT.LEFT);
        externalButton.setText(WorkbenchMessages.EditorSelection_external); 
        externalButton.addListener(SWT.Selection, this);
        data = new GridData();
        data.horizontalSpan = 1;
        externalButton.setLayoutData(data);
        externalButton.setFont(font);

        editorTable = new Table(contents, SWT.SINGLE | SWT.BORDER);
        editorTable.addListener(SWT.Selection, this);
        editorTable.addListener(SWT.DefaultSelection, this);
        editorTable.addListener(SWT.MouseDoubleClick, this);
        data = new GridData();
        data.widthHint = convertHorizontalDLUsToPixels(TABLE_WIDTH);
        data.horizontalAlignment = GridData.FILL;
        data.grabExcessHorizontalSpace = true;
        data.verticalAlignment = GridData.FILL;
        data.grabExcessVerticalSpace = true;
        data.horizontalSpan = 2;
        editorTable.setLayoutData(data);
        editorTable.setFont(font);
        data.heightHint = editorTable.getItemHeight() * 12;

        browseExternalEditorsButton = new Button(contents, SWT.PUSH);
		browseExternalEditorsButton.setText(WorkbenchMessages.EditorSelection_browse);
		browseExternalEditorsButton.addListener(SWT.Selection, this);
		data = new GridData();
		int widthHint = convertHorizontalDLUsToPixels(IDialogConstants.BUTTON_WIDTH);
		data.widthHint = Math.max(widthHint, browseExternalEditorsButton
				.computeSize(SWT.DEFAULT, SWT.DEFAULT, true).x);
		browseExternalEditorsButton.setLayoutData(data);
		browseExternalEditorsButton.setFont(font);

        restoreWidgetValues(); // Place buttons to the appropriate state

        fillEditorTable();

        updateEnableState();

        return contents;
    }

    protected void fillEditorTable() {
        editorTable.removeAll();
        editorTable.update();
        IEditorDescriptor[] editors;
        Image[] images;
        if (internalButton.getSelection()) {
            editors = getInternalEditors();
            images = internalEditorImages;
        } else {
            editors = getExternalEditors();
            images = externalEditorImages;
        }

        // 1FWHIEX: ITPUI:WINNT - Need to call setRedraw
        editorTable.setRedraw(false);
        for (int i = 0; i < editors.length; i++) {
            TableItem item = new TableItem(editorTable, SWT.NULL);
            item.setData(editors[i]);
            item.setText(editors[i].getLabel());
            item.setImage(images[i]);
        }
        editorTable.setRedraw(true);
    }

    /**
     * Return the dialog store to cache values into
     */

    protected IDialogSettings getDialogSettings() {
        IDialogSettings workbenchSettings = WorkbenchPlugin.getDefault()
                .getDialogSettings();
        IDialogSettings section = workbenchSettings
                .getSection("EditorSelectionDialog");//$NON-NLS-1$
        if (section == null) {
			section = workbenchSettings.addNewSection("EditorSelectionDialog");//$NON-NLS-1$
		}
        return section;
    }

    /**
     * Get a list of registered programs from the OS
     */
    protected IEditorDescriptor[] getExternalEditors() {
        if (externalEditors == null) {
            // Since this can take a while, show the busy
            // cursor. If the dialog is not yet visible,
            // then use the parent shell.
            Control shell = getShell();
            if (!shell.isVisible()) {
                Control topShell = shell.getParent();
                if (topShell != null) {
					shell = topShell;
				}
            }
            Cursor busy = new Cursor(shell.getDisplay(), SWT.CURSOR_WAIT);
            shell.setCursor(busy);
            // Get the external editors available
            EditorRegistry reg = (EditorRegistry) WorkbenchPlugin.getDefault()
                    .getEditorRegistry();
            externalEditors = reg.getSortedEditorsFromOS();
            externalEditors = filterEditors(externalEditors);
            externalEditorImages = getImages(externalEditors);
            // Clean up
            shell.setCursor(null);
            busy.dispose();
        }
        return externalEditors;
    }

    /**
     * Returns an array of editors which have been filtered according to 
     * the array of editors in the editorsToFilter instance variable.
     * 
     * @param editors an array of editors to filter 
     * @return a filtered array of editors
     */
    protected IEditorDescriptor[] filterEditors(IEditorDescriptor[] editors) {
        if ((editors == null) || (editors.length < 1)) {
			return editors;
		}

        if ((editorsToFilter == null) || (editorsToFilter.length < 1)) {
			return editors;
		}

        ArrayList filteredList = new ArrayList();
        for (int i = 0; i < editors.length; i++) {
            boolean add = true;
            for (int j = 0; j < editorsToFilter.length; j++) {
                if (editors[i].getId().equals(editorsToFilter[j].getId())) {
                    add = false;
                }
            }
            if (add) {
				filteredList.add(editors[i]);
			}
        }

        return (IEditorDescriptor[]) filteredList
                .toArray(new IEditorDescriptor[filteredList.size()]);
    }

    /**
     * Returns an array of images for the given array of editors
     */
    protected Image[] getImages(IEditorDescriptor[] editors) {
        Image[] images = new Image[editors.length];
        for (int i = 0; i < editors.length; i++) {
            images[i] = editors[i].getImageDescriptor().createImage();
        }
        return images;
    }

    /**
     * Returns the internal editors
     */
    protected IEditorDescriptor[] getInternalEditors() {
        if (internalEditors == null) {
            EditorRegistry reg = (EditorRegistry) WorkbenchPlugin.getDefault()
                    .getEditorRegistry();
            internalEditors = reg.getSortedEditorsFromPlugins();
            internalEditors = filterEditors(internalEditors);
            internalEditorImages = getImages(internalEditors);
        }
        return internalEditors;
    }

    /**
     * Return the editor the user selected
     * 
     * @return the selected editor
     */
    public IEditorDescriptor getSelectedEditor() {
        return selectedEditor;
    }

    public void handleEvent(Event event) {
        if (event.type == SWT.MouseDoubleClick) {
            handleDoubleClickEvent();
            return;
        }
        if (event.widget == externalButton) {
            fillEditorTable();
        } else if (event.widget == browseExternalEditorsButton) {
            promptForExternalEditor();
        } else if (event.widget == editorTable) {
            if (editorTable.getSelectionIndex() != -1) {
                selectedEditor = (EditorDescriptor) editorTable.getSelection()[0]
                        .getData();
            } else {
                selectedEditor = null;
                okButton.setEnabled(false);
            }
        }
        updateEnableState();
    }

    protected void promptForExternalEditor() {
        FileDialog dialog = new FileDialog(getShell(), SWT.OPEN
                | SWT.PRIMARY_MODAL);
        dialog.setFilterExtensions(Executable_Filters);
        String result = dialog.open();
        if (result != null) {
            EditorDescriptor editor = EditorDescriptor.createForProgram(result);
            // pretend we had obtained it from the list of os registered editors
            TableItem ti = new TableItem(editorTable, SWT.NULL);
            ti.setData(editor);
            ti.setText(editor.getLabel());
            Image image = editor.getImageDescriptor().createImage();
            ti.setImage(image);

            // need to pass an array to setSelection -- 1FSKYVO: SWT:ALL - inconsistent setSelection api on Table 
            editorTable.setSelection(new TableItem[] { ti });
            editorTable.showSelection();
            editorTable.setFocus();
            selectedEditor = editor;

            /* add to our collection of cached external editors in case the user
             flips back and forth between internal/external */
            IEditorDescriptor[] newEditors = new IEditorDescriptor[externalEditors.length + 1];
            System.arraycopy(externalEditors, 0, newEditors, 0,
                    externalEditors.length);
            newEditors[newEditors.length - 1] = editor;
            externalEditors = newEditors;

            Image[] newImages = new Image[externalEditorImages.length + 1];
            System.arraycopy(externalEditorImages, 0, newImages, 0,
                    externalEditorImages.length);
            newImages[newImages.length - 1] = image;
            externalEditorImages = newImages;
        }
    }

    /**
     * Handle a double click event on the list
     */
    protected void handleDoubleClickEvent() {
        buttonPressed(IDialogConstants.OK_ID);
    }

    /**
     *  Use the dialog store to restore widget values to the values that they held
     *  last time this wizard was used to completion
     */
    protected void restoreWidgetValues() {
        IDialogSettings settings = getDialogSettings();
        boolean wasExternal = settings.getBoolean(STORE_ID_INTERNAL_EXTERNAL);
        internalButton.setSelection(!wasExternal);
        externalButton.setSelection(wasExternal);
    }

    /**
     *  Since Finish was pressed, write widget values to the dialog store so that they
     *  will persist into the next invocation of this wizard page
     */
    protected void saveWidgetValues() {
        IDialogSettings settings = getDialogSettings();
        // record whether use was viewing internal or external editors
        settings
                .put(STORE_ID_INTERNAL_EXTERNAL, !internalButton.getSelection());
    }

    /**
     * Set the message displayed by this message dialog
     * 
     * @param aMessage the message
     */
    public void setMessage(String aMessage) {
        message = aMessage;
    }

    /**
     * Set the editors which will not appear in the dialog.
     * 
     * @param editors an array of editors
     */
    public void setEditorsToFilter(IEditorDescriptor[] editors) {
        editorsToFilter = editors;
    }

    /**
     * Update enabled state.
     */
    public void updateEnableState() {
        boolean enableExternal = externalButton.getSelection();
        browseExternalEditorsButton.setEnabled(enableExternal);
        updateOkButton();
    }

    protected void createButtonsForButtonBar(Composite parent) {
        okButton = createButton(parent, IDialogConstants.OK_ID,
                IDialogConstants.OK_LABEL, true);
        createButton(parent, IDialogConstants.CANCEL_ID,
                IDialogConstants.CANCEL_LABEL, false);
        //initially there is no selection so OK button should not be enabled
        okButton.setEnabled(false);

    }

    /**
     * Update the button enablement state.
     */
    protected void updateOkButton() {
        // Buttons are null during dialog creation
        if (okButton == null) {
			return;
		}
        // If there is no selection, do not enable OK button
        if (editorTable.getSelectionCount() == 0) {
            okButton.setEnabled(false);
            return;
        }
        // At this point, there is a selection
        okButton.setEnabled(selectedEditor != null);
    }
}
