/*******************************************************************************
 * Copyright (c) 2003, 2005 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 API and implementation
 *******************************************************************************/
/*
 * Created on Dec 8, 2003
 * 
 * To change the template for this generated file go to Window>Preferences>Java>Code Generation>Code and Comments
 */
package org.eclipse.jst.j2ee.internal.wizard;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Iterator;
import java.util.List;

import org.eclipse.jface.viewers.CellEditor;
import org.eclipse.jface.viewers.CheckStateChangedEvent;
import org.eclipse.jface.viewers.CheckboxTableViewer;
import org.eclipse.jface.viewers.ColumnWeightData;
import org.eclipse.jface.viewers.ICellModifier;
import org.eclipse.jface.viewers.ICheckStateListener;
import org.eclipse.jface.viewers.TableLayout;
import org.eclipse.jface.viewers.TextCellEditor;
import org.eclipse.jst.j2ee.application.internal.operations.EARComponentImportDataModelProvider;
import org.eclipse.jst.j2ee.datamodel.properties.IEARComponentImportDataModelProperties;
import org.eclipse.jst.j2ee.datamodel.properties.IJ2EEComponentImportDataModelProperties;
import org.eclipse.jst.j2ee.internal.actions.IJ2EEUIContextIds;
import org.eclipse.jst.j2ee.internal.plugin.J2EEUIMessages;
import org.eclipse.jst.j2ee.internal.plugin.J2EEUIPlugin;
import org.eclipse.jst.j2ee.internal.plugin.J2EEUIPluginIcons;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
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.Table;
import org.eclipse.swt.widgets.TableColumn;
import org.eclipse.swt.widgets.TableItem;
import org.eclipse.wst.common.componentcore.resources.IVirtualComponent;
import org.eclipse.wst.common.frameworks.datamodel.DataModelEvent;
import org.eclipse.wst.common.frameworks.datamodel.IDataModel;
import org.eclipse.wst.common.frameworks.internal.datamodel.ui.DataModelWizardPage;

/**
 * @author cbridgha
 * 
 * To change the template for this generated type comment go to Window>Preferences>Java>Code
 * Generation>Code and Comments
 */
public class EARComponentProjectsPage extends DataModelWizardPage {

	private CheckboxTableViewer earFileListViewer;

	public static final String INCLUDE_COLUMN = J2EEUIMessages.getResourceString("EARImportProjectsPage_UI_0"); //$NON-NLS-1$
	public static final String FILE_COLUMN = J2EEUIMessages.getResourceString("EARImportProjectsPage_UI_1"); //$NON-NLS-1$
	public static final String PROJECT_COLUMN = J2EEUIMessages.getResourceString("EARImportProjectsPage_UI_2"); //$NON-NLS-1$

	/**
	 * @param model
	 * @param pageName
	 */
	public EARComponentProjectsPage(IDataModel model, String pageName) {
		super(model, pageName);
		setTitle(J2EEUIMessages.getResourceString(J2EEUIMessages.EAR_IMPORT_PROJECT_PG_TITLE));
		setDescription(J2EEUIMessages.getResourceString(J2EEUIMessages.EAR_IMPORT_PROJECT_PG_DESC));
		setImageDescriptor(J2EEUIPlugin.getDefault().getImageDescriptor(J2EEUIPluginIcons.EAR_IMPORT_WIZARD_BANNER));
	}

	protected Composite createTopLevelComposite(Composite parent) {
		Composite composite = new Composite(parent, SWT.NONE);
		setInfopopID(IJ2EEUIContextIds.IMPORT_EAR_WIZARD_P3);
		GridLayout layout = new GridLayout();
		composite.setLayout(layout);
		composite.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
		createListGroup(composite);
		createButtonsGroup(composite);

		return composite;
	}

	protected void setColumnEditors() {
		Table t = earFileListViewer.getTable();
		CellEditor[] columnEditors = new CellEditor[t.getColumnCount()];
		columnEditors[1] = new TextCellEditor(t);

		earFileListViewer.setCellEditors(columnEditors);
	}

	protected void createButtonsGroup(Composite parent) {
		Composite buttonGroup = new Composite(parent, SWT.NONE);
		GridLayout layout = new GridLayout();
		layout.numColumns = 3;
		buttonGroup.setLayout(layout);
		buttonGroup.setLayoutData(new GridData(GridData.FILL_BOTH));

		Button selectNotInWorkspace = new Button(buttonGroup, SWT.PUSH);
		selectNotInWorkspace.setText(J2EEUIMessages.getResourceString("EARImportProjectsPage_UI_3")); //$NON-NLS-1$
		GridData gd = new GridData(GridData.HORIZONTAL_ALIGN_FILL | GridData.VERTICAL_ALIGN_FILL);
		//gd.horizontalSpan = 1;
		//gd.heightHint = 22;
		gd.widthHint = 140;
		selectNotInWorkspace.setLayoutData(gd);
		selectNotInWorkspace.addSelectionListener(new SelectionAdapter() {
			public void widgetSelected(SelectionEvent e) {
				List list = (List) model.getProperty(IEARComponentImportDataModelProperties.ALL_PROJECT_MODELS_LIST);
				List selectedList = (List) model.getProperty(IEARComponentImportDataModelProperties.SELECTED_MODELS_LIST);
				List newList = new ArrayList();
				newList.addAll(selectedList);
				IDataModel importDM = null;
				for (int i = 0; i < list.size(); i++) {
					importDM = (IDataModel) list.get(i);
					if (!newList.contains(importDM) && !((IVirtualComponent) importDM.getProperty(IJ2EEComponentImportDataModelProperties.COMPONENT)).exists()) {
						newList.add(importDM);
					}
				}
				model.setProperty(IEARComponentImportDataModelProperties.SELECTED_MODELS_LIST, newList);
			}
		});

		Button selectAllButton = new Button(buttonGroup, SWT.PUSH);
		selectAllButton.setText(J2EEUIMessages.getResourceString(J2EEUIMessages.EAR_IMPORT_SELECT_ALL_UTIL_BUTTON));
		gd = new GridData(GridData.HORIZONTAL_ALIGN_FILL | GridData.VERTICAL_ALIGN_FILL);
		//gd.horizontalSpan = 1;
		//gd.heightHint = 22;
		gd.widthHint = 140;
		selectAllButton.setLayoutData(gd);
		selectAllButton.addSelectionListener(new SelectionAdapter() {
			public void widgetSelected(SelectionEvent e) {
				List list = (List) model.getProperty(IEARComponentImportDataModelProperties.ALL_PROJECT_MODELS_LIST);
				List newList = new ArrayList();
				newList.addAll(list);
				model.setProperty(IEARComponentImportDataModelProperties.SELECTED_MODELS_LIST, newList);
			}
		});

		Button deselectAllButton = new Button(buttonGroup, SWT.PUSH);
		deselectAllButton.setText(J2EEUIMessages.getResourceString(J2EEUIMessages.EAR_IMPORT_DESELECT_ALL_UTIL_BUTTON));
		gd = new GridData(GridData.HORIZONTAL_ALIGN_FILL | GridData.VERTICAL_ALIGN_FILL);
		////gd.horizontalSpan = 1;
		//gd.heightHint = 22;
		gd.widthHint = 140;
		deselectAllButton.setLayoutData(gd);
		deselectAllButton.addSelectionListener(new SelectionAdapter() {
			public void widgetSelected(SelectionEvent e) {
				List newList = new ArrayList();
				model.setProperty(IEARComponentImportDataModelProperties.SELECTED_MODELS_LIST, newList);
			}
		});
	}

	public void propertyChanged(DataModelEvent event) {
		if (event.getPropertyName().equals(IEARComponentImportDataModelProperties.SELECTED_MODELS_LIST)) {
			if(earFileListViewer != null){
				updateGUICheckSelection();
			}
		}
		super.propertyChanged(event);
	}

	public void setFileListViewerInput() {
		TableObjects files = new TableObjects();
		Iterator iterator = ((List) model.getProperty(IEARComponentImportDataModelProperties.ALL_PROJECT_MODELS_LIST)).iterator();
		while (iterator.hasNext()) {
			files.tableObjectsList.add(iterator.next());
		}
		earFileListViewer.setInput(files);
		updateGUICheckSelection();
	}

	private void updateGUICheckSelection() {
		List selectedList = (List) model.getProperty(IEARComponentImportDataModelProperties.SELECTED_MODELS_LIST);
		List projectList = (List) model.getProperty(IEARComponentImportDataModelProperties.ALL_PROJECT_MODELS_LIST);
		Object currentElement = null;
		for (int i = 0; i < projectList.size(); i++) {
			currentElement = projectList.get(i);
			earFileListViewer.setChecked(currentElement, selectedList.contains(currentElement));
		}
	}

	/**
	 * @see org.eclipse.jst.j2ee.internal.internal.internal.wizard.J2EEWizardPage#enter()
	 */
	protected void enter() {
		super.enter();
		setFileListViewerInput();
		validatePage();
	}

	/**
	 * Creates the import source specification widgets. <b>Subclasses </b> must override this hook
	 * method.
	 * 
	 * @param parent
	 *            a <code>Composite</code> that is to be used as the parent of this group's
	 *            collection of visual components
	 * @see org.eclipse.swt.widgets.Composite
	 */
	protected void createListGroup(org.eclipse.swt.widgets.Composite parent) {
		Composite listGroup = new Composite(parent, SWT.NONE);
		GridLayout layout = new GridLayout();
		layout.numColumns = 1;
		listGroup.setLayout(layout);
		GridData gd = new GridData(GridData.FILL_BOTH);
		listGroup.setLayoutData(gd);

		earFileListViewer = CheckboxTableViewer.newCheckList(listGroup, SWT.BORDER | SWT.H_SCROLL | SWT.V_SCROLL | SWT.FULL_SELECTION);
		EARImportListContentProvider provider = new EARImportListContentProvider();
		earFileListViewer.setContentProvider(provider);
		earFileListViewer.setLabelProvider(provider);
		earFileListViewer.addCheckStateListener(new ICheckStateListener() {
			public void checkStateChanged(CheckStateChangedEvent event) {
				IDataModel matchingModel = null;// getEARImportDataModel().getMatchingEJBJarOrClient(aModel);
				if (null != matchingModel) {
					earFileListViewer.setChecked(matchingModel, event.getChecked());
				}
				List result = new ArrayList();
				result.addAll(Arrays.asList(earFileListViewer.getCheckedElements()));
				model.setProperty(IEARComponentImportDataModelProperties.SELECTED_MODELS_LIST, result);

			}
		});

		Table earFileListTable = (Table) earFileListViewer.getControl();
		earFileListTable.setHeaderVisible(true);
		earFileListTable.setLinesVisible(true);
		// set up table layout
		TableLayout tableLayout = new org.eclipse.jface.viewers.TableLayout();
		tableLayout.addColumnData(new ColumnWeightData(100, true));
		tableLayout.addColumnData(new ColumnWeightData(200, true));
		earFileListTable.setLayout(tableLayout);

		gd = new GridData(GridData.FILL_BOTH | GridData.GRAB_HORIZONTAL | GridData.GRAB_VERTICAL);
		gd.widthHint = 400;
		earFileListTable.setLayoutData(gd);


		TableColumn fileNameColumns = new TableColumn(earFileListTable, SWT.NONE);
		fileNameColumns.setText(J2EEUIMessages.getResourceString(J2EEUIMessages.EAR_IMPORT_Modules_in_EAR)); //$NON-NLS-1$ = "Modules in EAR"
		fileNameColumns.setResizable(true);

		TableColumn importNameColumn = new TableColumn(earFileListTable, SWT.NONE);
		importNameColumn.setText(J2EEUIMessages.getResourceString(J2EEUIMessages.EAR_IMPORT_New_Project_Name)); //$NON-NLS-1$ = "New Project Name"
		importNameColumn.setResizable(true);

		String[] columnProperties = new String[2];
		columnProperties[0] = FILE_COLUMN;
		columnProperties[1] = PROJECT_COLUMN;
		earFileListViewer.setColumnProperties(columnProperties);

		setColumnEditors();
		earFileListViewer.setCellModifier(new ICellModifier() {
			public boolean canModify(Object element, String property) {
				return PROJECT_COLUMN.equals(property);
			}

			public Object getValue(Object element, String property) {
				TableItem[] items = earFileListViewer.getTable().getSelection();
				TableItem item = items[0];
				return item.getText(1);
			}

			public void modify(Object element, String property, Object value) {
				TableItem elementHolder = (TableItem) element;
				if (property.equals(PROJECT_COLUMN)) {
					elementHolder.setText(1, (String) value);
					((IDataModel) elementHolder.getData()).setProperty(IJ2EEComponentImportDataModelProperties.PROJECT_NAME, value);
				}
			}
		});
	}


	protected void restoreWidgetValues() {
		// This page doesn't implement...
	}

	public void storeDefaultSettings() {
		// This page doesn't implement...
	}

	protected String[] getValidationPropertyNames() {
		return new String[]{IEARComponentImportDataModelProperties.SELECTED_MODELS_LIST, EARComponentImportDataModelProvider.NESTED_PROJECTS_VALIDATION};
	}


}
