/*******************************************************************************
 * 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.EntityGenTools;
import org.eclipse.jpt.gen.internal.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 });
			}
		}

	}

}
