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

import java.io.File;

import org.eclipse.epf.authoring.ui.preferences.LibraryLocationData;
import org.eclipse.epf.export.ExportResources;
import org.eclipse.epf.ui.wizards.BaseWizardPage;
import org.eclipse.jface.wizard.Wizard;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Combo;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.DirectoryDialog;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Event;
import org.eclipse.swt.widgets.Listener;

/**
 * A wizard page that prompts the user to select a destination directory for an
 * export or import operation.
 * 
 * @author Bingxue Xu
 * @author Kelvin Low
 * @since 1.0
 * fix for https://bugs.eclipse.org/bugs/show_bug.cgi?id=157401
 */
public class DestinationCommonPage extends BaseWizardPage implements Listener {

	private static final String pageTitle = ExportResources.DestinationCommonPage_title; //$NON-NLS-1$

	private static final String pageDesc = ExportResources.DestinationCommonPage_desc; //$NON-NLS-1$

	protected Composite container;

	protected Combo ctrl_exportPath;

	protected Button ctrl_browse_button;

	protected LibraryLocationData llData;

	/**
	 * Creates a new instance.
	 */
	public DestinationCommonPage(String pageName, LibraryLocationData llData) {
		super(pageName);
		setTitle(pageTitle);
		setDescription(pageDesc);
		this.llData = llData;
	}

	/**
	 * @see org.eclipse.jface.dialogs.IDialogPage#createControl(org.eclipse.swt.widgets.Composite)
	 */
	public void createControl(Composite parent) {
		container = new Composite(parent, SWT.NONE);
		container.setLayout(new GridLayout(3, false));

		createLabel(container, ExportResources.DestinationCommonPage_label_dir); //$NON-NLS-1$
		ctrl_exportPath = super.createCombobox(container, 1); //$NON-NLS-1$
		ctrl_browse_button = new Button(container, SWT.NONE);
		ctrl_browse_button.setText(ExportResources.DestinationCommonPage_label_browse); //$NON-NLS-1$
		ctrl_browse_button.addSelectionListener(new SelectionAdapter() {
			public void widgetSelected(SelectionEvent e) {
				openDirectoryDialog();
			}
		});

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

		addListeners();

		setControl(container);

		initComboItems();
		
		setDefaultValue();
		
		setPageComplete(false);
	}
	
	protected void setDefaultValue(){
//		set last opened dir as the default selection when init this page
		addDefaultToItems();
		ctrl_exportPath.select(0);
		ctrl_exportPath.setEnabled(true);
		ctrl_browse_button.setEnabled(true);

	}
	
	protected void addDefaultToItems(){
		String[] items = ctrl_exportPath.getItems();
		int index=0;
		if(items!=null && items.length>0){
			for(int i=0; i<items.length; i++){
				if(items[i].equals(ExportUIPreferences.getDefaultExportPath()))
					return;
				index = i;
			}
			index++;
		}
		if(index>ExportUIPreferences.getListLength()-1){
			index = ExportUIPreferences.getListLength()-1;
			ctrl_exportPath.remove(index);
		}
		ctrl_exportPath.add(ExportUIPreferences.getDefaultExportPath(), index);
	}

	private void addListeners() {
		ctrl_exportPath.addListener(SWT.FocusIn, this);
		ctrl_exportPath.addListener(SWT.Modify, this);
		ctrl_exportPath.addListener(SWT.FocusOut, this);
		ctrl_exportPath.addListener(SWT.Selection, this);
	}

	/**
	 * @see org.eclipse.jface.dialogs.DialogPage#setVisible(boolean)
	 */
	public void setVisible(boolean visible) {
		super.setVisible(visible);
		if (visible) {
			Display display = container.getDisplay();
			if (!(display == null || display.isDisposed())) {
				display.asyncExec(new Runnable() {
					public void run() {
						ctrl_exportPath.setFocus();
					}
				});
			}
		}
	}

	/**
	 * @see org.eclipse.swt.widgets.Listener#handleEvent(org.eclipse.swt.widgets.Event)
	 */
	public void handleEvent(Event event) {
		Wizard wizard = (Wizard) getWizard();
		
		setPageComplete(isPageComplete());
		wizard.getContainer().updateButtons();

	}

	protected void saveToDataModel() {
		String libName = ctrl_exportPath.getText();
		if (libName.length() > 0) {
			if (!libName.endsWith(File.separator)){
				libName = libName.substring(libName.lastIndexOf(File.separator)+1, libName.length());
			}else
				libName = "";
		}
		llData.setLibName(libName);
		llData.setParentFolder(ctrl_exportPath.getText());
	}

	private void openDirectoryDialog() {
		try {
			DirectoryDialog dd = new DirectoryDialog(container.getShell(),
					SWT.NONE);
			dd.setFilterPath(ctrl_exportPath.getText());

			String destination = dd.open();
			if (destination != null) {
				ctrl_exportPath.setText(destination);
			}
		} catch (Exception ex) {
			ex.printStackTrace();
		}
	}
	
	/**
	 * use the opened dirs to init combo list
	 */
	protected void initComboItems(){
		return;
	}

}
