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

import java.util.List;

import org.eclipse.epf.authoring.ui.AuthoringUIHelpContexts;
import org.eclipse.epf.authoring.ui.AuthoringUIText;
import org.eclipse.epf.library.LibraryService;
import org.eclipse.epf.library.LibraryServiceUtil;
import org.eclipse.epf.library.ui.LibraryUIImages;
import org.eclipse.epf.publishing.services.PublishOptions;
import org.eclipse.epf.publishing.ui.PublishingUIResources;
import org.eclipse.epf.ui.wizards.BaseWizardPage;
import org.eclipse.epf.uma.MethodConfiguration;
import org.eclipse.jface.viewers.ArrayContentProvider;
import org.eclipse.jface.viewers.ISelectionChangedListener;
import org.eclipse.jface.viewers.ITableLabelProvider;
import org.eclipse.jface.viewers.LabelProvider;
import org.eclipse.jface.viewers.SelectionChangedEvent;
import org.eclipse.jface.viewers.StructuredSelection;
import org.eclipse.jface.viewers.TableViewer;
import org.eclipse.jface.wizard.IWizardPage;
import org.eclipse.jface.wizard.WizardPage;
import org.eclipse.swt.SWT;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Event;
import org.eclipse.swt.widgets.Listener;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.Table;
import org.eclipse.swt.widgets.TableItem;
import org.eclipse.swt.widgets.Text;
import org.eclipse.ui.PlatformUI;

/**
 * The Select Method Configuration page in the Publish Method Configuration
 * wizard.
 * 
 * @author Kelvin Low
 * @author Bingxue Xu
 * @author Jinhua Xi
 * @since 1.0
 */
public class PublishConfigSelectConfigPage extends BaseWizardPage implements
		ISelectionChangedListener, Listener {

	private Table table;

	private TableViewer tableViewer;

	private Text ctrl_briefDesc;

	private PublishOptions dataModel = null;

	private List vwList;

	/**
	 * Creates a new instance.
	 */
	public PublishConfigSelectConfigPage(String pageName,
			PublishOptions dataModel) {
		super(pageName);
		setTitle(PublishingUIResources.publishConfigWizard_selectConfigPage_title); //$NON-NLS-1$
		setDescription(PublishingUIResources.publishConfigWizard_selectConfigPage_text); //$NON-NLS-1$
		this.dataModel = dataModel;
	}

	/**
	 * @see org.eclipse.jface.dialogs.IDialogPage#createControl(Composite)
	 */
	public void createControl(Composite parent) {
		// Create the composite to hold the widgets.
		Composite composite = new Composite(parent, SWT.NULL);
		composite.setLayout(new GridLayout(1, false));

		createLabel(
				composite,
				PublishingUIResources.publishConfigWizard_methodConfig_text); //$NON-NLS-1$

		table = new Table(composite, SWT.BORDER | SWT.V_SCROLL);
		GridData gridData = new GridData(GridData.FILL_BOTH);
		gridData.heightHint = 120;
		gridData.widthHint = 280;
		table.setLayoutData(gridData);

		tableViewer = new TableViewer(table);
		tableViewer.setLabelProvider(new ConfigurationTableLabelProvider());
		tableViewer.setContentProvider(new ArrayContentProvider());
		MethodConfiguration[] configs = LibraryServiceUtil
				.getMethodConfigurations(LibraryService.getInstance()
						.getCurrentMethodLibrary());
		tableViewer.setInput(configs);

		createLabel(composite, AuthoringUIText.DESCRIPTION_TEXT);

		ctrl_briefDesc = createTextMulti(composite, "", 360, 80, 1); //$NON-NLS-1$

		// Select the first config and display its brief description.
		if (configs.length > 0) {
			table.select(0);
			setDisplayAttributes(configs[0]);
		}

		// TODO: Shouldn't this be the application shell image?
		PublishConfigurationWizard wizard = (PublishConfigurationWizard) getWizard();
		Shell shell = wizard.getContainer().getShell();
		shell.setImage(LibraryUIImages.IMG_METHOD_CONFIGURATON);

		tableViewer.addSelectionChangedListener(this);

		setControl(composite);

		PlatformUI
				.getWorkbench()
				.getHelpSystem()
				.setHelp(
						composite,
						AuthoringUIHelpContexts.CONFIGURATION_PUBLISH_WIZARD_ALL_PAGES_CONTEXT);
	}

	/**
	 * handle the selection change event
	 * @param event SelectionChangedEvent
	 */
	public void selectionChanged(SelectionChangedEvent event) {
		StructuredSelection selection = (StructuredSelection) event
				.getSelection();
		if (!selection.isEmpty()) {
			Object[] configs = selection.toArray();
			setDisplayAttributes((MethodConfiguration) configs[0]);
		}
		setPageComplete(isPageComplete());
		getWizard().getContainer().updateButtons();
	}

	/**
	 * handle the event
	 * @param event Event
	 */
	public void handleEvent(Event event) {
		setPageComplete(isPageComplete());
		getWizard().getContainer().updateButtons();
	}

	private void setDisplayAttributes(MethodConfiguration config) {
		ctrl_briefDesc.setText(config.getBriefDescription());
	}

	/**
	 * get the next wizard page
	 * 
	 * @return IWizardPage
	 */
	public IWizardPage getNextPage() {
		dataModel.publishConfiguration = true;
		// IWizardPage page = super.getNextPage();

		IWizardPage page = getWizard().getNextPage(this);
		return page;
	}

	/**
	 * check if the page is completed or not
	 * 
	 * @return boolean
	 */
	public boolean isPageComplete() {
		if (getErrorMessage() != null)
			return false;

		int count = table.getSelectionCount();

		if (count > 0) {
			TableItem[] items = table.getSelection();
			dataModel.setSelectedConfig(items[0].getText());
			MethodConfiguration config = LibraryServiceUtil
					.getMethodConfiguration(LibraryService.getInstance()
							.getCurrentMethodLibrary(),
							dataModel.selectedConfig);
			vwList = null;
			if (config != null) {
				vwList = config.getProcessViews();
			}

			if (vwList != null && vwList.size() > 0) {
				setErrorMessage(null);
				setMessage(null);
				return true;
			} else {
				setErrorMessage(null);
				setMessage(PublishingUIResources.missingViewError_msg, //$NON-NLS-1$
						WizardPage.WARNING);
				return false;
			}
		}

		return false;
	}

	class ConfigurationTableLabelProvider extends LabelProvider
			implements ITableLabelProvider {

		public Image getColumnImage(Object element, int index) {
			return null;
		}

		public String getColumnText(Object element, int index) {
			MethodConfiguration config = (MethodConfiguration) element;
			return config.getName();
		}
	}

}
