/**
 * Copyright (c) 2011, 2015 - Lunifera GmbH (Gross Enzersdorf, Austria), Loetz GmbH&Co.KG (69115 Heidelberg, Germany)
 * 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:
 *         Florian Pirchner - Initial implementation
 */
package org.eclipse.osbp.runtime.web.ecview.presentation.vaadin.internal;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Locale;
import java.util.Map;

import org.eclipse.emf.common.util.EList;
import org.eclipse.osbp.ecview.core.common.editpart.IElementEditpart;
import org.eclipse.osbp.ecview.core.common.editpart.IEmbeddableEditpart;
import org.eclipse.osbp.ecview.core.common.editpart.ILayoutEditpart;
import org.eclipse.osbp.ecview.core.common.model.core.YAlignment;
import org.eclipse.osbp.ecview.core.common.model.core.YEmbeddable;
import org.eclipse.osbp.ecview.core.extension.model.extension.YVerticalLayout;
import org.eclipse.osbp.ecview.core.extension.model.extension.YVerticalLayoutCellStyle;
import org.eclipse.osbp.runtime.web.ecview.presentation.vaadin.IConstants;
import org.eclipse.osbp.runtime.web.ecview.presentation.vaadin.common.AbstractLayoutPresenter;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.vaadin.ui.Alignment;
import com.vaadin.ui.Component;
import com.vaadin.ui.ComponentContainer;

import fi.jasoft.dragdroplayouts.DDVerticalLayout;

// TODO: Auto-generated Javadoc
/**
 * This presenter is responsible to render a text field on the given layout.
 */
public class VerticalLayoutPresentation extends
		AbstractLayoutPresenter<ComponentContainer> {

	/** The Constant LOGGER. */
	private static final Logger LOGGER = LoggerFactory
			.getLogger(VerticalLayoutPresentation.class);

	/** The vertical layout. */
	private DDVerticalLayout verticalLayout;

	/** The model access. */
	private ModelAccess modelAccess;

	/**
	 * The constructor.
	 * 
	 * @param editpart
	 *            The editpart of that presentation.
	 */
	public VerticalLayoutPresentation(IElementEditpart editpart) {
		super((ILayoutEditpart) editpart);
		this.modelAccess = new ModelAccess(
				(YVerticalLayout) editpart.getModel());
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.osbp.runtime.web.ecview.presentation.vaadin.common.
	 * AbstractVaadinWidgetPresenter#doUpdateLocale(java.util.Locale)
	 */
	@Override
	protected void doUpdateLocale(Locale locale) {
		// no need to set the locale to the ui elements. Is handled by vaadin
		// internally.

		// update the captions
		applyCaptions();
	}

	/**
	 * Applies the labels to the widgets.
	 */
	protected void applyCaptions() {
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.osbp.runtime.web.ecview.presentation.vaadin.common.
	 * AbstractLayoutPresenter
	 * #updateCellStyle(org.eclipse.osbp.ecview.core.common
	 * .model.core.YEmbeddable)
	 */
	public void updateCellStyle(YEmbeddable child) {
		// refresh the whole ui
		refreshUI();
	}

	/**
	 * Is called to refresh the UI. The element will be removed from the grid
	 * layout and added to it again afterwards.
	 */
	protected void refreshUI() {
		verticalLayout.removeAllComponents();

		// create a map containing the style for the embeddable
		//
		Map<YEmbeddable, YVerticalLayoutCellStyle> yStyles = new HashMap<YEmbeddable, YVerticalLayoutCellStyle>();
		for (YVerticalLayoutCellStyle style : modelAccess.getCellStyles()) {
			if (yStyles.containsKey(style.getTarget())) {
				LOGGER.warn("Multiple style for element {}", style.getTarget());
			}
			yStyles.put(style.getTarget(), style);
		}

		// iterate all elements and build the child element
		//
		List<Cell> cells = new ArrayList<Cell>();
		for (IEmbeddableEditpart childPresentation : getChildren()) {
			YEmbeddable yChild = (YEmbeddable) childPresentation.getModel();
			cells.add(addChildComponent(childPresentation, yStyles.get(yChild)));
		}

		for (Cell cell : cells) {
			if (cell.isExpandVertical()) {
				// expandVerticalFound = true;
				verticalLayout.setExpandRatio(cell.getComponent(), 1.0f);
			}
		}

	}

	/**
	 * Is called to create the child component and apply layouting defaults to
	 * it.
	 *
	 * @param editpart
	 *            the editpart
	 * @param yStyle
	 *            the y style
	 * @return the cell
	 */
	protected Cell addChildComponent(IEmbeddableEditpart editpart,
			YVerticalLayoutCellStyle yStyle) {

		Component child = (Component) editpart.render(verticalLayout);

		// calculate and apply the alignment to be used
		//
		YAlignment yAlignment = yStyle != null && yStyle.getAlignment() != null ? yStyle
				.getAlignment() : YAlignment.TOP_LEFT;

		verticalLayout.addComponent(child);
		applyAlignment(child, yAlignment);

		return new Cell(child, yAlignment);
	}

	/**
	 * Sets the alignment to the component.
	 *
	 * @param child
	 *            the child
	 * @param yAlignment
	 *            the y alignment
	 */
	protected void applyAlignment(Component child, YAlignment yAlignment) {

		if (yAlignment != null) {
			child.setSizeUndefined();
			switch (yAlignment) {
			case BOTTOM_CENTER:
				verticalLayout.setComponentAlignment(child,
						Alignment.BOTTOM_CENTER);
				break;
			case BOTTOM_FILL:
				verticalLayout.setComponentAlignment(child,
						Alignment.BOTTOM_LEFT);
				child.setWidth("100%");
				break;
			case BOTTOM_LEFT:
				verticalLayout.setComponentAlignment(child,
						Alignment.BOTTOM_LEFT);
				break;
			case BOTTOM_RIGHT:
				verticalLayout.setComponentAlignment(child,
						Alignment.BOTTOM_RIGHT);
				break;
			case MIDDLE_CENTER:
				verticalLayout.setComponentAlignment(child,
						Alignment.MIDDLE_CENTER);
				break;
			case MIDDLE_FILL:
				verticalLayout.setComponentAlignment(child,
						Alignment.MIDDLE_LEFT);
				child.setWidth("100%");
				break;
			case MIDDLE_LEFT:
				verticalLayout.setComponentAlignment(child,
						Alignment.MIDDLE_LEFT);
				break;
			case MIDDLE_RIGHT:
				verticalLayout.setComponentAlignment(child,
						Alignment.MIDDLE_RIGHT);
				break;
			case TOP_CENTER:
				verticalLayout.setComponentAlignment(child,
						Alignment.TOP_CENTER);
				break;
			case TOP_FILL:
				verticalLayout.setComponentAlignment(child, Alignment.TOP_LEFT);
				child.setWidth("100%");
				break;
			case TOP_LEFT:
				verticalLayout.setComponentAlignment(child, Alignment.TOP_LEFT);
				break;
			case TOP_RIGHT:
				verticalLayout
						.setComponentAlignment(child, Alignment.TOP_RIGHT);
				break;
			case FILL_CENTER:
				verticalLayout.setComponentAlignment(child,
						Alignment.TOP_CENTER);
				child.setHeight("100%");
				break;
			case FILL_FILL:
				verticalLayout.setComponentAlignment(child, Alignment.TOP_LEFT);
				child.setWidth("100%");
				child.setHeight("100%");
				break;
			case FILL_LEFT:
				verticalLayout.setComponentAlignment(child, Alignment.TOP_LEFT);
				child.setHeight("100%");
				break;
			case FILL_RIGHT:
				verticalLayout
						.setComponentAlignment(child, Alignment.TOP_RIGHT);
				child.setHeight("100%");
				break;
			default:
				break;
			}
		}
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.osbp.runtime.web.ecview.presentation.vaadin.common.
	 * AbstractVaadinWidgetPresenter#doCreateWidget(java.lang.Object)
	 */
	@Override
	public ComponentContainer doCreateWidget(Object parent) {
		if (verticalLayout == null) {
			verticalLayout = new DDVerticalLayout();
			setupComponent(verticalLayout, getCastedModel());

			associateWidget(verticalLayout, modelAccess.yLayout);

			if (modelAccess.isCssIdValid()) {
				verticalLayout.setId(modelAccess.getCssID());
			} else {
				verticalLayout.setId(getEditpart().getId());
			}

			if (modelAccess.isMargin()) {
				verticalLayout.addStyleName(IConstants.CSS_CLASS_MARGIN);
				verticalLayout.setMargin(true);
			}

			if (!modelAccess.isSpacing()) {
				verticalLayout.setSpacing(false);
			} else {
				verticalLayout.addStyleName(IConstants.CSS_CLASS_SPACING);
				verticalLayout.setSpacing(true);
			}

			if (modelAccess.isCssClassValid()) {
				verticalLayout.addStyleName(modelAccess.getCssClass());
			} else {
				verticalLayout.addStyleName(CSS_CLASS_CONTROL);
			}
			verticalLayout.addStyleName(IConstants.CSS_CLASS_VERTICALLAYOUT);

			// creates the binding for the field
			createBindings(modelAccess.yLayout, verticalLayout, null);

			// initialize all children
			initializeChildren();

			// and now render children
			renderChildren(false);
		}

		return verticalLayout;
	}

	/**
	 * Adds the children to the superclass and prevents rendering.
	 */
	private void initializeChildren() {
		setRenderLock(true);
		try {
			for (IEmbeddableEditpart editPart : getEditpart().getElements()) {
				super.add(editPart);
			}
		} finally {
			setRenderLock(false);
		}
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see
	 * org.eclipse.osbp.ecview.core.common.presentation.IWidgetPresentation#
	 * getWidget()
	 */
	@Override
	public ComponentContainer getWidget() {
		return verticalLayout;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see
	 * org.eclipse.osbp.ecview.core.common.presentation.IWidgetPresentation#
	 * isRendered()
	 */
	@Override
	public boolean isRendered() {
		return verticalLayout != null;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.osbp.runtime.web.ecview.presentation.vaadin.common.
	 * AbstractLayoutPresenter#internalDispose()
	 */
	@Override
	protected void internalDispose() {
		try {
			for (IEmbeddableEditpart child : new ArrayList<IEmbeddableEditpart>(
					getChildren())) {
				child.dispose();
			}
			unrender();
		} finally {
			super.internalDispose();
		}
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.osbp.runtime.web.ecview.presentation.vaadin.common.
	 * AbstractVaadinWidgetPresenter#doUnrender()
	 */
	@Override
	public void doUnrender() {
		if (verticalLayout != null) {

			// unbind all active bindings
			unbind();

			// remove assocations
			unassociateWidget(verticalLayout);

			// unrender the children
			unrenderChildren();

			verticalLayout.removeAllComponents();
			verticalLayout = null;
		}
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.osbp.runtime.web.ecview.presentation.vaadin.common.
	 * AbstractLayoutPresenter
	 * #internalAdd(org.eclipse.osbp.ecview.core.common.editpart
	 * .IEmbeddableEditpart)
	 */
	@Override
	protected void internalAdd(IEmbeddableEditpart editpart) {
		YEmbeddable yChild = (YEmbeddable) editpart.getModel();
		addChildComponent(editpart, modelAccess.getCellStyle(yChild));
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.osbp.runtime.web.ecview.presentation.vaadin.common.
	 * AbstractLayoutPresenter
	 * #internalRemove(org.eclipse.osbp.ecview.core.common
	 * .editpart.IEmbeddableEditpart)
	 */
	@Override
	protected void internalRemove(IEmbeddableEditpart child) {
		if (verticalLayout != null && child.isRendered()) {
			verticalLayout.removeComponent((Component) child.getWidget());
		}

		child.unrender();
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.osbp.runtime.web.ecview.presentation.vaadin.common.
	 * AbstractLayoutPresenter
	 * #internalInsert(org.eclipse.osbp.ecview.core.common
	 * .editpart.IEmbeddableEditpart, int)
	 */
	@Override
	protected void internalInsert(IEmbeddableEditpart editpart, int index) {
		refreshUI();
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.osbp.runtime.web.ecview.presentation.vaadin.common.
	 * AbstractLayoutPresenter
	 * #internalMove(org.eclipse.osbp.ecview.core.common.editpart
	 * .IEmbeddableEditpart, int, int)
	 */
	@Override
	protected void internalMove(IEmbeddableEditpart editpart, int oldIndex,
			int newIndex) {
		refreshUI();
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see
	 * org.eclipse.osbp.ecview.core.common.presentation.ILayoutPresentation#
	 * renderChildren(boolean)
	 */
	@Override
	public void renderChildren(boolean force) {
		if (force) {
			unrenderChildren();
		}

		refreshUI();
	}

	/**
	 * Will unrender all children.
	 */
	protected void unrenderChildren() {
		for (IEmbeddableEditpart editpart : getChildren()) {
			if (editpart.isRendered()) {
				editpart.unrender();
			}
		}
	}

	/**
	 * An internal helper class.
	 */
	private static class ModelAccess {

		/** The y layout. */
		private final YVerticalLayout yLayout;

		/**
		 * Instantiates a new model access.
		 *
		 * @param yLayout
		 *            the y layout
		 */
		public ModelAccess(YVerticalLayout yLayout) {
			super();
			this.yLayout = yLayout;
		}

		/**
		 * Gets the css class.
		 *
		 * @return the css class
		 * @see org.eclipse.osbp.ecview.core.ui.core.model.core.YCssAble#getCssClass()
		 */
		public String getCssClass() {
			return yLayout.getCssClass();
		}

		/**
		 * Returns true, if the css class is not null and not empty.
		 *
		 * @return true, if is css class valid
		 */
		public boolean isCssClassValid() {
			return getCssClass() != null && !getCssClass().equals("");
		}

		/**
		 * Checks if is spacing.
		 *
		 * @return true, if is spacing
		 * @see org.eclipse.osbp.ecview.core.ui.core.model.extension.YVerticalLayout#isSpacing()
		 */
		public boolean isSpacing() {
			return yLayout.isSpacing();
		}

		/**
		 * Gets the css id.
		 *
		 * @return the css id
		 * @see org.eclipse.osbp.ecview.core.ui.core.model.core.YCssAble#getCssID()
		 */
		public String getCssID() {
			return yLayout.getCssID();
		}

		/**
		 * Returns true, if the css id is not null and not empty.
		 *
		 * @return true, if is css id valid
		 */
		public boolean isCssIdValid() {
			return getCssID() != null && !getCssID().equals("");
		}

		/**
		 * Checks if is margin.
		 *
		 * @return true, if is margin
		 * @see org.eclipse.osbp.ecview.core.ui.core.model.extension.YVerticalLayout#isMargin()
		 */
		public boolean isMargin() {
			return yLayout.isMargin();
		}

		/**
		 * Gets the cell styles.
		 *
		 * @return the cell styles
		 * @see org.eclipse.osbp.ecview.core.ui.core.model.extension.YVerticalLayout#getCellStyles()
		 */
		public EList<YVerticalLayoutCellStyle> getCellStyles() {
			return yLayout.getCellStyles();
		}

		/**
		 * Gets the cell style.
		 *
		 * @param element
		 *            the element
		 * @return the cell style
		 */
		public YVerticalLayoutCellStyle getCellStyle(YEmbeddable element) {
			return yLayout.getCellStyle(element);
		}

	}

	/**
	 * The Class Cell.
	 */
	public static class Cell {

		/** The component. */
		private final Component component;

		/** The alignment. */
		private final YAlignment alignment;

		/**
		 * Instantiates a new cell.
		 *
		 * @param component
		 *            the component
		 * @param alignment
		 *            the alignment
		 */
		public Cell(Component component, YAlignment alignment) {
			super();
			this.component = component;
			this.alignment = alignment;
		}

		/**
		 * Gets the component.
		 *
		 * @return the component
		 */
		protected Component getComponent() {
			return component;
		}

		/**
		 * Gets the alignment.
		 *
		 * @return the alignment
		 */
		protected YAlignment getAlignment() {
			return alignment;
		}

		/**
		 * Checks if is expand vertical.
		 *
		 * @return true, if is expand vertical
		 */
		protected boolean isExpandVertical() {
			switch (alignment) {
			case FILL_CENTER:
			case FILL_FILL:
			case FILL_LEFT:
			case FILL_RIGHT:
				return true;
			default:
				return false;
			}
		}

		/**
		 * Checks if is expand horizontal.
		 *
		 * @return true, if is expand horizontal
		 */
		protected boolean isExpandHorizontal() {
			switch (alignment) {
			case BOTTOM_FILL:
			case FILL_FILL:
			case MIDDLE_FILL:
			case TOP_FILL:
				return true;
			default:
				return false;
			}
		}
	}
}
