/*******************************************************************************
 * Copyright (c) 2003, 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
 *******************************************************************************/
/*
 * Created on Dec 3, 2003
 *
 * To change the template for this generated file go to
 * Window>Preferences>Java>Code Generation>Code and Comments
 */
package org.eclipse.jst.j2ee.internal.wizard;

import java.util.ArrayList;
import java.util.Iterator;

import org.eclipse.core.resources.IResource;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.jem.util.emf.workbench.ProjectUtilities;
import org.eclipse.jface.dialogs.IDialogSettings;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.jst.j2ee.datamodel.properties.IJ2EEComponentExportDataModelProperties;
import org.eclipse.jst.j2ee.internal.plugin.J2EEUIMessages;
import org.eclipse.jst.j2ee.internal.plugin.J2EEUIPlugin;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Combo;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.FileDialog;
import org.eclipse.swt.widgets.Label;
import org.eclipse.wst.common.frameworks.datamodel.IDataModel;
import org.eclipse.wst.common.frameworks.internal.datamodel.ui.DataModelWizardPage;

/**
 * @author cbridgha
 * 
 * To change the template for this generated type comment go to Window>Preferences>Java>Code
 * Generation>Code and Comments
 */
public abstract class J2EEExportPage extends DataModelWizardPage {

	public static boolean isWindows = SWT.getPlatform().toLowerCase().startsWith("win"); //$NON-NLS-1$

	protected IStructuredSelection currentResourceSelection;
	private static final int SIZING_TEXT_FIELD_WIDTH = 305;
	private static final String STORE_LABEL = "J2EE_EXPORT_"; //$NON-NLS-1$
	private static final String OVERWRITE_LABEL = "OVERWRITE"; //$NON-NLS-1$
	private static final String SOURCE_LABEL = "SOURCE"; //$NON-NLS-1$
//	private static final String META_LABEL = "META"; //$NON-NLS-1$
	protected static final String defBrowseButtonLabel = J2EEUIMessages.getResourceString(J2EEUIMessages.BROWSE_LABEL);
	protected String LABEL_DESTINATION = J2EEUIMessages.getResourceString(J2EEUIMessages.J2EE_EXPORT_DESTINATION);
	private Combo resourceNameCombo;
	private Combo destinationNameCombo;
	private Button destinationBrowseButton;
	protected Button overwriteExistingFilesCheckbox;
	private Button sourceFilesCheckbox;

	/**
	 * @param model
	 * @param pageName
	 */
	public J2EEExportPage(IDataModel model, String pageName, IStructuredSelection selection) {
		super(model, pageName);
		currentResourceSelection = selection;

	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.wst.common.frameworks.internal.ui.wizard.WTPWizardPage#getValidationPropertyNames()
	 */
	protected String[] getValidationPropertyNames() {
		return null;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.wst.common.frameworks.internal.ui.wizard.WTPWizardPage#createTopLevelComposite(org.eclipse.swt.widgets.Composite)
	 */
	protected Composite createTopLevelComposite(Composite parent) {

		Composite composite = new Composite(parent, SWT.NULL);
		//WorkbenchHelp.setHelp(composite, getInfopopID());
		GridLayout layout = new GridLayout(1, false);
		composite.setLayout(layout);

		createSourceAndDestinationGroup(composite);
		createOptionsGroup(composite);

		//setupBasedOnInitialSelections();
		setupInfopop(composite);
		return composite;
	}

	/**
	 * @param composite
	 */
	private void createSourceAndDestinationGroup(Composite parent) {

		Composite composite = new Composite(parent, SWT.NULL);
		GridLayout layout = new GridLayout(3, false);
		composite.setLayout(layout);
		createExportComponentGroup(composite);
		createDestinationGroup(composite);

	}
    /**
     * Creates the export source resource specification widgets.
     * 
     * @param parent
     *            a <code>Composite</code> that is to be used as the parent of this group's
     *            collection of visual components
     * @see org.eclipse.swt.widgets.Composite
     */
    protected void createExportComponentGroup(Composite parent) {
        //Project label
        Label projectLabel = new Label(parent, SWT.NONE);
        projectLabel.setText(getComponentLabel());
        //Project combo
        resourceNameCombo = new Combo(parent, SWT.SINGLE | SWT.BORDER);
        GridData data = new GridData(GridData.FILL_HORIZONTAL);
        data.widthHint = SIZING_TEXT_FIELD_WIDTH;
        resourceNameCombo.setLayoutData(data);
        synchHelper.synchCombo(resourceNameCombo, IJ2EEComponentExportDataModelProperties.COMPONENT_NAME, null);
        new Label(parent, SWT.NONE);//Pad label
    }

    /**
     * @return
     */
    protected abstract String getComponentLabel();

    protected void createDestinationGroup(org.eclipse.swt.widgets.Composite parent) {

        //Destination label
        Label destinationLabel = new Label(parent, SWT.NONE);
        destinationLabel.setText(LABEL_DESTINATION);
        // destination name combo field
        destinationNameCombo = new Combo(parent, SWT.SINGLE | SWT.BORDER);
        destinationNameCombo.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
        synchHelper.synchCombo(destinationNameCombo, IJ2EEComponentExportDataModelProperties.ARCHIVE_DESTINATION, null);

        // destination browse button
        destinationBrowseButton = new Button(parent, SWT.PUSH);
        destinationBrowseButton.setText(defBrowseButtonLabel); //$NON-NLS-1$
        destinationBrowseButton.setLayoutData((new GridData(GridData.FILL_HORIZONTAL)));
        destinationBrowseButton.addSelectionListener(new SelectionAdapter() {
            public void widgetSelected(SelectionEvent e) {
                handleDestinationBrowseButtonPressed();
            }
        });
        destinationBrowseButton.setEnabled(true);

    }
    
    /**
     * Create the export options specification widgets.
     * 
     * @param parent
     *            org.eclipse.swt.widgets.Composite
     */
    protected void createOptionsGroup(Composite parent) {

        // options group
        Composite optionsGroup = new Composite(parent, SWT.NULL);
        GridLayout layout = new GridLayout(1, false);
        optionsGroup.setLayout(layout);


        // source files... checkbox
        createSourceFilesCheckbox(optionsGroup);

        // overwrite... checkbox
        createOverwriteExistingFilesCheckbox(optionsGroup);

        // advanced button
        if (shouldShowProjectFilesCheckbox()) {
            createProjectFilesCheckbox(optionsGroup);
        }
    }
    
	protected void createOverwriteExistingFilesCheckbox(Composite optionsGroup) {
		//Overwrite checkbox
		overwriteExistingFilesCheckbox = new Button(optionsGroup, SWT.CHECK | SWT.LEFT);
		overwriteExistingFilesCheckbox.setText(J2EEUIMessages.getResourceString(J2EEUIMessages.J2EE_EXPORT_OVERWRITE_CHECKBOX)); //$NON-NLS-1$ = "Overwrite existing files without warning"
		overwriteExistingFilesCheckbox.setEnabled(true);
		synchHelper.synchCheckbox(overwriteExistingFilesCheckbox, IJ2EEComponentExportDataModelProperties.OVERWRITE_EXISTING, null);
	}

	protected void createSourceFilesCheckbox(Composite optionsGroup) {
		sourceFilesCheckbox = new Button(optionsGroup, SWT.CHECK | SWT.LEFT);
		sourceFilesCheckbox.setText(J2EEUIMessages.getResourceString(J2EEUIMessages.J2EE_EXPORT_SOURCE_CHECKBOX)); //$NON-NLS-1$
		synchHelper.synchCheckbox(sourceFilesCheckbox, IJ2EEComponentExportDataModelProperties.EXPORT_SOURCE_FILES, null);
	}

	/**
	 * @return
	 */
	protected boolean shouldShowProjectFilesCheckbox() {
		return false;
	}

	protected void createProjectFilesCheckbox(Composite composite) {
		//do nothing
	}

	/**
	 * Populates the resource name field based upon the currently-selected resources.
	 */
	protected void setupBasedOnInitialSelections() {

		if (currentResourceSelection.isEmpty() || setupBasedOnRefObjectSelection())
			return; // no setup needed

		java.util.List selections = new ArrayList();
		Iterator aenum = currentResourceSelection.iterator();
		while (aenum.hasNext()) {
			IResource currentResource = (IResource) aenum.next();
			// do not add inaccessible elements
			if (currentResource.isAccessible())
				selections.add(currentResource);
		}
		if (selections.isEmpty())
			return; // setup not needed anymore

//		int selectedResourceCount = selections.size();
//TODO: find a way to select an existing component
//		if (selectedResourceCount == 1) {
//			IResource resource = (IResource) selections.get(0);
//			if ((resource instanceof IProject) && checkForNature((IProject) resource)) {
//				resourceNameCombo.setText(resource.getName().toString());
//			}
//		}
	}

	/**
	 * @return
	 */
	protected String getProjectImportLabel() {
		return null;
	}

	/**
	 *  
	 */
	protected void handleDestinationBrowseButtonPressed() {

		FileDialog dialog = new FileDialog(destinationNameCombo.getShell(), SWT.SAVE);
		String fileName = getDataModel().getStringProperty(IJ2EEComponentExportDataModelProperties.COMPONENT_NAME);
		String[] filters = getFilterExpression();
		if (!isWindows) {
			if (filters.length != 0 && filters[0] != null && filters[0].indexOf('.') != -1) {
				fileName += filters[0].substring(filters[0].indexOf('.'));
			}
		}
		dialog.setFileName(fileName);
		if (isWindows) {
			dialog.setFilterExtensions(filters);
		}
		String filename = dialog.open();
		if (filename != null)
			destinationNameCombo.setText(filename);
	}

	protected void restoreWidgetValues() {

		IDialogSettings settings = getDialogSettings();
		if (settings != null) {
			String[] sourceNames = settings.getArray(STORE_LABEL + getFileNamesStoreID());
			if (sourceNames == null)
				return; // ie.- no settings stored
			for (int i = 0; i < sourceNames.length; i++) {
				if (sourceNames[i] == null)
					sourceNames[i] = ""; //$NON-NLS-1$
			}
			destinationNameCombo.setItems(sourceNames);
			boolean overwrite = settings.getBoolean(STORE_LABEL + OVERWRITE_LABEL);
			model.setBooleanProperty(IJ2EEComponentExportDataModelProperties.OVERWRITE_EXISTING, overwrite);
			boolean includeSource = settings.getBoolean(STORE_LABEL + SOURCE_LABEL);
			model.setBooleanProperty(IJ2EEComponentExportDataModelProperties.EXPORT_SOURCE_FILES, includeSource);
		}
	}

	public void storeDefaultSettings() {
		IDialogSettings settings = getDialogSettings();
		if (settings != null) {
			// update source names history
			String[] sourceNames = settings.getArray(STORE_LABEL + getFileNamesStoreID());
			if (sourceNames == null) {
				sourceNames = new String[0];
			}

			String newName = destinationNameCombo.getText();

			//rip out any empty filenames and trim length to 5
			ArrayList newNames = new ArrayList();
			for (int i = 0; i < sourceNames.length && i < 5; i++) {
				if (sourceNames[i].trim().length() > 0 && !newName.equals(sourceNames[i])) {
					newNames.add(sourceNames[i]);
				}
			}
			newNames.add(0, destinationNameCombo.getText());
			sourceNames = new String[newNames.size()];
			newNames.toArray(sourceNames);

			settings.put(STORE_LABEL + getFileNamesStoreID(), sourceNames);
			settings.put(STORE_LABEL + OVERWRITE_LABEL, model.getBooleanProperty(IJ2EEComponentExportDataModelProperties.OVERWRITE_EXISTING));
			settings.put(STORE_LABEL + SOURCE_LABEL, model.getBooleanProperty(IJ2EEComponentExportDataModelProperties.EXPORT_SOURCE_FILES));
		}
	}

	/**
	 * @return
	 */
	protected String getFileNamesStoreID() {
		return getCompnentID();
	}
	protected abstract String getCompnentID();

    /**
	 * @return
	 */
	protected String[] getFilterExpression() {
		return new String[0];
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.wst.common.frameworks.internal.ui.wizard.WTPWizardPage#enter()
	 */
	protected void enter() {
		super.enter();
		restoreWidgetValues();
	}

	/**
	 * @return
	 */
	//protected abstract String getNatureID();

	protected abstract boolean isMetaTypeSupported(Object o);

	/**
	 * Populates the resource name field based upon the currently-selected resources.
	 */
	protected boolean setupBasedOnRefObjectSelection() {

		if (currentResourceSelection.size() != 1)
			return false;

		Object o = currentResourceSelection.getFirstElement();
		if (!isMetaTypeSupported(o))
			return false;

		EObject ref = (EObject) o;
		IResource resource = ProjectUtilities.getProject(ref);
		if (resource != null) {
			resourceNameCombo.setText(resource.getName().toString());
		}
		return true;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.jface.wizard.WizardPage#getDialogSettings()
	 */
	protected IDialogSettings getDialogSettings() {
		return J2EEUIPlugin.getDefault().getDialogSettings();
	}

}
