//------------------------------------------------------------------------------
// 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.authoring.ui.wizards;

import org.eclipse.epf.authoring.ui.AuthoringUIPlugin;
import org.eclipse.epf.authoring.ui.AuthoringUIResources;
import org.eclipse.epf.authoring.ui.AuthoringUIText;
import org.eclipse.epf.library.LibraryService;
import org.eclipse.epf.library.LibraryServiceUtil;
import org.eclipse.jface.wizard.WizardPage;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.ModifyEvent;
import org.eclipse.swt.events.ModifyListener;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Text;

/**
 * A wizard page that prompts the user to enter a name and description for a new
 * Method Configuration.
 * 
 * @author Bingxue Xu
 * @author Kelvin Low
 * @since 1.0
 */
public class NewConfigurationMainPage extends WizardPage {

	/**
	 * The wizard page name.
	 */
	public static final String PAGE_NAME = NewConfigurationMainPage.class
			.getName();

	protected Text nameText, briefDescText;

	private boolean noOpenLibrary;

	/**
	 * Creates a new instance.
	 */
	public NewConfigurationMainPage() {
		super(PAGE_NAME);
		setTitle(AuthoringUIResources.AuthoringUIPlugin_NewConfigurationMainPage_pageTitle); //$NON-NLS-1$);
		setDescription(AuthoringUIResources.AuthoringUIPlugin_NewConfigurationMainPage_pageDescription); //$NON-NLS-1$
		setImageDescriptor(AuthoringUIPlugin.getDefault().getImageDescriptor(
				"full/wizban/New.gif")); //$NON-NLS-1$		
	}

	/**
	 * @see org.eclipse.jface.dialogs.IDialogPage#createControl(Composite)
	 */
	public void createControl(Composite parent) {
		GridData labelGridData = new GridData(GridData.VERTICAL_ALIGN_BEGINNING);

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

		Label nameLabel = new Label(composite, SWT.NONE);
		nameLabel.setText(AuthoringUIText.NAME_TEXT);
		nameLabel.setLayoutData(labelGridData);

		nameText = new Text(composite, SWT.BORDER);
		nameText.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
		((GridData) nameText.getLayoutData()).horizontalSpan = 2;

		Label briefDescLabel = new Label(composite, SWT.NONE);
		briefDescLabel.setText(AuthoringUIText.DESCRIPTION_TEXT);
		briefDescLabel.setLayoutData(labelGridData);

		briefDescText = new Text(composite, SWT.BORDER | SWT.MULTI | SWT.WRAP
				| SWT.V_SCROLL);
		briefDescText.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
		((GridData) briefDescText.getLayoutData()).horizontalSpan = 2;
		((GridData) briefDescText.getLayoutData()).heightHint = 70;
		((GridData) briefDescText.getLayoutData()).widthHint = 480;

		initControls();

		addListeners();

		noOpenLibrary = LibraryService.getInstance().getCurrentMethodLibrary() == null;
		if (noOpenLibrary) {
			setErrorMessage(AuthoringUIResources.noOpenLibraryError_msg);
		}

		setControl(composite);
	}

	/**
	 * Initializes the wizard page controls with data.
	 */
	protected void initControls() {
	}

	/**
	 * Adds event handlers to the wizard page controls.
	 */
	protected void addListeners() {
		nameText.addModifyListener(new ModifyListener() {
			public void modifyText(ModifyEvent e) {
				setPageComplete(isPageComplete());
				getWizard().getContainer().updateButtons();
			}
		});
	}

	/**
	 * @see org.eclipse.jface.wizard.WizardPage#isPageComplete()
	 */
	public boolean isPageComplete() {
		if (noOpenLibrary) {
			return false;
		}

		String configName = getConfigurationName();
		if (configName.length() == 0) {
			return false;
		}

		if (configurationExists(configName)) {
			String errMsg = AuthoringUIResources.bind(
					AuthoringUIResources.duplicateElementNameError_msg,
					configName);
			setErrorMessage(errMsg);
		} else {
			setErrorMessage(null);
		}

		return getErrorMessage() == null;
	}

	/**
	 * Adds listeners to the wizard controls.
	 */
	private boolean configurationExists(String configName) {
		String[] configNames = LibraryServiceUtil
				.getMethodConfigurationNames(LibraryService.getInstance()
						.getCurrentMethodLibrary());
		for (int i = 0; i < configNames.length; i++) {
			if (configName.equalsIgnoreCase(configNames[i])) {
				return true;
			}
		}
		return false;
	}

	/**
	 * Returns the method configuration name.
	 * 
	 * @return the user specified name for the new method configuraiton
	 */
	public String getConfigurationName() {
		return nameText.getText().trim();
	}

	/**
	 * Returns the method configuration brief decription.
	 * 
	 * @return the user specified brief decription for the new method
	 *         configuraiton
	 */
	public String getConfigurationBriefDescription() {
		return briefDescText.getText().trim();
	}

}
