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

import java.io.File;
import java.util.List;

import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status;
import org.eclipse.epf.export.wizards.DestinationCommonPage;
import org.eclipse.epf.importing.ImportPlugin;
import org.eclipse.epf.importing.ImportResources;
import org.eclipse.epf.importing.services.PluginImportData;
import org.eclipse.epf.importing.services.PluginImportingService;
import org.eclipse.epf.library.LibraryService;
import org.eclipse.epf.library.ui.LibraryUIResources;
import org.eclipse.jface.wizard.IWizardPage;

/**
 * A wizard page that prompts the user to select a directory that contains the
 * method plug-ins to import.
 * 
 * @author Jeff Hardy
 * @author Kelvin Low
 * @since 1.0
 */
public class SelectImportPluginSource extends DestinationCommonPage {

	public static final String PAGE_NAME = SelectImportPluginSource.class
			.getName();

	private static final Status OK_STATUS = new Status(
			IStatus.OK,
			ImportResources.SelectImportPluginSource_not_used, 0, "", null); //$NON-NLS-1$ //$NON-NLS-2$

	private PluginImportData data;

	private PluginImportingService service;

	private Status status = OK_STATUS;

	/**
	 * Creates a new instance.
	 */
	public SelectImportPluginSource(PluginImportData data,
			PluginImportingService service) {
		super(PAGE_NAME, data.llData);
		setTitle(ImportResources.selectPluginsDirWizardPage_title); //$NON-NLS-1$
		setDescription(ImportResources.selectPluginsDirWizardPage_text); //$NON-NLS-1$
		setImageDescriptor(ImportPlugin.getDefault().getImageDescriptor(
				"full/wizban/ImportMethodPlugins.gif")); //$NON-NLS-1$
		this.service = service;
		this.data = data;
	}
	
	/* (non-Javadoc)
	 * @see org.eclipse.epf.export.wizards.DestinationCommonPage#initComboItems()
	 */
	protected void initComboItems() {
		List dirList = ImportUIPreferences.getLastImportPluginPaths();
		
		if(dirList!=null && !dirList.isEmpty()){
			String[] dirs = new String[dirList.size()];
			for(int i=0; i<dirList.size(); i++){
				dirs[i] = dirList.get(i).toString();
			}
			ctrl_exportPath.setItems(dirs);
		}
	}
	
	/**
	 * @see org.eclipse.jface.wizard.WizardPage#isCompleted()
	 */
	public boolean isPageComplete() {
		if (LibraryService.getInstance().getCurrentMethodLibrary() == null) {
			setErrorMessage(LibraryUIResources.noOpenLibraryWarning_msg);
			return false;
		}
		boolean returnValue = false;
		status = OK_STATUS;
		if (ctrl_exportPath.getText().length()>0) {
			saveToDataModel();
			File libDir = new File(ctrl_exportPath.getText());
			if (!libDir.exists()) {
				status = new Status(
						IStatus.ERROR,
						ImportResources.SelectImportPluginSource_not_used, 0, ImportResources.SelectImportPluginSource_no_path, null); 
			} else {
				returnValue = true;
			}
		}
		applyToStatusLine();
		return returnValue;
	}

	/**
	 * @see org.eclipse.jface.wizard.WizardPage#getNextPage()
	 */
	public IWizardPage getNextPage() {
		saveToDataModel();

		// Validate first before going to the next page.
		service.validate(null);
		String error = data.getErrorInfo().getError();
		if (error != null && error.length() > 0) {
			super.setErrorMessage(error);
			return this;
		} else {
			SelectPluginsToImport page = ((ImportPluginWizard) getWizard()).page2;
			page.onEnterPage(null);
			return page;
		}
	}

	/**
	 * @see org.eclipse.jface.wizard.WizardPage#canFlipToNextPage()
	 */
	public boolean canFlipToNextPage() {
		return isPageComplete();
	}

	private void applyToStatusLine() {
		if (status != OK_STATUS)
			setErrorMessage(status.getMessage());
		else {
			setErrorMessage(null);
		}
	}

}
