//------------------------------------------------------------------------------
// Copyright (c) 2005, 2006 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 java.io.File;

import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Path;
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.authoring.ui.preferences.LibraryLocationData;
import org.eclipse.epf.library.xmi.XMILibraryUtil;
import org.eclipse.jface.wizard.WizardPage;
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.DirectoryDialog;
import org.eclipse.swt.widgets.Event;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Listener;
import org.eclipse.swt.widgets.Text;


/**
 * A wizard page that prompts the user to enter a name, description and
 * destination directory for a new Method Library.
 * 
 * @author Bingxue Xu
 * @author Kelvin Low
 * @since 1.0
 */
public class NewLibraryMainPage extends WizardPage implements Listener {

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

	protected LibraryLocationData llData;

	private Composite composite;

	private Text nameText;

	private Text briefDescText;

	private Text pathText;

	private Button browseButton;

	private Button defaultPathCheckbox;

	private Text ctrlInEditing;

	private String parentDir;

	/**
	 * Creates a new instance.
	 */
	public NewLibraryMainPage(LibraryLocationData llData) {
		super(PAGE_NAME);
		setTitle(AuthoringUIResources.AuthoringUIPlugin_NewLibraryMainPage_pageTitle); //$NON-NLS-1$
		setDescription(AuthoringUIResources.AuthoringUIPlugin_NewLibraryMainPage_pageDescription); //$NON-NLS-1$
		setImageDescriptor(AuthoringUIPlugin.getDefault().getImageDescriptor(
				"full/wizban/New.gif")); //$NON-NLS-1$			
		this.llData = llData;
	}

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

		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;

		Label pathLabel = new Label(composite, SWT.NONE);
		pathLabel
				.setText(AuthoringUIResources.AuthoringUIPlugin_AbstractNewLibraryPage_DirectoryLabel); //$NON-NLS-1$
		pathText = new Text(composite, SWT.BORDER);
		pathText.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
		browseButton = new Button(composite, SWT.NONE);
		browseButton.setText(AuthoringUIText.BROWSE_BUTTON_TEXT);
		browseButton.addSelectionListener(new SelectionAdapter() {
			public void widgetSelected(SelectionEvent e) {
				openDirectoryDialog();
			}
		});

		new Label(composite, SWT.NONE);
		defaultPathCheckbox = new Button(composite, SWT.CHECK);
		defaultPathCheckbox
				.setText(AuthoringUIResources.AuthoringUIPlugin_AbstractNewLibraryPage_UseDefaultDirectoryButtonLabel); //$NON-NLS-1$

		initDataFromDTO();

		addListeners();

		// Set the composite as the control for this page.
		setControl(composite);
	}

	private void addListeners() {
		nameText.addListener(SWT.Modify, this);
		nameText.addListener(SWT.FocusIn, this);
		nameText.addListener(SWT.FocusOut, this);
		briefDescText.addListener(SWT.Modify, this);
		briefDescText.addListener(SWT.FocusOut, this);
		pathText.addListener(SWT.FocusIn, this);
		pathText.addListener(SWT.Modify, this);
		pathText.addListener(SWT.FocusOut, this);
		defaultPathCheckbox.addListener(SWT.Selection, this);
	}

	/**
	 * @see org.eclipse.swt.widgets.Listener#handleEvent(Event)
	 */
	public void handleEvent(Event event) {
		setPageComplete(isPageComplete());

		// Remember the Method Library path.
		if (event.widget == nameText && event.type == SWT.FocusIn) {
			parentDir = pathText.getText();
			String currentName = nameText.getText();
			if (currentName.length() > 0
					&& parentDir.endsWith(File.separator + currentName)) {
				int idx = parentDir.lastIndexOf(File.separator + currentName);
				parentDir = parentDir.substring(0, idx);
			}
			if (!parentDir.endsWith(File.separator))
				parentDir += File.separator;

			ctrlInEditing = nameText;
		}

		// Whenever the name changes, update the library path accordingly.
		if (event.widget == nameText && ctrlInEditing == nameText) {
			pathText.setText(parentDir
					+ nameText.getText());
			setPathValidMessage();
		}

		if (event.widget == nameText && event.type == SWT.FocusOut) {
			ctrlInEditing = null;
		}

		if (event.widget == pathText && event.type == SWT.FocusIn) {
			ctrlInEditing = pathText;
		}

		if (event.widget == pathText && ctrlInEditing == pathText) {
			String parentLibPath = pathText.getText();
			int idx = parentLibPath.lastIndexOf(File.separator);
			String libName = parentLibPath
					.substring((idx >= 0) ? (idx + 1) : 0);
			nameText.setText((libName != null) ? libName : ""); //$NON-NLS-1$
			
			// for UNC path, don't validate for every chenge because it's two slow, 
			// only when lose focus
			// RATLC00386147 - There is massive slowdown in application response when user create a new library in UNC format.
			if (event.type == SWT.FocusOut || !parentLibPath.startsWith("\\") ) { //$NON-NLS-1$
				setPathValidMessage();
			} else {
				setErrorMessage(null);
			}
		}

		if (event.widget == pathText && event.type == SWT.FocusOut) {
			ctrlInEditing = null;
		}

		if (event.widget == defaultPathCheckbox) {
			if (!defaultPathCheckbox.getSelection()) {
				pathText.setText(llData.getParentFolder());
				pathText.setEditable(true);
				browseButton.setEnabled(true);
			} else {
				pathText.setText(llData.getDefaultLibDir());
				pathText.setEditable(false);
				browseButton.setEnabled(false);
			}
			appendLibraryNemeToPath();
		}

		NewLibraryWizard wizard = (NewLibraryWizard) getWizard();
		wizard.okToComplete = isPageComplete();

		getWizard().getContainer().updateButtons();

	}

	private void setPathValidMessage() {
		IStatus status = XMILibraryUtil.isValidLibrary(pathText.getText());
		if (status.isOK()) {
			setErrorMessage(null);
		} else {
			setErrorMessage(status.getMessage());
		}
	}
	private void appendLibraryNemeToPath() {
		String libName = nameText.getText().trim();
		String libPath = pathText.getText().trim();
		if (libName.length() > 0) {
			if (!libPath.endsWith(File.separator))
				libPath += File.separator;
			pathText.setText(libPath + libName);
		}
	}

	public static boolean isTextNonEmpty(Text t) {
		String s = t.getText();
		if ((s != null) && (s.trim().length() > 0))
			return true;
		return false;
	}

	private void initDataFromDTO() {
		nameText
				.setText(AuthoringUIResources.AuthoringUIPlugin_AbstractNewLibraryPage_DefaultLibraryName); //$NON-NLS-1$
		nameText.setSelection(0, nameText.getText().length());
		briefDescText
				.setText(AuthoringUIResources.AuthoringUIPlugin_AbstractNewLibraryPage_DefaultLibraryDescription); //$NON-NLS-1$
		pathText.setText(llData.getParentFolder());

		boolean checked = llData.isDefLibDirChecked();
		if (checked) {
			pathText.setText(llData.getDefaultLibDir());
			pathText.setEditable(false);
			browseButton.setEnabled(false);
		}
		defaultPathCheckbox.setSelection(checked);
	}

	private void openDirectoryDialog() {
		try {
			DirectoryDialog dd = new DirectoryDialog(composite.getShell(),
					SWT.NONE);

			String destination = dd.open();
			if (destination != null) {
				pathText.setText(destination);
				appendLibraryNemeToPath();
			}
		} catch (Exception ex) {
			ex.printStackTrace();
		}
	}

	public void saveData() {
		llData.setOkPressed(true);
		llData.setLibName(nameText.getText().trim());
		llData.setLibBriefDescription(briefDescText.getText().trim());
		Path libPath = new Path(pathText.getText());
		llData.setParentFolder(libPath.removeLastSegments(1).addTrailingSeparator() + nameText.getText().trim());
		llData.setDefLibDirChecked(defaultPathCheckbox.getSelection());
	}

	/**
	 * @see org.eclipse.jface.wizard.WizardPage.isCompleted()
	 */
	public boolean isPageComplete() {
		if (isTextNonEmpty(nameText) && isTextNonEmpty(pathText)
				&& getErrorMessage() == null) {
			return true;
		}
		return false;
	}

}
