/*******************************************************************************
 * Copyright (c) 2008, 2009 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.jpa.ui.internal.details;

import java.util.ArrayList;
import java.util.ListIterator;
import org.eclipse.jpt.common.ui.internal.JptCommonUiMessages;
import org.eclipse.jpt.common.ui.internal.util.SWTUtil;
import org.eclipse.jpt.common.ui.internal.widgets.DialogPane;
import org.eclipse.jpt.common.utility.internal.StringConverter;
import org.eclipse.jpt.common.utility.internal.model.value.CompositeListValueModel;
import org.eclipse.jpt.common.utility.internal.model.value.ListAspectAdapter;
import org.eclipse.jpt.common.utility.internal.model.value.PropertyAspectAdapter;
import org.eclipse.jpt.common.utility.internal.model.value.PropertyListValueModelAdapter;
import org.eclipse.jpt.common.utility.internal.model.value.TransformationPropertyValueModel;
import org.eclipse.jpt.common.utility.model.value.ListValueModel;
import org.eclipse.jpt.common.utility.model.value.PropertyValueModel;
import org.eclipse.jpt.common.utility.model.value.WritablePropertyValueModel;
import org.eclipse.jpt.jpa.ui.internal.JpaHelpContextIds;
import org.eclipse.osgi.util.NLS;
import org.eclipse.swt.widgets.Combo;
import org.eclipse.swt.widgets.Composite;

/**
 * Here the layout of this pane:
 * <pre>
 * -----------------------------------------------------------------------------
 * |                         ------------------------------------------------- |
 * | Name:                   | I                                           |v| |
 * |                         ------------------------------------------------- |
 * |                         ------------------------------------------------- |
 * | Referenced Column Name: | I                                           |v| |
 * |                         ------------------------------------------------- |
 * |                         ------------------------------------------------- |
 * | Table:                  | I                                           |v| |
 * |                         ------------------------------------------------- |
 * |                         ------------------------------------------------- |
 * | Column Definition:      | I                                             | |
 * |                         ------------------------------------------------- |
 * -----------------------------------------------------------------------------</pre>
 *
 * @see BaseJoinColumnStateObject
 * @see InverseJoinColumnInJoinTableDialog - A container of this pane
 * @see JoinColumnInReferenceTableDialog - A container of this pane
 * @see PrimaryKeyJoinColumnDialog - A container of this pane
 * @see PrimaryKeyJoinColumnInSecondaryTableDialog - A container of this pane
 *
 * @version 2.0
 * @since 2.0
 */
@SuppressWarnings("nls")
public class BaseJoinColumnDialogPane<T extends BaseJoinColumnStateObject> extends DialogPane<T>
{
	/**
	 * A key used to represent the default value, this is required to convert
	 * the selected item from a combo to <code>null</code>. This key is most
	 * likely never typed the user and it will help to convert the value to
	 * <code>null</code> when it's time to set the new selected value into the
	 * model.
	 */
	protected static String DEFAULT_KEY = "?!#!?#?#?default?#?!#?!#?";

	/**
	 * Creates a new <code>BaseJoinColumnDialogPane</code>.
	 *
	 * @param subjectHolder The holder of this pane's subject
	 * @param parent The parent container
	 */
	public BaseJoinColumnDialogPane(PropertyValueModel<? extends T> subjectHolder,
	                                Composite parent) {

		super(subjectHolder, parent);
	}

	private WritablePropertyValueModel<String> buildColumnDefinitionHolder() {
		return new PropertyAspectAdapter<BaseJoinColumnStateObject, String>(getSubjectHolder(), BaseJoinColumnStateObject.COLUMN_DEFINITION_PROPERTY) {
			@Override
			protected String buildValue_() {
				return subject.getColumnDefinition();
			}

			@Override
			protected void setValue_(String value) {
				if (value.length() == 0) {
					value = null;
				}
				subject.setColumnDefinition(value);
			}
		};
	}

	/*
	 * (non-Javadoc)
	 */
	@Override
	protected Composite addContainer(Composite parent) {
		return addSubPane(parent, 0, 7, 0, 5);
	}

	private PropertyValueModel<String> buildDefaultNameHolder() {
		return new TransformationPropertyValueModel<BaseJoinColumnStateObject, String>(getSubjectHolder()) {
			@Override
			protected String transform_(BaseJoinColumnStateObject value) {
				String name = value.getDefaultName();

				if (name == null) {
					name = DEFAULT_KEY;
				}
				else {
					name = DEFAULT_KEY + name;
				}

				return name;
			}
		};
	}

	private ListValueModel<String> buildDefaultNameListHolder() {
		return new PropertyListValueModelAdapter<String>(
			buildDefaultNameHolder()
		);
	}

	private PropertyValueModel<String> buildDefaultReferencedColumnNameHolder() {
		return new TransformationPropertyValueModel<BaseJoinColumnStateObject, String>(getSubjectHolder()) {
			@Override
			protected String transform_(BaseJoinColumnStateObject value) {
				String name = value.getDefaultReferencedColumnName();

				if (name == null) {
					name = DEFAULT_KEY;
				}
				else {
					name = DEFAULT_KEY + name;
				}

				return name;
			}
		};
	}

	private ListValueModel<String> buildDefaultReferencedColumnNameListHolder() {
		return new PropertyListValueModelAdapter<String>(
			buildDefaultReferencedColumnNameHolder()
		);
	}

	private PropertyValueModel<String> buildDefaultTableHolder() {
		return new TransformationPropertyValueModel<BaseJoinColumnStateObject, String>(getSubjectHolder()) {
			@Override
			protected String transform_(BaseJoinColumnStateObject value) {
				String name = value.getDefaultTable();

				if (name == null) {
					name = DEFAULT_KEY;
				}
				else {
					name = DEFAULT_KEY + name;
				}

				return name;
			}
		};
	}

	private ListValueModel<String> buildDefaultTableListHolder() {
		return new PropertyListValueModelAdapter<String>(
			buildDefaultTableHolder()
		);
	}

	private StringConverter<String> buildDisplayableStringConverter(final DefaultValueHandler handler) {
		return new StringConverter<String>() {
			public String convertToString(String value) {

				if (getSubject() == null) {
					return null;
				}

				if (value == null) {
					value = handler.getDefaultValue();

					if (value != null) {
						value = DEFAULT_KEY + value;
					}
					else {
						value = DEFAULT_KEY;
					}
				}

				if (value.startsWith(DEFAULT_KEY)) {
					String defaultName = value.substring(DEFAULT_KEY.length());

					if (defaultName.length() > 0) {
						value = NLS.bind(
							JptCommonUiMessages.DefaultWithOneParam,
							defaultName
						);
					}
					else {
						value = JptCommonUiMessages.DefaultEmpty;
					}
				}

				return value;
			}
		};
	}

	private WritablePropertyValueModel<String> buildNameHolder() {
		return new PropertyAspectAdapter<BaseJoinColumnStateObject, String>(getSubjectHolder(), BaseJoinColumnStateObject.NAME_PROPERTY) {
			@Override
			protected String buildValue_() {
				return subject.getName();
			}

			@Override
			protected void setValue_(String value) {

				// Convert the default value or an empty string to null
				if ((value != null) &&
				   ((value.length() == 0) || value.startsWith(DEFAULT_KEY))) {

					value = null;
				}

				subject.setName(value);
			}
		};
	}

	private ListValueModel<String> buildNameListHolder() {
		return new ListAspectAdapter<BaseJoinColumnStateObject, String>(getSubjectHolder(), BaseJoinColumnStateObject.NAMES_LIST) {
			@Override
			protected ListIterator<String> listIterator_() {
				return subject.names();
			}
			@Override
			protected int size_() {
				return subject.columnsSize();
			}
		};
	}

	private ListValueModel<String> buildNamesListHolder() {
		ArrayList<ListValueModel<String>> holders = new ArrayList<ListValueModel<String>>(2);
		holders.add(buildDefaultNameListHolder());
		holders.add(buildNameListHolder());
		return new CompositeListValueModel<ListValueModel<String>, String>(holders);
	}

	private StringConverter<String> buildNameStringConverter() {
		return buildDisplayableStringConverter(new DefaultValueHandler() {
			public String getDefaultValue() {
				return getSubject().getDefaultName();
			}
		});
	}

	private WritablePropertyValueModel<String> buildReferencedColumnNameHolder() {
		return new PropertyAspectAdapter<BaseJoinColumnStateObject, String>(getSubjectHolder(), BaseJoinColumnStateObject.REFERENCED_COLUMN_NAME_PROPERTY) {
			@Override
			protected String buildValue_() {
				return subject.getReferencedColumnName();
			}

			@Override
			protected void setValue_(String value) {

				// Convert the default value or an empty string to null
				if ((value != null) &&
				   ((value.length() == 0) || value.startsWith(DEFAULT_KEY))) {

					value = null;
				}

				subject.setReferencedColumnName(value);
			}
		};
	}

	private ListValueModel<String> buildReferencedColumnNameListHolder() {
		return new ListAspectAdapter<BaseJoinColumnStateObject, String>(getSubjectHolder(), BaseJoinColumnStateObject.REFERENCE_COLUMN_NAMES_LIST) {
			@Override
			protected ListIterator<String> listIterator_() {
				return subject.referenceColumnNames();
			}
			@Override
			protected int size_() {
				return subject.referenceColumnsSize();
			}
		};
	}

	private ListValueModel<String> buildReferencedColumnNamesListHolder() {
		ArrayList<ListValueModel<String>> holders = new ArrayList<ListValueModel<String>>(2);
		holders.add(buildDefaultReferencedColumnNameListHolder());
		holders.add(buildReferencedColumnNameListHolder());
		return new CompositeListValueModel<ListValueModel<String>, String>(holders);
	}

	private StringConverter<String> buildReferencedColumnNameStringConverter() {
		return buildDisplayableStringConverter(new DefaultValueHandler() {
			public String getDefaultValue() {
				return getSubject().getDefaultReferencedColumnName();
			}
		});
	}

	private WritablePropertyValueModel<String> buildTableHolder() {
		return new PropertyAspectAdapter<BaseJoinColumnStateObject, String>(getSubjectHolder(), BaseJoinColumnStateObject.TABLE_PROPERTY) {
			@Override
			protected String buildValue_() {
				return subject.getTable();
			}

			@Override
			protected void setValue_(String value) {

				// Convert the default value or an empty string to null
				if ((value != null) &&
				   ((value.length() == 0) || value.startsWith(DEFAULT_KEY))) {

					value = null;
				}

				subject.setTable(value);
			}
		};
	}

	private ListValueModel<String> buildTableListHolder() {
		return new ListAspectAdapter<BaseJoinColumnStateObject, String>(getSubjectHolder(), "") {
			@Override
			protected ListIterator<String> listIterator_() {
				return subject.tables();
			}
		};
	}

	private ListValueModel<String> buildTablesListHolder() {
		ArrayList<ListValueModel<String>> holders = new ArrayList<ListValueModel<String>>(2);
		holders.add(buildDefaultTableListHolder());
		holders.add(buildTableListHolder());
		return new CompositeListValueModel<ListValueModel<String>, String>(holders);
	}

	private StringConverter<String> buildTableStringConverter() {
		return buildDisplayableStringConverter(new DefaultValueHandler() {
			public String getDefaultValue() {
				return getSubject().getDefaultTable();
			}
		});
	}

	/*
	 * (non-Javadoc)
	 */
	@Override
	protected void initializeLayout(Composite container) {

		// Name widgets
		Combo nameCombo = addLabeledEditableCombo(
			container,
			JptUiDetailsMessages.JoinColumnDialog_name,
			buildNamesListHolder(),
			buildNameHolder(),
			buildNameStringConverter(),
			JpaHelpContextIds.MAPPING_JOIN_COLUMN_NAME
		);

		SWTUtil.attachDefaultValueHandler(nameCombo);

		// Referenced Column Name widgets
		Combo referencedColumnNameCombo = addLabeledEditableCombo(
			container,
			JptUiDetailsMessages.JoinColumnDialog_referencedColumnName,
			buildReferencedColumnNamesListHolder(),
			buildReferencedColumnNameHolder(),
			buildReferencedColumnNameStringConverter(),
			JpaHelpContextIds.MAPPING_JOIN_REFERENCED_COLUMN
		);

		SWTUtil.attachDefaultValueHandler(referencedColumnNameCombo);

		// Table widgets
		if (isTableEditable()) {

			Combo tableCombo = addLabeledEditableCombo(
				container,
				JptUiDetailsMessages.JoinColumnDialogPane_table,
				buildTablesListHolder(),
				buildTableHolder(),
				buildTableStringConverter(),
				JpaHelpContextIds.MAPPING_JOIN_REFERENCED_COLUMN
			);

			SWTUtil.attachDefaultValueHandler(tableCombo);
		}
		else {
			Combo tableCombo = addLabeledCombo(
				container,
				JptUiDetailsMessages.JoinColumnDialogPane_table,
				buildTablesListHolder(),
				buildTableHolder(),
				buildTableStringConverter(),
				JpaHelpContextIds.MAPPING_JOIN_REFERENCED_COLUMN
			);

			tableCombo.setEnabled(false);
		}

		// Column Definition widgets
		addLabeledText(
			container,
			JptUiDetailsMessages.JoinColumnDialogPane_columnDefinition,
			buildColumnDefinitionHolder()
		);
	}

	/**
	 * Determines whether the table combo should be editable or not. The default
	 * is to keep the combo read-only.
	 *
	 * @return <code>true</code> to support the editing of the selected table;
	 * <code>false</code> otherwise
	 */
	protected boolean isTableEditable() {
		return false;
	}

	protected static interface DefaultValueHandler {
		String getDefaultValue();
	}
}