/**
 * 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.List;
import java.util.Locale;

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.YCssLayout;
import org.eclipse.osbp.ecview.core.extension.model.extension.YCssLayoutCellStyle;
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.server.Responsive;
import com.vaadin.ui.Component;
import com.vaadin.ui.ComponentContainer;

import fi.jasoft.dragdroplayouts.DDCssLayout;

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

	/** The Constant LOGGER. */
	@SuppressWarnings("unused")
	private static final Logger LOGGER = LoggerFactory
			.getLogger(CssLayoutPresentation.class);

	/** The css layout. */
	private DDCssLayout cssLayout;
	
	/** The model access. */
	private ModelAccess modelAccess;

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

	/* (non-Javadoc)
	 * @see org.eclipse.osbp.runtime.web.ecview.presentation.vaadin.common.AbstractLayoutPresenter#add(org.eclipse.osbp.ecview.core.common.editpart.IEmbeddableEditpart)
	 */
	@Override
	public void add(IEmbeddableEditpart editpart) {
		super.add(editpart);

		refreshUI();
	}

	/* (non-Javadoc)
	 * @see org.eclipse.osbp.runtime.web.ecview.presentation.vaadin.common.AbstractLayoutPresenter#remove(org.eclipse.osbp.ecview.core.common.editpart.IEmbeddableEditpart)
	 */
	@Override
	public void remove(IEmbeddableEditpart editpart) {
		super.remove(editpart);

		refreshUI();
	}

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

		refreshUI();
	}

	/* (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();
	}

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

		refreshUI();
	}

	/* (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() {

	}

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

		// iterate all elements and build the child element
		//
		List<Cell> cells = new ArrayList<Cell>();
		for (IEmbeddableEditpart child : getEditpart().getElements()) {
			Cell cell = addChild(child);
			cells.add(cell);
		}

		cssLayout.setSizeUndefined();
	}

	/**
	 * Is called to create the child component and apply layouting defaults to
	 * it.
	 *
	 * @param editpart
	 *            the editpart
	 * @return the cell
	 */
	protected Cell addChild(IEmbeddableEditpart editpart) {

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

		child.setSizeUndefined();
		cssLayout.addComponent(child);

		return new Cell(child);
	}

	/**
	 * Maps the vertical part of the alignment to FILL.
	 * 
	 * @param yAlignment
	 *            the alignment
	 * @return alignment the mapped alignment
	 */
	// BEGIN SUPRESS CATCH EXCEPTION
	protected YAlignment mapToVerticalFill(YAlignment yAlignment) {
		// END SUPRESS CATCH EXCEPTION
		if (yAlignment != null) {
			switch (yAlignment) {
			case BOTTOM_CENTER:
			case MIDDLE_CENTER:
			case TOP_CENTER:
				return YAlignment.FILL_CENTER;
			case BOTTOM_FILL:
			case MIDDLE_FILL:
			case TOP_FILL:
				return YAlignment.FILL_FILL;
			case BOTTOM_LEFT:
			case MIDDLE_LEFT:
			case TOP_LEFT:
				return YAlignment.FILL_LEFT;
			case BOTTOM_RIGHT:
			case MIDDLE_RIGHT:
			case TOP_RIGHT:
				return YAlignment.FILL_RIGHT;
			case FILL_FILL:
			case FILL_LEFT:
			case FILL_RIGHT:
			case FILL_CENTER:
				return YAlignment.FILL_FILL;
			default:
				break;
			}
		}
		return YAlignment.FILL_FILL;
	}

	/**
	 * Maps the horizontal part of the alignment to FILL.
	 * 
	 * @param yAlignment
	 *            the alignment
	 * @return alignment the mapped alignment
	 */
	// BEGIN SUPRESS CATCH EXCEPTION
	protected YAlignment mapToHorizontalFill(YAlignment yAlignment) {
		// END SUPRESS CATCH EXCEPTION
		if (yAlignment != null) {
			switch (yAlignment) {
			case BOTTOM_CENTER:
			case BOTTOM_FILL:
			case BOTTOM_LEFT:
			case BOTTOM_RIGHT:
				return YAlignment.BOTTOM_FILL;
			case MIDDLE_CENTER:
			case MIDDLE_FILL:
			case MIDDLE_LEFT:
			case MIDDLE_RIGHT:
				return YAlignment.MIDDLE_FILL;
			case TOP_CENTER:
			case TOP_FILL:
			case TOP_LEFT:
			case TOP_RIGHT:
				return YAlignment.TOP_FILL;
			case FILL_FILL:
			case FILL_LEFT:
			case FILL_RIGHT:
			case FILL_CENTER:
				return YAlignment.FILL_FILL;
			default:
				break;
			}
		}
		return YAlignment.FILL_FILL;
	}

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

			cssLayout = new DDCssLayout();
			cssLayout.setImmediate(true);

			setupComponent(cssLayout, getCastedModel());

			associateWidget(cssLayout, modelAccess.yLayout);

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

			if (modelAccess.isCssClassValid()) {
				cssLayout.addStyleName(modelAccess.getCssClass());
			} else {
				cssLayout.addStyleName(CSS_CLASS_CONTROL);
			}
			cssLayout.addStyleName(IConstants.CSS_CLASS_CSSLAYOUT);

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

			Responsive.makeResponsive(cssLayout);
			initializeChildren();

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

		return cssLayout;
	}

	/**
	 * 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 cssLayout;
	}

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

	/* (non-Javadoc)
	 * @see org.eclipse.osbp.runtime.web.ecview.presentation.vaadin.common.AbstractLayoutPresenter#internalDispose()
	 */
	@Override
	protected void internalDispose() {

		try {
			unrender();
		} finally {
			super.internalDispose();
		}

	}

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

			// unbind all active bindings
			unbind();

			// remove assocations
			unassociateWidget(cssLayout);

			// unrender the children
			unrenderChildren();

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

	/* (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 YCssLayout yLayout;

		/**
		 * Instantiates a new model access.
		 *
		 * @param yLayout
		 *            the y layout
		 */
		public ModelAccess(YCssLayout 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("");
		}

		/**
		 * 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("");
		}

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

	}

	/**
	 * The Class Cell.
	 */
	public static class Cell {
		
		/** The component. */
		private final Component component;

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

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