/*******************************************************************************
 * Copyright (c) 2008-2011 Chair for Applied Software Engineering,
 * Technische Universitaet Muenchen.
 * 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:
 ******************************************************************************/
package org.eclipse.emf.ecp.editor.mecontrols.multiattributecontrol;

import java.util.ArrayList;

import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.EStructuralFeature;
import org.eclipse.emf.ecore.ETypedElement;
import org.eclipse.emf.ecp.editor.mecontrols.AbstractMEControl;
import org.eclipse.emf.edit.provider.IItemPropertyDescriptor;
import org.eclipse.swt.SWT;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.ui.forms.widgets.Form;

/**
 * Represents a multi-attribute-item for the editor of an EMFCP model element.
 * <p>
 * FEATURES:
 * <p>
 * * Changes are applied whenever a field is modified, then: immediate storage of any change in the model data and
 * immediate redrawing of the widget (always n+1 fields for n entries so a new one can be added easily)
 * <p>
 * * Limited to $upperBound$ entries if it is != -1.
 * <p>
 * * Non-changeable attributes are handled correctly.
 * <p>
 * * When a duplicate is entered (and forbidden), this is also handled in the GUI.
 * <p>
 * Note that some of the features have to be implemented in a concrete class. See description of abstract methods for
 * further information.
 * 
 * @author Christian Kroemer (christian.kroemer@z-corp-online.de)
 */
public abstract class MultiAttributeControl extends AbstractMEControl {
	// CONSTANTS
	private static final int PRIORITY = 2;

	// state attributes
	private int style;
	private int upperBound;
	private boolean isEditable;
	private boolean allowDuplicates;
	private ArrayList<AttributeControl> controlList = new ArrayList<AttributeControl>();

	// essential references
	private Composite composite;
	private GridLayout gridLayout;
	private Control emptyField; // or the bottom one if isFull() && isEditable()

	/**
	 * {@inheritDoc}
	 */
	@Override
	public int canRender(IItemPropertyDescriptor itemPropertyDescriptor, EObject modelElement) {
		Object feature = itemPropertyDescriptor.getFeature(modelElement);

		if (feature instanceof ETypedElement) {
			ETypedElement attr = (ETypedElement) feature;
			upperBound = attr.getUpperBound();
			if (upperBound == -1 || upperBound > 1) {
				return PRIORITY;
			} else {
				return DO_NOT_RENDER;
			}
		}
		return DO_NOT_RENDER;
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public Control createControl(Composite parent, int style) {
		final EStructuralFeature feature = (EStructuralFeature) getItemPropertyDescriptor().getFeature(
			getModelElement());
		createDataStructures(feature);

		// set state
		this.setStyle(style);
		setEditable(getItemPropertyDescriptor().canSetProperty(getModelElement()));
		setAllowDuplicates(!feature.isUnique());

		// create composite structure
		setComposite(getToolkit().createComposite(parent, style | SWT.BORDER));
		configureGridLayout();
		getComposite().setLayout(gridLayout);
		if (!getItemPropertyDescriptor().canSetProperty(getModelElement())) {
			getComposite().setEnabled(false);
		}
		// re-set upper bound... needed because canRender() was called in an other instance
		upperBound = feature.getUpperBound();

		initializeWidget();
		return getComposite();
	}

	/**
	 * Creates the lists for stored values and fields needed.
	 * 
	 * @param feature reference to the feature of this model element
	 */
	protected abstract void createDataStructures(EStructuralFeature feature);

	/**
	 * Configures the GridLayout.
	 */
	private void configureGridLayout() {
		gridLayout = new GridLayout(1, true);
		gridLayout.verticalSpacing = 0;
	}

	/**
	 * Creates, draws and fills all fields needed to display the attribute's data.
	 */
	protected void initializeWidget() {
		for (Object i : getAllStoredElements()) {
			createSingleField(i);
		}
		if (!isFull() && isEditable()) {
			createSingleField();
		}
		// make sure it is drawn correctly
		refreshWidget();
	}

	/**
	 * Resets the widget.
	 */
	protected void reInitializeWidget() {
		// remove empty control (not in controlList!)
		if (!isFull()) {
			emptyField.getParent().dispose();
		}
		// remove all other controls
		while (!controlList.isEmpty()) {
			controlList.get(0).dispose();
			controlList.remove(0);
		}
		initializeWidget();
	}

	/**
	 * Redraws the widget with correct layout.
	 */
	protected void refreshWidget() {
		Composite tmp = getComposite();
		while (!(tmp instanceof Form)) {
			// loop until the composite for the whole editor window is reached (doesn't work for less calls)
			tmp.layout(); // are all layout calls necessary?
			tmp = tmp.getParent();
		}
	}

	/**
	 * Checks if this widget is full.
	 * 
	 * @return true if full, false otherwise
	 */
	protected boolean isFull() {
		return ((getControlList().size() >= upperBound) && upperBound != -1);
	}

	/**
	 * Creates one new field within the widget.
	 * <p>
	 * Implement a widget that can display a single attribute of this type and make sure it features suitable Listeners
	 * (immediately store data and always call refreshWidget() after changes; also make sure there is always a new empty
	 * field if the upper bound isn't reached when the former empty field is filled with data; handle duplicates). Deny
	 * editing of field if the attribute is non-changeable.
	 * <p>
	 * Call this method without any parameter for an empty field!
	 * 
	 * @param content the data to be displayed in the new field; make sure it is the right type and cast it accordingly
	 *            in your implementation
	 */
	protected abstract void createSingleField(Object content);

	/**
	 * Creates one new empty field within the widget. See description of createSingleField(Object content) for further
	 * information on implementation details.
	 */
	protected abstract void createSingleField();

	/**
	 * Returns all elements of this attribute as Object array. Needed for some superclass methods.
	 * 
	 * @return the array
	 */
	public abstract Object[] getAllStoredElements();

	/**
	 * @param controlList the controlList to set
	 */
	public void setControlList(ArrayList<AttributeControl> controlList) {
		this.controlList = controlList;
	}

	/**
	 * @return the controlList
	 */
	public ArrayList<AttributeControl> getControlList() {
		return controlList;
	}

	/**
	 * @param style the style to set
	 */
	public void setStyle(int style) {
		this.style = style;
	}

	/**
	 * @return the style
	 */
	public int getStyle() {
		return style;
	}

	/**
	 * @param allowDuplicates the allowDuplicates to set
	 */
	public void setAllowDuplicates(boolean allowDuplicates) {
		this.allowDuplicates = allowDuplicates;
	}

	/**
	 * @return the allowDuplicates
	 */
	public boolean isAllowDuplicates() {
		return allowDuplicates;
	}

	/**
	 * @param composite the composite to set
	 */
	public void setComposite(Composite composite) {
		this.composite = composite;
	}

	/**
	 * @return the composite
	 */
	public Composite getComposite() {
		return composite;
	}

	/**
	 * @param isEditable the isEditable to set
	 */
	public void setEditable(boolean isEditable) {
		this.isEditable = isEditable;
	}

	/**
	 * @return the isEditable
	 */
	public boolean isEditable() {
		return isEditable;
	}

	/**
	 * @param emptyField the emptyField to set
	 */
	public void setEmptyField(Control emptyField) {
		this.emptyField = emptyField;
	}

	/**
	 * @return the emptyField
	 */
	public Control getEmptyField() {
		return emptyField;
	}

}