//------------------------------------------------------------------------------
// 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.core.runtime.Platform;
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.osgi.util.NLS;
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
 * 
 * fix for https://bugs.eclipse.org/bugs/show_bug.cgi?id=154638
 */
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.openLibraryMainWizardPage_title);
		String appName = Platform.getProduct().getName();
		String openLibDtext = NLS.bind(LibraryUIResources.openLibraryMainWizardPage_text,
				new Object[] { appName});
		setMessage(openLibDtext);
		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.libraryLabel_text);

		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.browseButton_text);
		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.promptForLibraryCheckbox_text);

		super.getShell().setText(LibraryUIResources.openLibraryWizard_title);

		super.getShell().addDisposeListener(new DisposeListener() {
			public void widgetDisposed(DisposeEvent event) {
				if (titleImage != null && !titleImage.isDisposed()) {
					titleImage.dispose();
				}
			}
		});

		return dialogArea;
	}

	/** 
	 * @see org.eclipse.jface.window.Window#open()
	 */
	public int open() {
		setShellStyle(getShellStyle() | SWT.APPLICATION_MODAL);
		return super.open();
	}

	/**
	 * @see org.eclipse.swt.widgets.Listener#handleEvent(org.eclipse.swt.widgets.Event)
	 */
	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.invalidPath_msg;
		}

		IPath ecPath = Path.fromOSString(path);
		boolean isValid = ecPath.isValidPath(path);
		if (!isValid) {
			return LibraryUIResources.invalidPath_msg;
		} else {
			if (!StrUtil.isValidPublishPath(path))
				return LibraryUIResources.invalidPath_msg;
			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;
	}

}
