/*******************************************************************************
 * 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.jdt.internal.ui.jarpackager;

import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.IWorkspace;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Path;

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.Composite;
import org.eclipse.swt.widgets.Event;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Listener;
import org.eclipse.swt.widgets.Text;

import org.eclipse.jface.dialogs.Dialog;
import org.eclipse.jface.dialogs.IDialogSettings;
import org.eclipse.jface.resource.JFaceResources;
import org.eclipse.jface.window.Window;
import org.eclipse.jface.wizard.IWizardPage;
import org.eclipse.jface.wizard.WizardPage;

import org.eclipse.ui.dialogs.SaveAsDialog;
import org.eclipse.ui.PlatformUI;

import org.eclipse.jdt.internal.corext.util.Messages;

import org.eclipse.jdt.ui.jarpackager.JarPackageData;

import org.eclipse.jdt.internal.ui.IJavaHelpContextIds;
import org.eclipse.jdt.internal.ui.JavaPlugin;

import org.eclipse.jdt.internal.ui.util.SWTUtil;

/**
 *	Page 2 of the JAR Package wizard
 */
class JarOptionsPage extends WizardPage implements IJarPackageWizardPage {

	// Untyped listener
	private class UntypedListener implements Listener {
		/*
		 * Implements method from Listener
		 */	
		public void handleEvent(Event e) {
			if (getControl() == null)
				return;
			update();
		}
	}

	private JarPackageData fJarPackage;

	// widgets
	private Button		fExportErrorsCheckbox;
	private Button		fExportWarningsCheckbox;
	private Button		fUseSourceFoldersCheckbox;
	private Composite	fDescriptionFileGroup;
	private Button		fSaveDescriptionCheckbox;
	private Label		fDescriptionFileLabel;
	private Text		fDescriptionFileText;
	private Button		fDescriptionFileBrowseButton;
	private Button		fBuildIfNeededCheckbox;

	// dialog store id constants
	private final static String PAGE_NAME= "jarOptionsWizardPage"; //$NON-NLS-1$
	
	private final static String STORE_EXPORT_WARNINGS= PAGE_NAME + ".EXPORT_WARNINGS"; //$NON-NLS-1$
	private final static String STORE_EXPORT_ERRORS= PAGE_NAME + ".EXPORT_ERRORS"; //$NON-NLS-1$
	private final static String STORE_SAVE_DESCRIPTION= PAGE_NAME + ".SAVE_DESCRIPTION"; //$NON-NLS-1$
	private final static String STORE_DESCRIPTION_LOCATION= PAGE_NAME + ".DESCRIPTION_LOCATION"; //$NON-NLS-1$
	private final static String STORE_USE_SRC_FOLDERS= PAGE_NAME + ".STORE_USE_SRC_FOLDERS"; //$NON-NLS-1$
	private final static String STORE_BUILD_IF_NEEDED= PAGE_NAME + ".BUILD_IF_NEEDED"; //$NON-NLS-1$

	/**
	 *	Create an instance of this class
	 */
	public JarOptionsPage(JarPackageData jarPackage) {
		super(PAGE_NAME);
		setTitle(JarPackagerMessages.JarOptionsPage_title); 
		setDescription(JarPackagerMessages.JarOptionsPage_description); 
		fJarPackage= jarPackage;
	}

	/*
	 * Method declared on IDialogPage.
	 */
	public void createControl(Composite parent) {
		Composite composite= new Composite(parent, SWT.NULL);
		composite.setLayout(new GridLayout());
		composite.setLayoutData(
			new GridData(GridData.VERTICAL_ALIGN_FILL | GridData.HORIZONTAL_ALIGN_FILL));

		createOptionsGroup(composite);

		restoreWidgetValues();
		setControl(composite);
		update();

		Dialog.applyDialogFont(composite);
		PlatformUI.getWorkbench().getHelpSystem().setHelp(composite, IJavaHelpContextIds.JAROPTIONS_WIZARD_PAGE);								
	}

	/**
	 *	Create the export options specification widgets.
	 *
	 *	@param parent org.eclipse.swt.widgets.Composite
	 */
	protected void createOptionsGroup(Composite parent) {
		
		initializeDialogUnits(parent);
		
		Composite optionsGroup= new Composite(parent, SWT.NONE);
		GridLayout layout= new GridLayout();
		layout.marginHeight= 0;
		optionsGroup.setLayout(layout);

		createLabel(optionsGroup, JarPackagerMessages.JarOptionsPage_howTreatProblems_label, false); 

		UntypedListener selectionListener= new UntypedListener();

		fExportErrorsCheckbox= new Button(optionsGroup, SWT.CHECK | SWT.LEFT);
		fExportErrorsCheckbox.setText(JarPackagerMessages.JarOptionsPage_exportErrors_text); 
		fExportErrorsCheckbox.addListener(SWT.Selection, selectionListener);

		fExportWarningsCheckbox= new Button(optionsGroup, SWT.CHECK | SWT.LEFT);
		fExportWarningsCheckbox.setText(JarPackagerMessages.JarOptionsPage_exportWarnings_text); 
		fExportWarningsCheckbox.addListener(SWT.Selection, selectionListener);

		createSpacer(optionsGroup);

		fUseSourceFoldersCheckbox= new Button(optionsGroup, SWT.CHECK | SWT.LEFT);
		fUseSourceFoldersCheckbox.setText(JarPackagerMessages.JarOptionsPage_useSourceFoldersHierarchy); 
		fUseSourceFoldersCheckbox.addListener(SWT.Selection, selectionListener);
		fUseSourceFoldersCheckbox.setEnabled(fJarPackage.areJavaFilesExported() && !fJarPackage.areGeneratedFilesExported());

		createSpacer(optionsGroup);

		fBuildIfNeededCheckbox= new Button(optionsGroup, SWT.CHECK | SWT.LEFT);
		fBuildIfNeededCheckbox.setText(JarPackagerMessages.JarOptionsPage_buildIfNeeded); 
		fBuildIfNeededCheckbox.addListener(SWT.Selection, selectionListener);

		createSpacer(optionsGroup);
		
		fSaveDescriptionCheckbox= new Button(optionsGroup, SWT.CHECK | SWT.LEFT);
		fSaveDescriptionCheckbox.setText(JarPackagerMessages.JarOptionsPage_saveDescription_text); 
		fSaveDescriptionCheckbox.addListener(SWT.Selection, selectionListener);
		createDescriptionFileGroup(parent);
	}

	/**
	 * Persists resource specification control setting that are to be restored
	 * in the next instance of this page. Subclasses wishing to persist
	 * settings for their controls should extend the hook method 
	 * <code>internalSaveWidgetValues</code>.
	 */
	public final void saveWidgetValues() {
		// update directory names history
		IDialogSettings settings= getDialogSettings();
		if (settings != null) {
			settings.put(STORE_EXPORT_WARNINGS, fJarPackage.exportWarnings());
			settings.put(STORE_EXPORT_ERRORS, fJarPackage.areErrorsExported());
			settings.put(STORE_USE_SRC_FOLDERS, fJarPackage.useSourceFolderHierarchy());
			settings.put(STORE_BUILD_IF_NEEDED, fJarPackage.isBuildingIfNeeded());
			settings.put(STORE_SAVE_DESCRIPTION, fJarPackage.isDescriptionSaved());
			settings.put(STORE_DESCRIPTION_LOCATION, fJarPackage.getDescriptionLocation().toString());
		}
		// Allow subclasses to save values
		internalSaveWidgetValues();
	}

	/**
	 * Hook method for subclasses to persist their settings.
	 */
	protected void internalSaveWidgetValues() {
	}

	/**
	 *	Hook method for restoring widget values to the values that they held
	 *	last time this wizard was used to completion.
	 */
	protected void restoreWidgetValues() {
		if (!((JarPackageWizard)getWizard()).isInitializingFromJarPackage())
			initializeJarPackage();

		fExportWarningsCheckbox.setSelection(fJarPackage.exportWarnings());
		fExportErrorsCheckbox.setSelection(fJarPackage.areErrorsExported());
		fBuildIfNeededCheckbox.setSelection(fJarPackage.isBuildingIfNeeded());
		fUseSourceFoldersCheckbox.setSelection(fJarPackage.useSourceFolderHierarchy());
		fSaveDescriptionCheckbox.setSelection(fJarPackage.isDescriptionSaved());
		fDescriptionFileText.setText(fJarPackage.getDescriptionLocation().toString());
	}

	/**
	 *	Initializes the JAR package from last used wizard page values.
	 */
	protected void initializeJarPackage() {
		IDialogSettings settings= getDialogSettings();
		if (settings != null) {
			fJarPackage.setExportWarnings(settings.getBoolean(STORE_EXPORT_WARNINGS));
			fJarPackage.setExportErrors(settings.getBoolean(STORE_EXPORT_ERRORS));
			fJarPackage.setUseSourceFolderHierarchy(settings.getBoolean(STORE_USE_SRC_FOLDERS));
			fJarPackage.setSaveDescription(false); // bug 15877
			String pathStr= settings.get(STORE_DESCRIPTION_LOCATION);
			if (pathStr == null)
				pathStr= ""; //$NON-NLS-1$
			fJarPackage.setDescriptionLocation(new Path(pathStr));
			if (settings.get(STORE_BUILD_IF_NEEDED) != null)
				fJarPackage.setBuildIfNeeded(settings.getBoolean(STORE_BUILD_IF_NEEDED));
		}
	}

	private void update() {
		updateModel();
		updateWidgetEnablements();
		updatePageCompletion();
	}

	/**
	 *	Stores the widget values in the JAR package.
	 */
	protected void updateModel() {
		if (getControl() == null)
			return;
		fJarPackage.setExportWarnings(fExportWarningsCheckbox.getSelection());
		fJarPackage.setExportErrors(fExportErrorsCheckbox.getSelection());
		fJarPackage.setBuildIfNeeded(fBuildIfNeededCheckbox.getSelection());
		fJarPackage.setSaveDescription(fSaveDescriptionCheckbox.getSelection());
		fJarPackage.setDescriptionLocation(new Path(fDescriptionFileText.getText()));
		fJarPackage.setUseSourceFolderHierarchy(fUseSourceFoldersCheckbox.getSelection());
	}

	/**
	 *	Open an appropriate destination browser so that the user can specify a source
	 *	to import from
	 */
	protected void handleDescriptionFileBrowseButtonPressed() {
		SaveAsDialog dialog= new SaveAsDialog(getContainer().getShell());
		dialog.create();
		dialog.getShell().setText(JarPackagerMessages.JarOptionsPage_saveAsDialog_title); 
		dialog.setMessage(JarPackagerMessages.JarOptionsPage_saveAsDialog_message); 
		dialog.setOriginalFile(createFileHandle(fJarPackage.getDescriptionLocation()));
		if (dialog.open() == Window.OK) {
			IPath path= dialog.getResult();
			path= path.removeFileExtension().addFileExtension(JarPackagerUtil.DESCRIPTION_EXTENSION);
			fDescriptionFileText.setText(path.toString());
		}
	}

	/**
	 * Updates the enablements of this page's controls. Subclasses may extend.
	 */
	protected void updateWidgetEnablements() {
		boolean saveDescription= fSaveDescriptionCheckbox.getSelection();
		fDescriptionFileGroup.setEnabled(saveDescription);
		fDescriptionFileBrowseButton.setEnabled(saveDescription);
		fDescriptionFileText.setEnabled(saveDescription);
		fDescriptionFileLabel.setEnabled(saveDescription);
		
		boolean exportClassFiles= fJarPackage.areClassFilesExported() && !fJarPackage.areOutputFoldersExported();
		fExportWarningsCheckbox.setEnabled(exportClassFiles);
		fExportErrorsCheckbox.setEnabled(exportClassFiles);
		
		boolean isAutobuilding= ResourcesPlugin.getWorkspace().isAutoBuilding();
		fBuildIfNeededCheckbox.setEnabled(exportClassFiles && !isAutobuilding);
		
		fUseSourceFoldersCheckbox.setEnabled(fJarPackage.areJavaFilesExported() && !fJarPackage.areGeneratedFilesExported());		
	}

	/*
	 * Implements method from IJarPackageWizardPage
	 */
	public boolean isPageComplete() {
		if (fJarPackage.isDescriptionSaved()){
			if (fJarPackage.getDescriptionLocation().toString().length() == 0) {
				setErrorMessage(null);
				return false;
			}
			IPath location= fJarPackage.getDescriptionLocation();
			if (!location.toString().startsWith("/")) { //$NON-NLS-1$
				setErrorMessage(JarPackagerMessages.JarOptionsPage_error_descriptionMustBeAbsolute); 
				return false;
			}			
			IResource resource= findResource(location);
			if (resource != null && resource.getType() != IResource.FILE) {
				setErrorMessage(JarPackagerMessages.JarOptionsPage_error_descriptionMustNotBeExistingContainer); 
				return false;
			}
			resource= findResource(location.removeLastSegments(1));
			if (resource == null || resource.getType() == IResource.FILE) {
				setErrorMessage(JarPackagerMessages.JarOptionsPage_error_descriptionContainerDoesNotExist); 
				return false;
			}
			String fileExtension= fJarPackage.getDescriptionLocation().getFileExtension();
			if (fileExtension == null || !fileExtension.equals(JarPackagerUtil.DESCRIPTION_EXTENSION)) {
				setErrorMessage(Messages.format(JarPackagerMessages.JarOptionsPage_error_invalidDescriptionExtension, JarPackagerUtil.DESCRIPTION_EXTENSION)); 
				return false;
			}
		}
		setErrorMessage(null);		
		return true;
	}
	
	public boolean canFlipToNextPage() {
		return fJarPackage.areGeneratedFilesExported() && super.canFlipToNextPage();
	}
	
	/*
	 * Overrides method from WizardDataTransferPage
	 */
	protected void createDescriptionFileGroup(Composite parent) {
		// destination specification group
		fDescriptionFileGroup= new Composite(parent, SWT.NONE);
		GridLayout layout= new GridLayout();
		layout.numColumns= 3;
		fDescriptionFileGroup.setLayout(layout);
		fDescriptionFileGroup.setLayoutData(new GridData(GridData.HORIZONTAL_ALIGN_FILL | GridData.VERTICAL_ALIGN_FILL | GridData.GRAB_HORIZONTAL));

		fDescriptionFileLabel= new Label(fDescriptionFileGroup, SWT.NONE);
		fDescriptionFileLabel.setText(JarPackagerMessages.JarOptionsPage_descriptionFile_label); 

		// destination name entry field
		fDescriptionFileText= new Text(fDescriptionFileGroup, SWT.SINGLE | SWT.BORDER);
		fDescriptionFileText.addListener(SWT.Modify, new UntypedListener());
		GridData data= new GridData(GridData.HORIZONTAL_ALIGN_FILL | GridData.GRAB_HORIZONTAL);
		data.widthHint= convertWidthInCharsToPixels(40);
		fDescriptionFileText.setLayoutData(data);

		// destination browse button
		fDescriptionFileBrowseButton= new Button(fDescriptionFileGroup, SWT.PUSH);
		fDescriptionFileBrowseButton.setText(JarPackagerMessages.JarOptionsPage_browseButton_text); 
		fDescriptionFileBrowseButton.setLayoutData(new GridData(GridData.HORIZONTAL_ALIGN_FILL));
		SWTUtil.setButtonDimensionHint(fDescriptionFileBrowseButton);
		fDescriptionFileBrowseButton.addSelectionListener(new SelectionAdapter() {
			public void widgetSelected(SelectionEvent e) {
				handleDescriptionFileBrowseButtonPressed();
			}
		});
	}

	/**
	 * Creates a file resource handle for the file with the given workspace path.
	 * This method does not create the file resource; this is the responsibility
	 * of <code>createFile</code>.
	 *
	 * @param filePath the path of the file resource to create a handle for
	 * @return the new file resource handle
	 */
	protected IFile createFileHandle(IPath filePath) {
		if (filePath.isValidPath(filePath.toString()) && filePath.segmentCount() >= 2)
			return JavaPlugin.getWorkspace().getRoot().getFile(filePath);
		else
			return null;
	}
	/* 
	 * Method declared on IWizardPage.
	 */
	public void setPreviousPage(IWizardPage page) {
		super.setPreviousPage(page);
		updateWidgetEnablements();
		if (getControl() != null)
			updatePageCompletion();
	}

	/* 
	 * Implements method from IJarPackageWizardPage.
	 */
	public void finish() {
		saveWidgetValues();
	}

	/**
	 * Creates a new label with a bold font.
	 *
	 * @param parent the parent control
	 * @param text the label text
	 * @return the new label control
	 */
	protected Label createLabel(Composite parent, String text, boolean bold) {
		Label label= new Label(parent, SWT.NONE);
		if (bold)
			label.setFont(JFaceResources.getBannerFont());
		label.setText(text);
		GridData data= new GridData();
		data.verticalAlignment= GridData.FILL;
		data.horizontalAlignment= GridData.FILL;
		label.setLayoutData(data);
		return label;
	}

	/**
	 * Creates a horizontal spacer line that fills the width of its container.
	 *
	 * @param parent the parent control
	 */
	protected void createSpacer(Composite parent) {
		Label spacer= new Label(parent, SWT.NONE);
		GridData data= new GridData();
		data.horizontalAlignment= GridData.FILL;
		data.verticalAlignment= GridData.BEGINNING;
		spacer.setLayoutData(data);
	}

	/**
	 * Determine if the page is complete and update the page appropriately. 
	 */
	protected void updatePageCompletion() {
		boolean pageComplete= isPageComplete();
		setPageComplete(pageComplete);
		if (pageComplete) {
			setErrorMessage(null);
		}
	}

	/**
	 * Returns the resource for the specified path.
	 *
	 * @param path	the path for which the resource should be returned
	 * @return the resource specified by the path or <code>null</code>
	 */
	protected IResource findResource(IPath path) {
		IWorkspace workspace= JavaPlugin.getWorkspace();
		IStatus result= workspace.validatePath(
							path.toString(),
							IResource.ROOT | IResource.PROJECT | IResource.FOLDER | IResource.FILE);
		if (result.isOK() && workspace.getRoot().exists(path))
			return workspace.getRoot().findMember(path);
		return null;
	}
}
