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

import java.io.File;
import java.io.IOException;
import java.util.List;
import java.util.zip.ZipException;
import java.util.zip.ZipFile;

import org.eclipse.jface.dialogs.IDialogSettings;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.jface.viewers.ITreeContentProvider;
import org.eclipse.osgi.util.NLS;
import org.eclipse.swt.SWT;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.FileDialog;
import org.eclipse.swt.widgets.Listener;
import org.eclipse.ui.IWorkbench;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.model.WorkbenchContentProvider;
import org.eclipse.ui.wizards.datatransfer.ImportOperation;
import org.eclipse.ui.wizards.datatransfer.ZipFileStructureProvider;


/**
 *	Page 1 of the base resource import-from-zip Wizard.
 *
 *	Note that importing from .jar is identical to importing from .zip, so
 *	all references to .zip in this class are equally applicable to .jar
 *	references.
 */
public class WizardZipFileResourceImportPage1 extends
        WizardFileSystemResourceImportPage1 implements Listener {
    private ZipFileStructureProvider providerCache;

    ZipFileStructureProvider currentProvider;

    // constants
    private static final String[] FILE_IMPORT_MASK = { "*.jar;*.zip", "*.*" }; //$NON-NLS-1$ //$NON-NLS-2$

    // dialog store id constants
    private final static String STORE_SOURCE_NAMES_ID = "WizardZipFileResourceImportPage1.STORE_SOURCE_NAMES_ID"; //$NON-NLS-1$

    private final static String STORE_OVERWRITE_EXISTING_RESOURCES_ID = "WizardZipFileResourceImportPage1.STORE_OVERWRITE_EXISTING_RESOURCES_ID"; //$NON-NLS-1$

    private final static String STORE_SELECTED_TYPES_ID = "WizardZipFileResourceImportPage1.STORE_SELECTED_TYPES_ID"; //$NON-NLS-1$

    /**
     *	Creates an instance of this class
     * @param aWorkbench IWorkbench
     * @param selection IStructuredSelection
     */
    public WizardZipFileResourceImportPage1(IWorkbench aWorkbench,
            IStructuredSelection selection) {
        super("zipFileImportPage1", aWorkbench, selection); //$NON-NLS-1$
        setTitle(DataTransferMessages.ZipExport_exportTitle);
        setDescription(DataTransferMessages.ZipImport_description);
    }

    /**
     * Called when the user presses the Cancel button. Return a boolean
     * indicating permission to close the wizard.
     *
     * @return boolean
     */
    public boolean cancel() {
        clearProviderCache();
        return true;
    }

    /**
     * Clears the cached structure provider after first finalizing
     * it properly.
     */
    protected void clearProviderCache() {
        if (providerCache != null) {
            closeZipFile(providerCache.getZipFile());
            providerCache = null;
        }
    }

    /**
     * Attempts to close the passed zip file, and answers a boolean indicating success.
     */
    protected boolean closeZipFile(ZipFile file) {
        try {
            file.close();
        } catch (IOException e) {
            displayErrorDialog(NLS.bind(DataTransferMessages.ZipImport_couldNotClose, file.getName()));
            return false;
        }

        return true;
    }

    /** (non-Javadoc)
     * Method declared on IDialogPage.
     */
    public void createControl(Composite parent) {
        super.createControl(parent);
        PlatformUI.getWorkbench().getHelpSystem().setHelp(getControl(),
                IDataTransferHelpContextIds.ZIP_FILE_IMPORT_WIZARD_PAGE);
    }

    /**
     *	Create the options specification widgets. There is only one
     * in this case so create no group.
     *
     *	@param parent org.eclipse.swt.widgets.Composite
     */
    protected void createOptionsGroup(Composite parent) {

        // overwrite... checkbox
        overwriteExistingResourcesCheckbox = new Button(parent, SWT.CHECK);
        overwriteExistingResourcesCheckbox.setText(DataTransferMessages.FileImport_overwriteExisting);
        overwriteExistingResourcesCheckbox.setFont(parent.getFont());
    }

    /**
     *	Answer a boolean indicating whether the specified source currently exists
     *	and is valid (ie.- proper format)
     */
    protected boolean ensureSourceIsValid() {
        ZipFile specifiedFile = getSpecifiedSourceFile();

        if (specifiedFile == null) {
			return false;
		}

        return closeZipFile(specifiedFile);
    }

    /**
     * The Finish button was pressed.  Try to do the required work now and answer
     * a boolean indicating success.  If <code>false</code> is returned then the
     * wizard will not close.
     *
     * @return boolean
     */
    public boolean finish() {
        if (!super.finish()) {
			return false;
		}

        clearProviderCache();
        return true;
    }

    /**
     * Returns a content provider for <code>FileSystemElement</code>s that returns 
     * only files as children.
     */
    protected ITreeContentProvider getFileProvider() {
        return new WorkbenchContentProvider() {
            public Object[] getChildren(Object o) {
                if (o instanceof MinimizedFileSystemElement) {
                    MinimizedFileSystemElement element = (MinimizedFileSystemElement) o;
                    return element.getFiles(currentProvider).getChildren(
                            element);
                }
                return new Object[0];
            }
        };
    }

    /**
     *	Answer the root FileSystemElement that represents the contents of the
     *	currently-specified .zip file.  If this FileSystemElement is not
     *	currently defined then create and return it.
     */
    protected MinimizedFileSystemElement getFileSystemTree() {

        ZipFile sourceFile = getSpecifiedSourceFile();
        if (sourceFile == null) {
            //Clear out the provider as well
            this.currentProvider = null;
            return null;
        }

        ZipFileStructureProvider provider = getStructureProvider(sourceFile);
        this.currentProvider = provider;
        return selectFiles(provider.getRoot(), provider);
    }

    /**
     * Returns a content provider for <code>FileSystemElement</code>s that returns 
     * only folders as children.
     */
    protected ITreeContentProvider getFolderProvider() {
        return new WorkbenchContentProvider() {
            public Object[] getChildren(Object o) {
                if (o instanceof MinimizedFileSystemElement) {
                    MinimizedFileSystemElement element = (MinimizedFileSystemElement) o;
                    return element.getFolders(currentProvider).getChildren(
                            element);
                }
                return new Object[0];
            }

            public boolean hasChildren(Object o) {
                if (o instanceof MinimizedFileSystemElement) {
                    MinimizedFileSystemElement element = (MinimizedFileSystemElement) o;
                    if (element.isPopulated()) {
						return getChildren(element).length > 0;
					} else {
                        //If we have not populated then wait until asked
                        return true;
                    }
                }
                return false;
            }
        };
    }

    /**
     *	Answer the string to display as the label for the source specification field
     */
    protected String getSourceLabel() {
        return DataTransferMessages.ZipImport_fromFile;
    }

    /**
     *	Answer a handle to the zip file currently specified as being the source.
     *	Return null if this file does not exist or is not of valid format.
     */
    protected ZipFile getSpecifiedSourceFile() {
        return getSpecifiedSourceFile(sourceNameField.getText());
    }

    /**
     *	Answer a handle to the zip file currently specified as being the source.
     *	Return null if this file does not exist or is not of valid format.
     */
    private ZipFile getSpecifiedSourceFile(String fileName) {
        if (fileName.length() == 0) {
			return null;
		}

        try {
            return new ZipFile(fileName);
        } catch (ZipException e) {
            displayErrorDialog(DataTransferMessages.ZipImport_badFormat);
        } catch (IOException e) {
            displayErrorDialog(DataTransferMessages.ZipImport_couldNotRead);
        }

        sourceNameField.setFocus();
        return null;
    }

    /**
     * Returns a structure provider for the specified zip file.
     */
    protected ZipFileStructureProvider getStructureProvider(ZipFile targetZip) {
        if (providerCache == null) {
			providerCache = new ZipFileStructureProvider(targetZip);
		} else if (!providerCache.getZipFile().getName().equals(
                targetZip.getName())) {
            clearProviderCache();
            // ie.- new value, so finalize&remove old value
            providerCache = new ZipFileStructureProvider(targetZip);
        } else if (!providerCache.getZipFile().equals(targetZip)) {
			closeZipFile(targetZip); // ie.- duplicate handle to same .zip
		}

        return providerCache;
    }

    /**
     *	Open a FileDialog so that the user can specify the source
     *	file to import from
     */
    protected void handleSourceBrowseButtonPressed() {
        String selectedFile = queryZipFileToImport();

        if (selectedFile != null) {
            if (!selectedFile.equals(sourceNameField.getText())) {
                //Be sure it is valid before we go setting any names
                ZipFile sourceFile = getSpecifiedSourceFile(selectedFile);
                if (sourceFile != null) {
                    closeZipFile(sourceFile);
                    setSourceName(selectedFile);
                    selectionGroup.setFocus();
                }
            }
        }
    }

    /**
     *  Import the resources with extensions as specified by the user
     */
    protected boolean importResources(List fileSystemObjects) {
        ZipFile zipFile = getSpecifiedSourceFile();
        ZipFileStructureProvider structureProvider = getStructureProvider(zipFile);
        ImportOperation operation = new ImportOperation(getContainerFullPath(),
                structureProvider.getRoot(), structureProvider, this,
                fileSystemObjects);

        operation.setContext(getShell());
        boolean result = executeImportOperation(operation);

        closeZipFile(zipFile);

        return result;
    }

    /**
     * Initializes the specified operation appropriately.
     */
    protected void initializeOperation(ImportOperation op) {
        op.setOverwriteResources(overwriteExistingResourcesCheckbox
                .getSelection());
    }

    /**
     * Opens a file selection dialog and returns a string representing the
     * selected file, or <code>null</code> if the dialog was canceled.
     */
    protected String queryZipFileToImport() {
        FileDialog dialog = new FileDialog(sourceNameField.getShell(), SWT.OPEN);
        dialog.setFilterExtensions(FILE_IMPORT_MASK);
        dialog.setText(DataTransferMessages.ZipImportSource_title);

        String currentSourceString = sourceNameField.getText();
        int lastSeparatorIndex = currentSourceString
                .lastIndexOf(File.separator);
        if (lastSeparatorIndex != -1) {
			dialog.setFilterPath(currentSourceString.substring(0,
                    lastSeparatorIndex));
		}

        return dialog.open();
    }

    /**
     *	Repopulate the view based on the currently entered directory.
     */
    protected void resetSelection() {

        super.resetSelection();
        setAllSelections(true);
    }

    /**
     *	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();
        if (settings != null) {
            String[] sourceNames = settings.getArray(STORE_SOURCE_NAMES_ID);
            if (sourceNames == null) {
				return; // ie.- no settings stored
			}

            // set filenames history
            for (int i = 0; i < sourceNames.length; i++) {
				sourceNameField.add(sourceNames[i]);
			}

            // radio buttons and checkboxes	
            overwriteExistingResourcesCheckbox.setSelection(settings
                    .getBoolean(STORE_OVERWRITE_EXISTING_RESOURCES_ID));
        }
    }

    /**
     * 	Since Finish was pressed, write widget values to the dialog store so that they
     *	will persist into the next invocation of this wizard page.
     *
     *	Note that this method is identical to the one that appears in the superclass.
     *	This is necessary because proper overriding of instance variables is not occurring.
     */
    protected void saveWidgetValues() {
        IDialogSettings settings = getDialogSettings();
        if (settings != null) {
            // update source names history
            String[] sourceNames = settings.getArray(STORE_SOURCE_NAMES_ID);
            if (sourceNames == null) {
				sourceNames = new String[0];
			}

            sourceNames = addToHistory(sourceNames, sourceNameField.getText());
            settings.put(STORE_SOURCE_NAMES_ID, sourceNames);

            // update specific types to import history
            String[] selectedTypesNames = settings
                    .getArray(STORE_SELECTED_TYPES_ID);
            if (selectedTypesNames == null) {
				selectedTypesNames = new String[0];
			}

            settings.put(STORE_OVERWRITE_EXISTING_RESOURCES_ID,
                    overwriteExistingResourcesCheckbox.getSelection());
        }
    }

    /**
     *	Answer a boolean indicating whether self's source specification
     *	widgets currently all contain valid values.
     */
    protected boolean validateSourceGroup() {

        //If there is nothing being provided to the input then there is a problem
        if (this.currentProvider == null) {
            setMessage(SOURCE_EMPTY_MESSAGE);
            enableButtonGroup(false);
            return false;
        } else {
            enableButtonGroup(true);
            return true;
        }
    }
}
