/*******************************************************************************
 * Copyright (c) 2006, 2008 Oracle. 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:
 *     Oracle - initial API and implementation
 ******************************************************************************/
package org.eclipse.jpt.ui.internal.wizards;

import java.util.Collection;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;

import org.eclipse.core.runtime.IStatus;
import org.eclipse.jdt.core.IJavaElement;
import org.eclipse.jdt.ui.wizards.NewTypeWizardPage;
import org.eclipse.jface.viewers.CheckboxTableViewer;
import org.eclipse.jface.viewers.ColumnWeightData;
import org.eclipse.jface.viewers.IBaseLabelProvider;
import org.eclipse.jface.viewers.ICellModifier;
import org.eclipse.jface.viewers.IContentProvider;
import org.eclipse.jface.viewers.ISelectionChangedListener;
import org.eclipse.jface.viewers.IStructuredContentProvider;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.jface.viewers.ITableLabelProvider;
import org.eclipse.jface.viewers.LabelProvider;
import org.eclipse.jface.viewers.SelectionChangedEvent;
import org.eclipse.jface.viewers.TextCellEditor;
import org.eclipse.jface.viewers.Viewer;
import org.eclipse.jface.viewers.ViewerSorter;
import org.eclipse.jpt.db.Table;
import org.eclipse.jpt.gen.internal.old.EntityGenTools;
import org.eclipse.jpt.gen.internal.old.EntityGenerator;
import org.eclipse.jpt.ui.internal.JpaHelpContextIds;
import org.eclipse.jpt.ui.internal.JptUiMessages;
import org.eclipse.jpt.ui.internal.util.SWTUtil;
import org.eclipse.jpt.ui.internal.util.TableLayoutComposite;
import org.eclipse.jpt.utility.internal.NameTools;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.KeyAdapter;
import org.eclipse.swt.events.KeyEvent;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.events.SelectionListener;
import org.eclipse.swt.graphics.Image;
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.Group;
import org.eclipse.swt.widgets.TableColumn;
import org.eclipse.swt.widgets.TableItem;
import org.eclipse.ui.PlatformUI;

// TODO add numerous settings to UI...
// TODO validate list of user-approved entity names:
//     no duplicates (case-sensitive)
//     valid Java identifiers @see NameTools.stringConsistsOfJavaIdentifierCharacters(String)
//     no Java reserved words @see NameTools.JAVA_RESERVED_WORDS_SET
class GenerateEntitiesWizardPage extends NewTypeWizardPage {

	CheckboxTableViewer tableTable;
	Button synchronizeClassesCheckBox;

	// TODO if this flag changes we need to re-calculate the entity names...
	// (at the moment, it does not change because it is not visible to the user...)
	private boolean convertToJavaStyleIdentifiers = true;
	private boolean fieldAccessType = true;
	private String collectionTypeName = Set.class.getName();
	private String collectionAttributeNameSuffix = "_collection"; //$NON-NLS-1$
	private int fieldVisibility = EntityGenerator.Config.PRIVATE;
	private int methodVisibility = EntityGenerator.Config.PUBLIC;
	private boolean generateGettersAndSetters = true;
	private boolean generateDefaultConstructor = true;
	private boolean serializable = true;
	private boolean generateSerialVersionUID = true;
	private boolean generateEmbeddedIdForCompoundPK = true;
	private String embeddedIdAttributeName = "pk";  //$NON-NLS-1$
	private String primaryKeyMemberClassName = "PK";  //$NON-NLS-1$

	// key = table; value = entity name
	private HashMap<Table, String> entityNames;
	
	private boolean synchronizePersistenceXml = false;

	static final String[] TABLE_TABLE_COLUMN_PROPERTIES = { "table", "entityName" }; //$NON-NLS-1$ //$NON-NLS-2$
	private static final int TABLE_COLUMN_INDEX = 0;
	private static final int ENTITY_NAME_COLUMN_INDEX = 1;
	

	GenerateEntitiesWizardPage() {
		super(true, "Generate Entities"); //$NON-NLS-1$
		setTitle(JptUiMessages.GenerateEntitiesWizardPage_generateEntities);
		setMessage(JptUiMessages.GenerateEntitiesWizardPage_chooseEntityTable);
	}
	
	// -------- Initialization ---------
	/**
	 * The wizard owning this page is responsible for calling this method with the
	 * current selection. The selection is used to initialize the fields of the wizard 
	 * page.
	 * 
	 * @param selection used to initialize the fields
	 */
	void init(IStructuredSelection selection) {
		IJavaElement jelem= getInitialJavaElement(selection);
		initContainerPage(jelem);
		initTypePage(jelem);
		doStatusUpdate();
	}

	public void createControl(Composite parent) {
		Composite composite = new Composite(parent, SWT.NULL);
		int nColumns= 4;
		GridLayout layout = new GridLayout();
		layout.numColumns = nColumns;
		composite.setLayout(layout);
		PlatformUI.getWorkbench().getHelpSystem().setHelp(composite, JpaHelpContextIds.DIALOG_GENERATE_ENTITIES);
		
		createContainerControls(composite, nColumns);	
		createPackageControls(composite, nColumns);	
		
		this.synchronizeClassesCheckBox = new Button(composite, SWT.CHECK);
		synchronizeClassesCheckBox.setText(JptUiMessages.GenerateEntitiesWizardPage_synchronizeClasses);
		synchronizeClassesCheckBox.addSelectionListener(this.buildSynchClassesSelectionListener());
		
		Group tablesGroup = new Group(composite, SWT.SHADOW_ETCHED_IN);
		tablesGroup.setLayout(new GridLayout(2, false));
		tablesGroup.setText(JptUiMessages.GenerateEntitiesWizardPage_tables);
		GridData data = new GridData();
		data.horizontalSpan = 4;
		data.verticalAlignment = SWT.FILL;
		data.horizontalAlignment = SWT.FILL;
		data.grabExcessHorizontalSpace = true;
		data.grabExcessVerticalSpace = true;
		tablesGroup.setLayoutData(data);
		
		createTablesSelectionControl(tablesGroup);
		createButtonComposite(tablesGroup);
		
		this.initTablesSelectionControl();
		
		//set initial selection state of the synchronize classes checkbox
		synchronizeClassesCheckBox.setSelection( ! this.getGenEntitiesWizard().getJpaProject().discoversAnnotatedClasses());
		setSynchronizePersistenceXml(synchronizeClassesCheckBox.getSelection());
		
		PlatformUI.getWorkbench().getHelpSystem().setHelp(this.tableTable.getControl(), JpaHelpContextIds.DIALOG_GENERATE_ENTITIES_TABLES);
		
		setControl(composite);
		this.setPageComplete(false);
	}

	private GenerateEntitiesWizard getGenEntitiesWizard() {
		return (GenerateEntitiesWizard) this.getWizard();
	}

	void selectAllTables(){
		this.tableTable.setAllChecked(true);
		doStatusUpdate();
	}
	
	void deselectAllTables(){
		this.tableTable.setAllChecked(false);
		doStatusUpdate();
	}
	
	private void initTablesSelectionControl() {
		this.setPossibleTables(this.getGenEntitiesWizard().getPossibleTables());
	}

	void setPossibleTables(Collection<Table> possibleTables) {
		if (this.tableTable == null) {
			return;  // the wizard has called this method before our widgets are built
		}
		this.entityNames = new HashMap<Table, String>(possibleTables.size());
		for (Table table : possibleTables) {
			String tableName = table.getName();
			String entityName = (this.convertToJavaStyleIdentifiers) ?
							EntityGenTools.convertToUniqueJavaStyleClassName(tableName, entityNames.values())
						:
							NameTools.uniqueNameFor(tableName, entityNames.values());
			this.entityNames.put(table, entityName);
		}
		this.tableTable.setInput(possibleTables);
	}

	private void createTablesSelectionControl(Composite parent) {
		TableLayoutComposite layout= new TableLayoutComposite(parent, SWT.NONE);
		addColumnLayoutData(layout);
		
		final org.eclipse.swt.widgets.Table table = new org.eclipse.swt.widgets.Table(layout, SWT.H_SCROLL | SWT.V_SCROLL | SWT.SINGLE | SWT.FULL_SELECTION | SWT.BORDER | SWT.CHECK);
		table.setHeaderVisible(true);
		table.setLinesVisible(true);
		
		TableColumn tableNameColumn = new TableColumn(table, SWT.NONE, TABLE_COLUMN_INDEX);
		tableNameColumn.setText(JptUiMessages.GenerateEntitiesWizardPage_tableColumn);
		tableNameColumn.setResizable(true);

		TableColumn entityNameColumn = new TableColumn(table, SWT.NONE, ENTITY_NAME_COLUMN_INDEX);
		entityNameColumn.setText(JptUiMessages.GenerateEntitiesWizardPage_entityNameColumn);
		entityNameColumn.setResizable(true);
		
		GridData gd= new GridData(GridData.FILL_BOTH);
		gd.heightHint= SWTUtil.getTableHeightHint(table, 20);
		gd.widthHint = 600;
		layout.setLayoutData(gd);

		this.tableTable = new CheckboxTableViewer(table);
		this.tableTable.setUseHashlookup(true);
		this.tableTable.setLabelProvider(this.buildTableTableLabelProvider());
		this.tableTable.setContentProvider(this.buildTableTableContentProvider());
		this.tableTable.setSorter(new ViewerSorter() {
			@Override
			public int compare(Viewer viewer, Object e1, Object e2) {
				return ((Table) e1).getName().compareTo(((Table) e2).getName());
			}
		});
		
		this.tableTable.addPostSelectionChangedListener(new ISelectionChangedListener() {
			public void selectionChanged(SelectionChangedEvent event) {
				handleTablesListSelectionChanged();
			}
		});
		
		table.addKeyListener(new KeyAdapter() {
			@Override
			public void keyPressed(KeyEvent e) {
				if (e.keyCode == SWT.F2 && e.stateMask == SWT.NONE) {
					editEntityNameIfPossible();
					e.doit= false;
				}
			}
		});
		
		this.addCellEditors();
	}
	
	private void createButtonComposite(Group tablesGroup){
		Composite buttonComposite = new Composite(tablesGroup, SWT.NULL);
		GridLayout buttonLayout = new GridLayout(1, false);
		buttonComposite.setLayout(buttonLayout);
		GridData data =  new GridData();
		data.horizontalAlignment = GridData.FILL;
		data.verticalAlignment = GridData.BEGINNING;
		buttonComposite.setLayoutData(data);
		
		Button selectAllButton = new Button(buttonComposite, SWT.PUSH);
		selectAllButton.setText(JptUiMessages.General_selectAll);
		GridData gridData =  new GridData();
		gridData.horizontalAlignment = GridData.FILL;
		selectAllButton.setLayoutData(gridData);
		selectAllButton.addSelectionListener(this.buildSelectAllButtonSelectionListener());
		
		Button deselectAllButton = new Button(buttonComposite, SWT.PUSH);
		deselectAllButton.setText(JptUiMessages.General_deselectAll);
		gridData =  new GridData();
		gridData.horizontalAlignment = GridData.FILL;
		deselectAllButton.setLayoutData(gridData);
		deselectAllButton.addSelectionListener(this.buildDeselectAllButtonSelectionListener());
	}
	
	
	private void addColumnLayoutData(TableLayoutComposite layout) {
		layout.addColumnData(new ColumnWeightData(50, true));
		layout.addColumnData(new ColumnWeightData(50, true));
	}

	void editEntityNameIfPossible(){
		Object[] selected = ((IStructuredSelection) this.tableTable.getSelection()).toArray();
		if (selected.length == 1) {
			this.tableTable.editElement(selected[0], ENTITY_NAME_COLUMN_INDEX);
		}
	}
	
	private void addCellEditors() {
		this.tableTable.setColumnProperties(TABLE_TABLE_COLUMN_PROPERTIES);
		
		TextCellEditor[] editors = new TextCellEditor[TABLE_TABLE_COLUMN_PROPERTIES.length];
		editors[ENTITY_NAME_COLUMN_INDEX]= new TextCellEditor(this.tableTable.getTable(), SWT.SINGLE);
		
		this.tableTable.setCellEditors(editors);
		this.tableTable.setCellModifier(this.buildTableTableCellModifier());
	}

	void handleTablesListSelectionChanged() {
		this.setPageComplete(true);
		if (this.noTablesAreSelected()) {
			this.setPageComplete(false);
		}
	}
	
	private IBaseLabelProvider buildTableTableLabelProvider() {
		return new TableTableLabelProvider();
	}
	
	private IContentProvider buildTableTableContentProvider() {
		return new TableTableContentProvider();
	}
	
	private ICellModifier buildTableTableCellModifier() {
		return new TableTableCellModifier();
	}
	
	Map<Table, String> getSelectedTables() {
		Object[] checkedElements = this.tableTable.getCheckedElements();
		HashMap<Table, String> selectedTables = new HashMap<Table, String>(checkedElements.length);
		for (Object checkedElement : checkedElements) {
			Table table = (Table) checkedElement;
			selectedTables.put(table, this.entityNames.get(table));
		}
		return selectedTables;
	}

	private boolean noTablesAreSelected() {
		return (this.tableTable == null) ? true : (this.tableTable.getCheckedElements().length == 0);
	}
	
	@Override
	protected void handleFieldChanged(String fieldName) {
		super.handleFieldChanged(fieldName);
		
		doStatusUpdate();
	}
	
	private void doStatusUpdate() {
		// status of all used components
		IStatus[] status= new IStatus[] {
			fContainerStatus,
			fPackageStatus
		};
		// the mode severe status will be displayed and the OK button enabled/disabled.
		this.updateStatus(status);
	}
	
	/**
	 * Update the status line and the OK button according to the given status
	 */
	@Override
	protected void updateStatus(IStatus status) {
		super.updateStatus(status);
		if (this.isPageComplete() && this.noTablesAreSelected()) {
			this.setPageComplete(false);
		}
	}

	String getEntityName(Table table) {
		return this.entityNames.get(table);
	}

	/**
	 * return whether the new entity name is different from the old entity name
	 */
	boolean setEntityName(Table table, String entityName) {
		String old = this.entityNames.put(table, entityName);
		return ! entityName.equals(old);
	}

	boolean convertToJavaStyleIdentifiers() {
		return this.convertToJavaStyleIdentifiers;
	}

	boolean fieldAccessType() {
		return this.fieldAccessType;
	}

	String getCollectionTypeName() {
		return this.collectionTypeName;
	}

	String getCollectionAttributeNameSuffix() {
		return this.collectionAttributeNameSuffix;
	}

	int getFieldVisibility() {
		return this.fieldVisibility;
	}

	int getMethodVisibility() {
		return this.methodVisibility;
	}

	boolean generateGettersAndSetters() {
		return this.generateGettersAndSetters;
	}

	boolean generateDefaultConstructor() {
		return this.generateDefaultConstructor;
	}

	boolean serializable() {
		return this.serializable;
	}

	boolean generateSerialVersionUID() {
		return this.generateSerialVersionUID;
	}

	boolean generateEmbeddedIdForCompoundPK() {
		return this.generateEmbeddedIdForCompoundPK;
	}

	boolean synchronizePersistenceXml() {
		return this.synchronizePersistenceXml;
	}
	
	void setSynchronizePersistenceXml(boolean synchronizePersistenceXml){
		this.synchronizePersistenceXml = synchronizePersistenceXml;
	}

	String getEmbeddedIdAttributeName() {
		return this.embeddedIdAttributeName;
	}

	String getPrimaryKeyMemberClassName() {
		return this.primaryKeyMemberClassName;
	}
	
	private SelectionListener buildSelectAllButtonSelectionListener() {
		return new SelectionListener() {
			public void widgetDefaultSelected(SelectionEvent event) {
				// nothing special for "default" (double-click?)
				this.widgetSelected(event);
			}
			public void widgetSelected(SelectionEvent event) {
				selectAllTables();
			}
		};
	}
	
	private SelectionListener buildDeselectAllButtonSelectionListener() {
		return new SelectionListener() {
			public void widgetDefaultSelected(SelectionEvent event) {
				// nothing special for "default" (double-click?)
				this.widgetSelected(event);
			}
			public void widgetSelected(SelectionEvent event) {
				deselectAllTables();
			}
		};
	}
	
	private SelectionListener buildSynchClassesSelectionListener() {
		return new SelectionListener() {
			public void widgetDefaultSelected(SelectionEvent event) {
				// nothing special for "default" (double-click?)
				this.widgetSelected(event);
			}
			public void widgetSelected(SelectionEvent event) {
				setSynchronizePersistenceXml(synchronizeClassesCheckBox.getSelection());
			}
		};
	}


	// ********** inner classes **********

	class TableTableLabelProvider extends LabelProvider implements ITableLabelProvider {

		TableTableLabelProvider() {
			super();
		}

		@Override
		public String getText(Object element) {
			return ((Table) element).getName();
		}

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

		public String getColumnText(Object element, int columnIndex) {
			if (element == null) {
				return null;
			}
			switch (columnIndex) {
				case TABLE_COLUMN_INDEX:
					return ((Table) element).getName();

				case ENTITY_NAME_COLUMN_INDEX:
					return GenerateEntitiesWizardPage.this.getEntityName((Table) element);
			}
			throw new IllegalArgumentException("invalid column index: " + columnIndex); //$NON-NLS-1$
		}

	}


	static class TableTableContentProvider implements IStructuredContentProvider {

		TableTableContentProvider() {
			super();
		}

		public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {
			// do nothing
		}
	
		public void dispose() {
			// do nothing
		}
	
		public Object[] getElements(Object inputElement) {
			return ((Collection<?>) inputElement).toArray();
		}

	}


	class TableTableCellModifier implements ICellModifier {

		TableTableCellModifier() {
			super();
		}

		public boolean canModify(Object element, String property) {
			return property.equals(TABLE_TABLE_COLUMN_PROPERTIES[ENTITY_NAME_COLUMN_INDEX]);
		}

		public Object getValue(Object element, String property) {
			if (property.equals(TABLE_TABLE_COLUMN_PROPERTIES[ENTITY_NAME_COLUMN_INDEX])) {
				return GenerateEntitiesWizardPage.this.getEntityName((Table) element);
			}
			return null;
		}

		public void modify(Object element, String property, Object value) {
			if (element instanceof TableItem) {
				element= ((TableItem) element).getData();
			}
			if ( ! (element instanceof Table)) {
				return;
			}
			Table table = (Table) element;

			boolean changed = true;
			if (property.equals(TABLE_TABLE_COLUMN_PROPERTIES[ENTITY_NAME_COLUMN_INDEX])) {
				changed = GenerateEntitiesWizardPage.this.setEntityName(table, (String) value);
			}
			if (changed) {
				GenerateEntitiesWizardPage.this.tableTable.update(table, new String[] { property });
			}
		}

	}

}
