/*******************************************************************************
 * Copyright (c) 2003, 2004 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.jem.util.emf.workbench.JavaProjectUtilities;
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.EnterpriseApplicationImportDataModel;
import org.eclipse.jst.j2ee.application.internal.operations.J2EEArtifactImportDataModel;
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.frameworks.internal.operations.WTPOperationDataModelEvent;

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

	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 EARImportProjectsPage(J2EEArtifactImportDataModel 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));
		EARImportOptionsPage.createNestedProjectOverwriteCheckbox(synchHelper, composite);
		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 = 4;
		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);
		gd.horizontalSpan = 1;
		gd.heightHint = 22;
		gd.widthHint = 120;
		selectNotInWorkspace.setLayoutData(gd);
		selectNotInWorkspace.addSelectionListener(new SelectionAdapter() {
			public void widgetSelected(SelectionEvent e) {
				List list = getEARImportDataModel().getProjectModels();
				List selectedList = getEARImportDataModel().getSelectedModels();
				List newList = new ArrayList();
				newList.addAll(selectedList);
				J2EEArtifactImportDataModel importDM = null;
				for (int i = 0; i < list.size(); i++) {
					importDM = (J2EEArtifactImportDataModel) list.get(i);
					if (!newList.contains(importDM) && !importDM.getProject().exists()) {
						newList.add(importDM);
					}
				}
				getEARImportDataModel().setProperty(EnterpriseApplicationImportDataModel.SELECTED_MODELS_LIST, newList);
			}
		});

		Button selectBinary = new Button(buttonGroup, SWT.PUSH);
		selectBinary.setText(J2EEUIMessages.getResourceString("EARImportProjectsPage_UI_4")); //$NON-NLS-1$
		gd = new GridData(GridData.HORIZONTAL_ALIGN_FILL);
		gd.horizontalSpan = 1;
		gd.heightHint = 22;
		gd.widthHint = 120;
		selectBinary.setLayoutData(gd);
		selectBinary.addSelectionListener(new SelectionAdapter() {
			public void widgetSelected(SelectionEvent e) {
				List list = getEARImportDataModel().getProjectModels();
				List selectedList = getEARImportDataModel().getSelectedModels();
				List newList = new ArrayList();
				newList.addAll(selectedList);
				J2EEArtifactImportDataModel importDM = null;
				for (int i = 0; i < list.size(); i++) {
					importDM = (J2EEArtifactImportDataModel) list.get(i);
					if (!newList.contains(importDM) && JavaProjectUtilities.isBinaryProject(importDM.getProject())) {
						newList.add(importDM);
					}
				}
				getEARImportDataModel().setProperty(EnterpriseApplicationImportDataModel.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);
		gd.horizontalSpan = 1;
		gd.heightHint = 22;
		gd.widthHint = 120;
		selectAllButton.setLayoutData(gd);
		selectAllButton.addSelectionListener(new SelectionAdapter() {
			public void widgetSelected(SelectionEvent e) {
				List list = getEARImportDataModel().getProjectModels();
				List newList = new ArrayList();
				newList.addAll(list);
				getEARImportDataModel().setProperty(EnterpriseApplicationImportDataModel.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);
		gd.horizontalSpan = 1;
		gd.heightHint = 22;
		gd.widthHint = 120;
		deselectAllButton.setLayoutData(gd);
		deselectAllButton.addSelectionListener(new SelectionAdapter() {
			public void widgetSelected(SelectionEvent e) {
				List newList = new ArrayList();
				getEARImportDataModel().setProperty(EnterpriseApplicationImportDataModel.SELECTED_MODELS_LIST, newList);
			}
		});
	}

	public void propertyChanged(WTPOperationDataModelEvent event) {
		if (event.getPropertyName().equals(EnterpriseApplicationImportDataModel.SELECTED_MODELS_LIST)) {
			updateGUICheckSelection();
		}
		super.propertyChanged(event);
	}

	public void setFileListViewerInput() {
		TableObjects files = new TableObjects();
		Iterator iterator = getEARImportDataModel().getProjectModels().iterator();
		while (iterator.hasNext()) {
			files.tableObjectsList.add(iterator.next());
		}
		earFileListViewer.setInput(files);
		updateGUICheckSelection();
	}

	private void updateGUICheckSelection() {
		List selectedList = getEARImportDataModel().getSelectedModels();
		List projectList = getEARImportDataModel().getProjectModels();
		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 | GridData.GRAB_HORIZONTAL);
		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) {
				J2EEArtifactImportDataModel aModel = (J2EEArtifactImportDataModel) event.getElement();
				J2EEArtifactImportDataModel matchingModel = getEARImportDataModel().getMatchingEJBJarOrClient(aModel);
				if (null != matchingModel) {
					earFileListViewer.setChecked(matchingModel, event.getChecked());
				}
				List result = new ArrayList();
				result.addAll(Arrays.asList(earFileListViewer.getCheckedElements()));
				getEARImportDataModel().setProperty(EnterpriseApplicationImportDataModel.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(this);
	}

	private EnterpriseApplicationImportDataModel getEARImportDataModel() {
		return (EnterpriseApplicationImportDataModel) model;
	}

	public boolean canModify(Object element, String property) {
		return !getEARImportDataModel().getBooleanProperty(J2EEArtifactImportDataModel.PRESERVE_PROJECT_METADATA);
	}

	public java.lang.Object getValue(java.lang.Object element, java.lang.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);
			((J2EEArtifactImportDataModel) elementHolder.getData()).setProperty(J2EEArtifactImportDataModel.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[]{EnterpriseApplicationImportDataModel.NESTED_PROJECTS_VALIDATION, EnterpriseApplicationImportDataModel.OVERWRITE_NESTED_PROJECTS, EnterpriseApplicationImportDataModel.SELECTED_MODELS_LIST};
	}
}