//------------------------------------------------------------------------------
// 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.preferences;

import java.util.regex.Matcher;
import java.util.regex.Pattern;

import org.eclipse.epf.authoring.ui.AuthoringUIResources;
import org.eclipse.epf.authoring.ui.AuthoringUIText;
import org.eclipse.epf.common.utils.FileUtil;
import org.eclipse.epf.library.LibraryPlugin;
import org.eclipse.epf.library.prefs.LibraryPreferenceConstants;
import org.eclipse.epf.library.ui.preferences.LibraryUIPreferences;
import org.eclipse.jface.preference.IPreferenceStore;
import org.eclipse.jface.preference.PreferencePage;
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.events.SelectionListener;
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.DirectoryDialog;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Text;
import org.eclipse.ui.IWorkbench;
import org.eclipse.ui.IWorkbenchPreferencePage;


/**
 * Library options preference page
 * 
 * @author BingXue Xu
 * @since 1.0
 */
public class LibraryPrefPage extends PreferencePage implements
		IWorkbenchPreferencePage, SelectionListener, ModifyListener {

	Composite composite_tab;

	Text ctrl_libParentPath;

	Button ctrl_browseButton;

	String defLibPPath = "/"; //$NON-NLS-1$

	private Button bakCheckbox;

	private Button discardUnresolvedRefCheckBox;
	
	Text ctrl_defaultListLength;
	
	private final String DEFAULT_LIST_LENGTH = "10";

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.jface.preference.PreferencePage#createContents(org.eclipse.swt.widgets.Composite)
	 */
	protected Control createContents(Composite parent) {

		// composite_tab << parent
		composite_tab = createComposite(parent, 3);

		// createLabel(composite_tab, "Choose a library save option:");
		//
		// radio button composite << tab composite
		// Composite composite_radioButton = createComposite(composite_tab, 1);
		// radioButton1 = createRadioButton(composite_radioButton, "Save as
		// multiple folders");
		// radioButton2 = createRadioButton(composite_radioButton, "Save as a
		// single file");

		createLabel(composite_tab, " ", 3); //$NON-NLS-1$
		createLabel(composite_tab, AuthoringUIResources.chooseDefaultDirectory_text, 3); 

		// Directory Path
		createLabel(composite_tab, AuthoringUIResources.directory_text, 1); 

		ctrl_libParentPath = new Text(composite_tab, SWT.BORDER);
		{
			GridData gridData = new GridData(GridData.BEGINNING
					| GridData.FILL_HORIZONTAL | GridData.GRAB_HORIZONTAL);
			gridData.widthHint = 400;
			ctrl_libParentPath.setLayoutData(gridData);
		}

		ctrl_libParentPath.setText(defLibPPath);

		ctrl_browseButton = new Button(composite_tab, SWT.NONE);
		ctrl_browseButton.setText(AuthoringUIText.BROWSE_BUTTON_TEXT);
		{
			GridData gridData = new GridData(GridData.END
					| GridData.GRAB_HORIZONTAL);
			ctrl_browseButton.setLayoutData(gridData);
		}

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

		createLine(composite_tab, 3);
		createLabel(composite_tab, " ", 3); //$NON-NLS-1$
		// backup before save check box
		//
		createLabel(composite_tab, " ", 1); //$NON-NLS-1$
		bakCheckbox = new Button(composite_tab, SWT.CHECK);
		bakCheckbox.setText(AuthoringUIResources.backupbeforesave_text); 
		createLabel(composite_tab, " ", 1); //$NON-NLS-1$

		// 'discard unresolved references' check box
		createLabel(composite_tab, " ", 1); //$NON-NLS-1$
		discardUnresolvedRefCheckBox = new Button(composite_tab, SWT.CHECK);
		discardUnresolvedRefCheckBox.setText(AuthoringUIResources.discardunresolvedref); 
		createLabel(composite_tab, " ", 1); //$NON-NLS-1$

		createLabel(composite_tab, " ", 3); //$NON-NLS-1$
		createLine(composite_tab, 3);
		
		Composite composite_tab_size = createComposite(composite_tab, 3);
		{
			GridData gridData = new GridData(GridData.BEGINNING
					| GridData.FILL_HORIZONTAL | GridData.GRAB_HORIZONTAL);
			gridData.horizontalSpan=3;
			composite_tab_size.setLayoutData(gridData);
		}
		createLabel(composite_tab_size, AuthoringUIResources.default_list_length_label, 1); 
		ctrl_defaultListLength = new Text(composite_tab_size, SWT.BORDER);
		{
			GridData gridData = new GridData(GridData.BEGINNING
					| GridData.FILL_HORIZONTAL | GridData.GRAB_HORIZONTAL);
			gridData.horizontalSpan=2;
			ctrl_defaultListLength.setLayoutData(gridData);
		}
		createLine(composite_tab, 3);

		initializeValues();

		ctrl_browseButton.addSelectionListener(new SelectionAdapter() {
			public void widgetSelected(SelectionEvent e) {
				openDirectoryDialog();
			}
		});

		// font = null;
		return new Composite(parent, SWT.NULL);
	}

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

			String destination = dd.open();
			if (destination != null) {
				ctrl_libParentPath.setText(destination);
			}

		} catch (Exception ex) {
			ex.printStackTrace();
		}
	}

	private Composite createComposite(Composite parent, int numColumns) {

		Composite composite = new Composite(parent, SWT.NULL);

		// GridLayout
		GridLayout layout = new GridLayout();
		layout.numColumns = numColumns;
		composite.setLayout(layout);

		// GridData
		GridData data = new GridData();
		data.verticalAlignment = GridData.FILL;
		data.horizontalAlignment = GridData.FILL;
		composite.setLayoutData(data);

		return composite;
	}

	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 Button createRadioButton(Composite parent, String label) {
	// Button button = new Button(parent, SWT.RADIO | SWT.LEFT);
	// button.setText(label);
	// button.addSelectionListener(this);
	// GridData data = new GridData();
	// button.setLayoutData(data);
	// return button;
	// }

	private void createLine(Composite parent, int ncol) {
		Label line = new Label(parent, SWT.SEPARATOR | SWT.HORIZONTAL
				| SWT.BOLD);
		GridData gridData = new GridData(GridData.FILL_HORIZONTAL);
		gridData.horizontalSpan = ncol;
		line.setLayoutData(gridData);
	}

	/*
	 * (non-Javadoc)
	 * @see org.eclipse.jface.preference.PreferencePage#doGetPreferenceStore()
	 */
	protected IPreferenceStore doGetPreferenceStore() {

		return LibraryPlugin.getDefault().getPreferenceStore();
		// return PlatformUI.getWorkbench().getPreferenceStore();

	}

	/**
	 * Initializes states of the controls using default values in the preference
	 * store.
	 */
	private void initializeDefaults() {
		IPreferenceStore store = getPreferenceStore();

		defLibPPath = store
				.getDefaultString(LibraryPreferenceConstants.PREF_DEFAULT_LIBRARY_PARENT_DIRECTORY);
		if (defLibPPath == null || defLibPPath.length() == 0)
			defLibPPath = System.getProperty("user.home") + //$NON-NLS-1$
//					FileUtil.FILE_SEP + LibraryUIManager.getAppName() + //$NON-NLS-1$
					FileUtil.FILE_SEP + LibraryUIPreferences.getApplicationShortName() + 
					FileUtil.FILE_SEP + "Method Libraries"; //$NON-NLS-1$
		// System.out.println("DEBUG: default defLibPPath = " +
		// defLibPPath);
		ctrl_libParentPath.setText(defLibPPath);

		// radioButton1.setSelection(false);
		// radioButton2.setSelection(false);
		// int choice =
		// store.getDefaultInt(LibaryPreferenceConstants.PRE_RADIO_SAVE_CHOICE);
		// switch (choice) {
		// case 1:
		// radioButton1.setSelection(true);
		// break;
		// case 2:
		// radioButton2.setSelection(true);
		// break;
		// default:
		// radioButton1.setSelection(true);
		// break;
		// }

		bakCheckbox
				.setSelection(store
						.getDefaultBoolean(LibraryPreferenceConstants.PREF_BACK_UP_BEFORE_SAVE));
		discardUnresolvedRefCheckBox
				.setSelection(store
						.getDefaultBoolean(LibraryPreferenceConstants.PREF_DISCARD_UNRESOLVED_REFERENCES));
		
		String listLength = store
		.getString(LibraryPreferenceConstants.PREF_DEFAULT_HISTORY_SIZE);
		if(listLength==null || listLength.length()<=0)
			listLength = DEFAULT_LIST_LENGTH;
		
		ctrl_defaultListLength.setText(listLength);
	}
	
	private boolean isDigitStr(String str){
	     Pattern pattern = Pattern.compile("[0-9]+"); 
	     Matcher matcher = pattern.matcher((CharSequence)str); 
	     return matcher.matches(); 

	}

	/**
	 * Initializes states of the controls from the preference store.
	 */
	private void initializeValues() {
		IPreferenceStore store = getPreferenceStore();
		defLibPPath = store
				.getString(LibraryPreferenceConstants.PREF_DEFAULT_LIBRARY_PARENT_DIRECTORY);
		if (defLibPPath == null || defLibPPath.length() == 0)
			defLibPPath = System.getProperty("user.home") + //$NON-NLS-1$
//					FileUtil.FILE_SEP + LibraryUIManager.getAppName() + //$NON-NLS-1$
					FileUtil.FILE_SEP + LibraryUIPreferences.getApplicationShortName() + 
					FileUtil.FILE_SEP + "Method Libraries"; //$NON-NLS-1$ 
		// System.out.println("DEBUG: read defLibPPath = " + defLibPPath);
		ctrl_libParentPath.setText(defLibPPath);

		// int choice =
		// store.getInt(LibaryPreferenceConstants.PRE_RADIO_SAVE_CHOICE);
		// switch (choice) {
		// case 1:
		// radioButton1.setSelection(true);
		// break;
		// case 2:
		// radioButton2.setSelection(true);
		// break;
		// default:
		// radioButton1.setSelection(true);
		// break;
		// }

		bakCheckbox
				.setSelection(store
						.getBoolean(LibraryPreferenceConstants.PREF_BACK_UP_BEFORE_SAVE));
		discardUnresolvedRefCheckBox
				.setSelection(store
						.getBoolean(LibraryPreferenceConstants.PREF_DISCARD_UNRESOLVED_REFERENCES));
		
		String listLength = store
		.getString(LibraryPreferenceConstants.PREF_DEFAULT_HISTORY_SIZE);
		if(listLength==null || listLength.length()<=0)
			listLength = DEFAULT_LIST_LENGTH;
		ctrl_defaultListLength.setText(listLength);
	}

	/*
	 * (non-Javadoc) Method declared on PreferencePage
	 */
	protected void performDefaults() {
		super.performDefaults();
		initializeDefaults();
	}

	/*
	 * (non-Javadoc) Method declared on PreferencePage
	 */
	public boolean performOk() {
		storeValues();
		LibraryPlugin.getDefault().savePluginPreferences();
		return true;
	}

	/**
	 * Stores the values of the controls back to the preference store.
	 */
	private void storeValues() {
		IPreferenceStore store = getPreferenceStore();

		defLibPPath = ctrl_libParentPath.getText().trim();
		System.out.println("DEBUG: defLibPPath = " + defLibPPath); //$NON-NLS-1$
		store
				.setValue(
						LibraryPreferenceConstants.PREF_DEFAULT_LIBRARY_PARENT_DIRECTORY,
						defLibPPath);
		// int choice = 1;
		// if (radioButton2.getSelection())
		// choice = 2;
		//
		// store.setValue(LibaryPreferenceConstants.PRE_RADIO_SAVE_CHOICE,
		// choice);

		store.setValue(LibraryPreferenceConstants.PREF_BACK_UP_BEFORE_SAVE,
				bakCheckbox.getSelection());
		store.setValue(
				LibraryPreferenceConstants.PREF_DISCARD_UNRESOLVED_REFERENCES,
				discardUnresolvedRefCheckBox.getSelection());
		
		String listLength = ctrl_defaultListLength.getText();
		if(!isDigitStr(listLength))
			listLength = DEFAULT_LIST_LENGTH;
		else{
			if(Integer.parseInt(listLength)<=0)
				listLength = DEFAULT_LIST_LENGTH;
		}
		store.setValue(
				LibraryPreferenceConstants.PREF_DEFAULT_HISTORY_SIZE, listLength);
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.ui.IWorkbenchPreferencePage#init(org.eclipse.ui.IWorkbench)
	 */
	public void init(IWorkbench workbench) {
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.swt.events.SelectionListener#widgetSelected(org.eclipse.swt.events.SelectionEvent)
	 */
	public void widgetSelected(SelectionEvent e) {
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.swt.events.SelectionListener#widgetDefaultSelected(org.eclipse.swt.events.SelectionEvent)
	 */
	public void widgetDefaultSelected(SelectionEvent e) {
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.swt.events.ModifyListener#modifyText(org.eclipse.swt.events.ModifyEvent)
	 */
	public void modifyText(ModifyEvent e) {
	}

}
