//------------------------------------------------------------------------------
// Copyright (c) 2005, 2007 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 implementation
//------------------------------------------------------------------------------
package org.eclipse.epf.publishing.ui.wizards;

import java.io.File;
import java.util.ArrayList;
import java.util.List;

import org.eclipse.epf.authoring.ui.AuthoringUIText;
import org.eclipse.epf.publishing.ui.PublishingUIPlugin;
import org.eclipse.epf.publishing.ui.PublishingUIResources;
import org.eclipse.epf.publishing.ui.preferences.PublishingUIPreferences;
import org.eclipse.epf.ui.wizards.BaseWizardPage;
import org.eclipse.epf.uma.MethodConfiguration;
import org.eclipse.jface.wizard.IWizardPage;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.ModifyEvent;
import org.eclipse.swt.events.ModifyListener;
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.DirectoryDialog;
import org.eclipse.swt.widgets.Group;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Shell;

/**
 * A wizard page that prompts the user to select the destination directory and
 * format for the published web site.
 * 
 * @author Kelvin Low
 * @since 1.2
 */
public class SelectDestinationPage extends BaseWizardPage {

	public static final String PAGE_NAME = SelectDestinationPage.class
			.getName();

	protected Shell shell;

	protected Combo dirCombo;

	protected Button browseButton;

	protected Button staticWebSiteRadioButton;

	protected Composite staticWebSiteComposite;

	protected Button javaWebAppRadioButton;

	protected Composite javaWebAppComposite;

	protected Label webAppNameLabel;

	protected Combo webAppNameCombo;

	protected Button includeSearchCheckbox;

	protected MethodConfiguration config;

	protected List<MethodConfiguration> selectedConfigs = new ArrayList<MethodConfiguration>();

	/**
	 * Creates a new instance.
	 */
	public SelectDestinationPage() {
		super(PAGE_NAME);
		setTitle(PublishingUIResources.selectDestinationWizardPage_title);
		setDescription(PublishingUIResources.selectDestinationWizardPage_text);
		setImageDescriptor(PublishingUIPlugin.getDefault().getImageDescriptor(
				"full/wizban/PublishConfiguration.gif")); //$NON-NLS-1$
	}

	/**
	 * @see org.eclipse.jface.dialogs.IDialogPage#createControl(Composite)
	 */
	public void createControl(Composite parent) {
		shell = parent.getShell();

		Composite composite = createGridLayoutComposite(parent, 1);

		Composite dirComposite = new Composite(composite, SWT.NONE);
		dirComposite.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
		dirComposite.setLayout(new GridLayout(3, false));

		createLabel(dirComposite, PublishingUIResources.dirLabel_text);

		dirCombo = createCombobox(dirComposite);

		browseButton = createButton(dirComposite,
				AuthoringUIText.BROWSE_BUTTON_TEXT);

		Group webAppGroup = new Group(composite, SWT.NULL);
		webAppGroup.setLayout(new GridLayout(1, false));
		webAppGroup.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
		webAppGroup.setText(PublishingUIResources.webAppGroup_text);

		staticWebSiteRadioButton = createRadioButton(webAppGroup,
				PublishingUIResources.staticWebSiteRadioButton_text);

		staticWebSiteComposite = new Composite(webAppGroup, SWT.NONE);
		staticWebSiteComposite.setLayoutData(new GridData(
				GridData.FILL_HORIZONTAL));
		staticWebSiteComposite.setLayout(new GridLayout(1, false));
		((GridLayout) staticWebSiteComposite.getLayout()).marginTop = -3;
		((GridLayout) staticWebSiteComposite.getLayout()).marginLeft = 13;

		javaWebAppRadioButton = createRadioButton(webAppGroup,
				PublishingUIResources.dynamicWebAppRadioButton_text);

		javaWebAppComposite = new Composite(webAppGroup, SWT.NONE);
		javaWebAppComposite
				.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
		javaWebAppComposite.setLayout(new GridLayout(3, false));
		((GridLayout) javaWebAppComposite.getLayout()).marginTop = -3;
		((GridLayout) javaWebAppComposite.getLayout()).marginLeft = 13;

		includeSearchCheckbox = createCheckbox(javaWebAppComposite,
				PublishingUIResources.includeSearchCheckbox_text, 3);

		webAppNameLabel = createLabel(javaWebAppComposite,
				PublishingUIResources.webApplicationNameLabel_text);

		webAppNameCombo = createCombobox(javaWebAppComposite, 2);
		webAppNameCombo.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));

		initControls();

		addEventHandlers();

		setControl(composite);
	}

	/**
	 * Initializes the wizard page controls with data.
	 */
	protected void initControls() {
		String configId = config != null ? config.getGuid() : ""; //$NON-NLS-1$

		String dir = PublishingUIPreferences.getPublishPath(configId);
		if (dir != null && dir.length() > 0) {
			dirCombo.setItems(new String[] { dir });
			dirCombo.setText(dir);
		}

		boolean publishStaticWebSite = PublishingUIPreferences
				.getPublishStaticWebSite(configId);
		staticWebSiteRadioButton.setSelection(publishStaticWebSite);
		javaWebAppRadioButton.setSelection(!publishStaticWebSite);

		includeSearchCheckbox.setSelection(PublishingUIPreferences
				.getIncludeSearch(configId));

		String webAppName = PublishingUIPreferences.getWebAppName(configId);
		if (webAppName != null && webAppName.length() > 0) {
			webAppNameCombo.setItems(new String[] { webAppName });
			webAppNameCombo.setText(webAppName);
		}

		updateControls();
	}

	/**
	 * Adds event handlers to the wizard page controls.
	 */
	protected void addEventHandlers() {
		dirCombo.addModifyListener(new ModifyListener() {
			public void modifyText(ModifyEvent e) {
				setPageComplete(isPageComplete());
			}
		});

		browseButton.addSelectionListener(new SelectionAdapter() {
			public void widgetSelected(SelectionEvent event) {
				try {
					DirectoryDialog dialog = new DirectoryDialog(shell,
							SWT.NONE);
					String selectedDir = dialog.open();
					if (selectedDir != null) {
						dirCombo.add(selectedDir, 0);
						dirCombo.setText(selectedDir);
					}
				} catch (Exception e) {
					PublishingUIPlugin.getDefault().getLogger().logError(e);
				}
			}
		});

		staticWebSiteRadioButton.addSelectionListener(new SelectionAdapter() {
			public void widgetSelected(SelectionEvent event) {
				updateControls();
			}
		});

		javaWebAppRadioButton.addSelectionListener(new SelectionAdapter() {
			public void widgetSelected(SelectionEvent event) {
				updateControls();
			}
		});
	}

	/**
	 * Updates the control.
	 */
	protected void updateControls() {
		boolean publishStaticWebSite = getStaticWebSiteSelection();
		webAppNameLabel.setEnabled(!publishStaticWebSite);
		webAppNameCombo.setEnabled(!publishStaticWebSite);
		includeSearchCheckbox.setEnabled(!publishStaticWebSite);
	}

	/**
	 * @see org.eclipse.epf.ui.wizards.BaseWizardPage#onEnterPage(Object)
	 */
	public void onEnterPage(Object obj) {
		if (obj != null && obj instanceof MethodConfiguration) {
			config = (MethodConfiguration) obj;
			if (!selectedConfigs.contains(config)) {
				selectedConfigs.add(config);
				initControls();
			}
		}
	}

	/**
	 * @see org.eclipse.jface.wizard.WizardPage#isCompleted()
	 */
	public boolean isPageComplete() {
		return getPublishDirectory().length() > 0;

	}

	/**
	 * @see org.eclipse.jface.wizard.WizardPage#getNextPage()
	 */
	public IWizardPage getNextPage() {
		return null;
	}

	/**
	 * Gets the user specified publish directory.
	 */
	public String getPublishDirectory() {
		File dir = new File(dirCombo.getText().trim());
		return dir.getAbsolutePath();
	}

	/**
	 * Gets the user specified static web site selection.
	 */
	public boolean getStaticWebSiteSelection() {
		return staticWebSiteRadioButton.getSelection();
	}

	/**
	 * Gets the user specified include search selection.
	 */
	public boolean getIncludeSearchSelection() {
		return includeSearchCheckbox.getSelection();
	}

	/**
	 * Gets the web aplication name.
	 */
	public String getWebAppName() {
		return webAppNameCombo.getText().trim();
	}

	/**
	 * Saves the user selections in this wizard page to preference store.
	 */
	public void savePreferences() {
		if (config != null) {
			String configId = config.getGuid();
			PublishingUIPreferences.setPublishPath(configId,
					getPublishDirectory());
			PublishingUIPreferences.setPublishStaticWebSite(configId,
					getStaticWebSiteSelection());
			PublishingUIPreferences.setIncludeSearch(configId,
					getIncludeSearchSelection());
			PublishingUIPreferences.setWebAppName(configId, getWebAppName());
		}
	}

}