//------------------------------------------------------------------------------
// 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.library.ui.dialogs;

import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.Path;
import org.eclipse.epf.common.utils.StrUtil;
import org.eclipse.epf.library.ui.LibraryUIPlugin;
import org.eclipse.epf.library.ui.LibraryUIResources;
import org.eclipse.epf.library.ui.preferences.LibraryUIPreferences;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.DisposeEvent;
import org.eclipse.swt.events.DisposeListener;
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.graphics.Image;
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.Control;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Event;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Listener;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.Text;


/**
 * Prompts the user to select a Method Library folder.
 * 
 * @author Kelvin Low
 * @author 1.0
 */
public class OpenLibraryDialog extends BaseDialog implements Listener {

	private Image titleImage;

	private Text libraryPathText;

	private String libraryPath;

	private Button promptForLibraryCheckbox;

	/**
	 * Creates a new instance.
	 * 
	 * @param parent
	 *            The parent control.
	 * @param libraryPath
	 *            Path to a Method Library.
	 */
	public OpenLibraryDialog(Shell parent, String libraryPath) {
		super(parent);
		this.libraryPath = libraryPath;
	}

	/**
	 * @see org.eclipse.epf.library.ui.dialogs.BaseDialog#createDialogArea(Composite)
	 */
	protected Control createDialogArea(Composite parent) {
		final Composite dialogArea = (Composite) super.createDialogArea(parent);

		setTitle(LibraryUIResources
				.getString("LibraryUI.openLibraryDialogArea.title")); //$NON-NLS-1$
		setMessage(LibraryUIResources
				.getString("LibraryUI.openLibraryDialogArea.text")); //$NON-NLS-1$
		titleImage = LibraryUIPlugin.getDefault().getImage("OpenLibrary.gif"); //$NON-NLS-1$
		setTitleImage(titleImage);

		Composite inputComposite = new Composite(dialogArea, SWT.NONE);
		inputComposite.setLayout(new GridLayout(3, false));

		createLabel(inputComposite, " ", 3); //$NON-NLS-1$

		Label libraryLabel = new Label(inputComposite, SWT.NONE);
		libraryLabel.setText(LibraryUIResources
				.getString("LibraryUI.libraryLabel.text")); //$NON-NLS-1$

		libraryPathText = new Text(inputComposite, SWT.BORDER);
		GridData gridData = new GridData(GridData.FILL_HORIZONTAL);
		gridData.widthHint = 450;
		libraryPathText.setLayoutData(gridData);

		libraryPathText.setText(libraryPath);
		libraryPathText.addModifyListener(new ModifyListener() {
			 public void modifyText(ModifyEvent e) {
				 if (okButton != null) {
					 String status = isValidPath(libraryPathText.getText());
					 if (status == null) {
						setErrorMessage(null);
						okButton.setEnabled(true);
					 } else {
						setErrorMessage(status);
					 	okButton.setEnabled(false);
					 }
				 }
			  }
		 });

		Button browseButton = new Button(inputComposite, SWT.NONE);
		browseButton.setText(LibraryUIResources
				.getString("LibraryUI.browseButton.text")); //$NON-NLS-1$
		browseButton.addSelectionListener(new SelectionAdapter() {
			public void widgetSelected(SelectionEvent event) {
				try {
					SelectLibraryDirectoryDialog dd = new SelectLibraryDirectoryDialog(
							Display.getCurrent().getActiveShell());
					dd.setFilterPath(libraryPathText.getText());
					String path = dd.open();
					if (path != null) {
						libraryPathText.setText(path);
					}
				} catch (Exception e) {
					// TODO: Display an error dialog.
					e.printStackTrace();
				}
			}
		});

		createLabel(inputComposite, " ", 3); //$NON-NLS-1$
		createLabel(inputComposite, " ", 3); //$NON-NLS-1$
		createLabel(inputComposite, " ", 3); //$NON-NLS-1$
		new Label(inputComposite, SWT.CHECK);

		promptForLibraryCheckbox = new Button(inputComposite, SWT.CHECK);
		promptForLibraryCheckbox.setText(LibraryUIResources
				.getString("LibraryUI.promptForLibraryCheckbox.text")); //$NON-NLS-1$

		super.getShell().setText(
				LibraryUIResources
						.getString("LibraryUI.openLibraryDialog.title")); //$NON-NLS-1$
		super.getShell().addDisposeListener(new DisposeListener() {
			public void widgetDisposed(DisposeEvent event) {
				if (titleImage != null && !titleImage.isDisposed()) {
					titleImage.dispose();
				}
			}
		});

		return dialogArea;
	}

	public int open() {
		setShellStyle(getShellStyle() | SWT.APPLICATION_MODAL);
		return super.open();
	}

	public void handleEvent(Event event) {
		if (event.widget == promptForLibraryCheckbox) {
			LibraryUIPreferences
					.setPromptForMethodLibraryAtStartup(promptForLibraryCheckbox
							.getSelection());
		}
	}

	private Label createLabel(Composite parent, String text, int span) {
		Label label = new Label(parent, SWT.LEFT);
		label.setText(text);
		GridData data = new GridData();
		data.horizontalSpan = span;
		data.horizontalAlignment = GridData.FILL;
		label.setLayoutData(data);
		return label;
	}
	
	private String isValidPath(String path) {
	   	if (path == null || path.trim().length() == 0) {
    		return LibraryUIResources.getString("LibraryUI.DirectoryValidator.invalid_path"); //$NON-NLS-1$  		
    	}
		
    	IPath ecPath = Path.fromOSString(path);
    	boolean isValid = ecPath.isValidPath(path);
    	if (!isValid) {
    		return LibraryUIResources.getString("LibraryUI.DirectoryValidator.invalid_path"); //$NON-NLS-1$
    	} else {
    		if (!StrUtil.isValidPublishPath(path))
    			return LibraryUIResources.getString("LibraryUI.DirectoryValidator.invalid_path"); //$NON-NLS-1$
    		else
    			return null;
    	}
	}

	/**
	 * @see org.eclipse.epf.library.ui.dialogs.BaseDialog#createButtonsForButtonBar(Composite
	 *      parent)
	 */
	protected void createButtonsForButtonBar(Composite parent) {
		super.createButtonsForButtonBar(parent);
		okButton.setEnabled(true);
	}

	/**
	 * Called when the OK button is selected.
	 */
	protected void okPressed() {
		libraryPath = libraryPathText.getText().trim();
		LibraryUIPreferences
				.setPromptForMethodLibraryAtStartup(!promptForLibraryCheckbox
						.getSelection());
		super.okPressed();
	}

	/**
	 * Called when the Cancel button is selected.
	 * 
	 * TODO: This will shutdown the Eclipse IDE.
	 */
	protected void cancelPressed() {
		System.exit(0);
	}

	/**
	 * Returns the selected Method Library path.
	 */
	public String getLibraryPath() {
		return libraryPath;
	}

}
