/*******************************************************************************
 * Copyright (c) 2007, 2010 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.core.internal.jpa1.context.orm;

import java.util.List;
import org.eclipse.jpt.common.core.utility.TextRange;
import org.eclipse.jpt.jpa.core.context.NamedColumn;
import org.eclipse.jpt.jpa.core.context.TypeMapping;
import org.eclipse.jpt.jpa.core.context.orm.OrmAttributeMapping;
import org.eclipse.jpt.jpa.core.context.orm.OrmPersistentAttribute;
import org.eclipse.jpt.jpa.core.internal.context.JptValidator;
import org.eclipse.jpt.jpa.core.internal.context.NamedColumnTextRangeResolver;
import org.eclipse.jpt.jpa.core.internal.context.orm.AbstractOrmXmlContextNode;
import org.eclipse.jpt.jpa.core.internal.jpa2.context.OrderColumnValidator;
import org.eclipse.jpt.jpa.core.jpa2.context.OrderColumn2_0;
import org.eclipse.jpt.jpa.core.jpa2.context.orm.OrmOrderColumn2_0;
import org.eclipse.jpt.jpa.core.jpa2.context.orm.OrmOrderable2_0;
import org.eclipse.jpt.jpa.core.resource.orm.OrmFactory;
import org.eclipse.jpt.jpa.core.resource.orm.XmlOrderColumn;
import org.eclipse.jpt.jpa.core.resource.orm.XmlOrderable;
import org.eclipse.jpt.jpa.db.Table;
import org.eclipse.wst.validation.internal.provisional.core.IMessage;
import org.eclipse.wst.validation.internal.provisional.core.IReporter;

/**
 * <code>orm.xml</code> ordering
 * <p>
 * <strong>NB:</strong> Setting any flag to <code>false</code> (or setting the
 * specified "order by" to <code>null</code>) can be a bit unpredictable. The
 * intent is to set a flag to <code>true</code> (or set the specified "order by"
 * to a non-<code>null</code> value).
 * <p>
 * <strong>(JPA 2.0 only) NB:</strong> If both the "order-by" and the
 * "order-column" elements are present (which is prohibited by the JPA spec),
 * both are ignored.
 */
public class GenericOrmOrderable
	extends AbstractOrmXmlContextNode
	implements OrmOrderable2_0
{
	protected String specifiedOrderBy;
	protected boolean noOrdering = false;
	protected boolean pkOrdering = false;
	protected boolean customOrdering = false;

	// JPA 2.0
	protected final Owner owner;  // this is null for JPA 1.0 mappings
	protected boolean orderColumnOrdering = false;
	protected final OrmOrderColumn2_0 orderColumn;  // this is null for JPA 1.0 mappings


	/**
	 * JPA 1.0
	 */
	public GenericOrmOrderable(OrmAttributeMapping parent) {
		this(parent, null);
	}

	/**
	 * JPA 2.0
	 */
	public GenericOrmOrderable(OrmAttributeMapping parent, Owner owner) {
		super(parent);

		this.specifiedOrderBy = this.buildSpecifiedOrderBy();
		this.noOrdering = this.buildNoOrdering();
		this.pkOrdering = this.buildPkOrdering();
		this.customOrdering = this.buildCustomOrdering();

		this.owner = owner;
		this.orderColumnOrdering = this.buildOrderColumnOrdering();
		this.orderColumn = this.buildOrderColumn();
	}


	// ********** synchronize/update **********

	@Override
	public void synchronizeWithResourceModel() {
		super.synchronizeWithResourceModel();

		this.setSpecifiedOrderBy_(this.buildSpecifiedOrderBy());
		this.setNoOrdering_(this.buildNoOrdering());
		this.setPkOrdering_(this.buildPkOrdering());
		this.setCustomOrdering_(this.buildCustomOrdering());

		this.setOrderColumnOrdering_(this.buildOrderColumnOrdering());
		if (this.orderColumn != null) {
			this.orderColumn.synchronizeWithResourceModel();
		}
	}

	@Override
	public void update() {
		super.update();
		if (this.orderColumn != null) {
			this.orderColumn.update();
		}
	}


	// ********** specified order by **********

	public String getSpecifiedOrderBy() {
		return this.specifiedOrderBy;
	}

	public void setSpecifiedOrderBy(String orderBy) {
		if (orderBy != null) {
			this.setSpecifiedOrderBy_(orderBy);
			this.setNoOrdering_(false);
			this.setPkOrdering_(orderBy.length() == 0);
			this.setCustomOrdering_(orderBy.length() != 0);
			this.setOrderColumnOrdering_(false);

			this.removeXmlOrderColumn();
			this.getXmlOrderable().setOrderBy(orderBy);
		} else {
			this.setNoOrdering(true);  // hmmm...
		}
	}

	protected void setSpecifiedOrderBy_(String orderBy) {
		String old = this.specifiedOrderBy;
		this.specifiedOrderBy = orderBy;
		this.firePropertyChanged(SPECIFIED_ORDER_BY_PROPERTY, old, orderBy);
	}

	protected String buildSpecifiedOrderBy() {
		if (this.xmlOrderColumnIsPresent()) {
			return null;
		}
		return this.getXmlOrderBy();
	}


	// ********** no ordering **********

	public boolean isNoOrdering() {
		return this.noOrdering;
	}

	public void setNoOrdering(boolean noOrdering) {
		if (noOrdering) {
			this.setSpecifiedOrderBy_(null);
			this.setNoOrdering_(true);
			this.setPkOrdering_(false);
			this.setCustomOrdering_(false);
			this.setOrderColumnOrdering_(false);

			this.removeXmlOrderColumn();
			this.getXmlOrderable().setOrderBy(null);
		} else {
			this.setPkOrdering(true);  // hmmm...
		}
	}

	protected void setNoOrdering_(boolean noOrdering) {
		boolean old = this.noOrdering;
		this.noOrdering = noOrdering;
		this.firePropertyChanged(NO_ORDERING_PROPERTY, old, noOrdering);
	}

	protected boolean buildNoOrdering() {
		return this.isJpa2_0Compatible() ? this.buildNoOrdering2_0() : this.buildNoOrdering1_0();
	}

	/**
	 * both elements are missing <em>or</em> both are present
	 */
	protected boolean buildNoOrdering2_0() {
		boolean orderByMissing = (this.getXmlOrderBy() == null);
		boolean orderByPresent = ! orderByMissing;
		boolean orderColumnMissing = (this.getXmlOrderColumn() == null);
		boolean orderColumnPresent = ! orderColumnMissing;
		return (orderByMissing && orderColumnMissing) || (orderByPresent && orderColumnPresent);
	}

	/**
	 * the order-by element is missing
	 */
	protected boolean buildNoOrdering1_0() {
		return this.getXmlOrderBy() == null;
	}


	// ********** pk ordering **********

	public boolean isPkOrdering() {
		return this.pkOrdering;
	}

	public void setPkOrdering(boolean pkOrdering) {
		if (pkOrdering) {
			this.setSpecifiedOrderBy(""); //$NON-NLS-1$
		} else {
			this.setNoOrdering(true);  // hmmm...
		}
	}

	protected void setPkOrdering_(boolean pkOrdering) {
		boolean old = this.pkOrdering;
		this.pkOrdering = pkOrdering;
		this.firePropertyChanged(PK_ORDERING_PROPERTY, old, pkOrdering);
	}

	/**
	 * the order-by element is present but no value specified
	 */
	protected boolean buildPkOrdering() {
		if (this.xmlOrderColumnIsPresent()) {
			return false;
		}
		String xmlOrderBy = this.getXmlOrderBy();
		return (xmlOrderBy != null) && (xmlOrderBy.length() == 0);
	}


	// ********** custom ordering **********

	public boolean isCustomOrdering() {
		return this.customOrdering;
	}

	/**
	 * Unfortunately, setting the "custom ordering" flag directly is a bit hacky:
	 * The "specified order-by" is initially set to an empty string, which is
	 * the same as a "primary key ordering" state....
	 */
	public void setCustomOrdering(boolean customOrdering) {
		if (customOrdering) {
			this.setSpecifiedOrderBy_("");  // hmmm... //$NON-NLS-1$
			this.setNoOrdering_(false);
			this.setPkOrdering_(false);
			this.setCustomOrdering_(true);
			this.setOrderColumnOrdering_(false);

			this.removeXmlOrderColumn();
			this.getXmlOrderable().setOrderBy(""); //$NON-NLS-1$
		} else {
			this.setNoOrdering(true);  // hmmm...
		}
	}

	protected void setCustomOrdering_(boolean customOrdering) {
		boolean old = this.customOrdering;
		this.customOrdering = customOrdering;
		this.firePropertyChanged(CUSTOM_ORDERING_PROPERTY, old, customOrdering);
	}

	/**
	 * the order-by element is present and it has a specified value
	 */
	protected boolean buildCustomOrdering() {
		if (this.xmlOrderColumnIsPresent()) {
			return false;
		}
		String xmlOrderBy = this.getXmlOrderBy();
		return (xmlOrderBy != null) && (xmlOrderBy.length() != 0);
	}


	// ********** order column ordering **********

	public boolean isOrderColumnOrdering() {
		return this.orderColumnOrdering;
	}

	public void setOrderColumnOrdering(boolean orderColumnOrdering) {
		if (orderColumnOrdering) {
			this.setSpecifiedOrderBy_(null);
			this.setNoOrdering_(false);
			this.setPkOrdering_(false);
			this.setCustomOrdering_(false);
			this.setOrderColumnOrdering_(true);

			this.getXmlOrderable().setOrderBy(null);
			this.buildXmlOrderColumn();
		} else {
			this.setNoOrdering(true);  // hmmm...
		}
	}

	protected void setOrderColumnOrdering_(boolean orderColumnOrdering) {
		boolean old = this.orderColumnOrdering;
		this.orderColumnOrdering = orderColumnOrdering;
		this.firePropertyChanged(ORDER_COLUMN_ORDERING_PROPERTY, old, orderColumnOrdering);
	}

	/**
	 * JPA 2.0 only;
	 * the <code>order-column</code> element is present <em>and</em>
	 * the <code>order-by</code> element is missing
	 */
	protected boolean buildOrderColumnOrdering() {
		return this.xmlOrderColumnIsPresent() &&
				(this.getXmlOrderBy() == null);
	}


	// ********** order column **********

	public OrmOrderColumn2_0 getOrderColumn() {
		return this.orderColumn;
	}

	/**
	 * JPA 2.0 only
	 */
	protected OrmOrderColumn2_0 buildOrderColumn() {
		return this.isJpa2_0Compatible() ? this.buildOrderColumn_() : null;
	}

	protected OrmOrderColumn2_0 buildOrderColumn_() {
		return this.getContextNodeFactory2_0().buildOrmOrderColumn(this, new OrderColumnOwner());
	}


	// ********** xml order by **********

	protected String getXmlOrderBy() {
		return this.getXmlOrderable().getOrderBy();
	}


	// ********** xml order column **********

	protected XmlOrderColumn getXmlOrderColumn() {
		return this.getXmlOrderable().getOrderColumn();
	}

	/**
	 * NB: Only return <code>true</code> for JPA 2.0 mappings.
	 */
	protected boolean xmlOrderColumnIsPresent() {
		return this.isJpa2_0Compatible() && (this.getXmlOrderColumn() != null);
	}

	protected XmlOrderColumn buildXmlOrderColumn() {
		XmlOrderColumn xmlColumn = OrmFactory.eINSTANCE.createXmlOrderColumn();
		GenericOrmOrderable.this.getXmlOrderable().setOrderColumn(xmlColumn);
		return xmlColumn;
	}

	protected void removeXmlOrderColumn() {
		if (this.xmlOrderColumnIsPresent()) {
			this.getXmlOrderable().setOrderColumn(null);
		}
	}


	// ********** misc **********

	@Override
	public OrmAttributeMapping getParent() {
		return (OrmAttributeMapping) super.getParent();
	}

	protected OrmAttributeMapping getAttributeMapping() {
		return this.getParent();
	}

	protected OrmPersistentAttribute getPersistentAttribute() {
		return this.getAttributeMapping().getPersistentAttribute();
	}

	protected XmlOrderable getXmlOrderable() {
		return (XmlOrderable) this.getAttributeMapping().getXmlAttributeMapping();
	}

	// JPA 2.0
	public String getDefaultTableName() {
		return this.owner.getTableName();
	}

	// JPA 2.0
	protected Table resolveDbTable(String tableName) {
		return this.owner.resolveDbTable(tableName);
	}


	// ********** validation **********

	public TextRange getValidationTextRange() {
		TextRange textRange = this.getXmlOrderable().getValidationTextRange();
		return (textRange != null) ? textRange : this.getAttributeMapping().getValidationTextRange();
	}

	@Override
	public void validate(List<IMessage> messages, IReporter reporter) {
		super.validate(messages, reporter);
		// order-column and order-by both specified is handled with schema validation
		if (this.orderColumnOrdering) {
			// TODO validation message if type is not List
			this.orderColumn.validate(messages, reporter);
		}
	}


	// ********** order column owner (JPA 2.0) **********

	protected class OrderColumnOwner
		implements OrmOrderColumn2_0.Owner
	{
		public String getDefaultTableName() {
			return GenericOrmOrderable.this.getDefaultTableName();
		}

		public Table resolveDbTable(String tableName) {
			return GenericOrmOrderable.this.resolveDbTable(tableName);
		}

		public String getDefaultColumnName() {
			return this.getPersistentAttribute().getName() + "_ORDER"; //$NON-NLS-1$
		}

		public TypeMapping getTypeMapping() {
			return this.getPersistentAttribute().getOwningTypeMapping();
		}

		public TextRange getValidationTextRange() {
			return GenericOrmOrderable.this.getValidationTextRange();
		}

		public JptValidator buildColumnValidator(NamedColumn column, NamedColumnTextRangeResolver textRangeResolver) {
			return new OrderColumnValidator(this.getPersistentAttribute(), (OrderColumn2_0) column, textRangeResolver);
		}

		public XmlOrderColumn getXmlColumn() {
			return GenericOrmOrderable.this.getXmlOrderColumn();
		}

		public XmlOrderColumn buildXmlColumn() {
			return GenericOrmOrderable.this.buildXmlOrderColumn();
		}

		public void removeXmlColumn() {
			GenericOrmOrderable.this.removeXmlOrderColumn();
		}

		protected OrmPersistentAttribute getPersistentAttribute() {
			return GenericOrmOrderable.this.getPersistentAttribute();
		}
	}
}
