/**
 * 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 2.0 
 * which accompanies this distribution, and is available at
 * https://www.eclipse.org/legal/epl-2.0/
 *
 * SPDX-License-Identifier: EPL-2.0
 *
 * 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.osbp.ecview.core.common.editpart.IElementEditpart;
import org.eclipse.osbp.ecview.core.extension.model.extension.YTabSheet;
import org.eclipse.osbp.ecview.core.ui.core.editparts.extension.ITabEditpart;
import org.eclipse.osbp.ecview.core.ui.core.editparts.extension.ITabSheetEditpart;
import org.eclipse.osbp.ecview.core.ui.core.editparts.extension.presentation.ITabSheetPresentation;
import org.eclipse.osbp.runtime.designer.api.IDesignerService.IDesignListener;
import org.eclipse.osbp.runtime.web.ecview.presentation.vaadin.common.AbstractTabSheetPresenter;

import com.vaadin.ui.Component;
import com.vaadin.ui.ComponentContainer;
import com.vaadin.ui.CssLayout;
import com.vaadin.ui.TabSheet;

import fi.jasoft.dragdroplayouts.DDTabSheet;

// TODO: Auto-generated Javadoc
/**
 * This presenter is responsible to render a tab sheet on the given layout.
 */
public class TabSheetPresentation extends
		AbstractTabSheetPresenter<ComponentContainer> implements
		ITabSheetPresentation<ComponentContainer>, IDesignListener {

	/** The component base. */
	private CssLayout componentBase;

	/** The tab sheet. */
	private DDTabSheet tabSheet;

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

	/** The rendered tabs. */
	private List<ITabEditpart> renderedTabs = new ArrayList<ITabEditpart>();

	/**
	 * The constructor.
	 * 
	 * @param editpart
	 *            The editpart of that editpart.
	 */
	public TabSheetPresentation(IElementEditpart editpart) {
		super((ITabSheetEditpart) editpart);
		this.modelAccess = new ModelAccess((YTabSheet) 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() {
	}

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

		unrenderTabs();
		tabSheet.removeAllComponents();

		// iterate all elements and build the tab element
		//
		for (ITabEditpart editPart : getEditpart().getTabs()) {
			addTab(editPart);
		}
	}

	/**
	 * Is called to create the tab component and apply layouting defaults to it.
	 *
	 * @param editpart
	 *            the editpart
	 */
	protected void addTab(ITabEditpart editpart) {
		editpart.render(tabSheet);
		renderedTabs.add(editpart);
	}

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

			componentBase.addStyleName(CSS_CLASS_CONTROL_BASE);
			if (modelAccess.isCssIdValid()) {
				componentBase.setId(modelAccess.getCssID());
			} else {
				componentBase.setId(getEditpart().getId());
			}

			associateWidget(componentBase, modelAccess.yLayout);

			tabSheet = new DDTabSheet();
			componentBase.addComponent(tabSheet);
			tabSheet.setSizeFull();

			associateWidget(tabSheet, modelAccess.yLayout);

			if (modelAccess.isCssClassValid()) {
				tabSheet.addStyleName(modelAccess.getCssClass());
			} else {
				tabSheet.addStyleName(CSS_CLASS_CONTROL);
			}

			initialize(tabSheet, getCastedModel());

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

			renderTabs(false);
		}

		return componentBase;
	}

	protected void createBindings(YTabSheet yField, TabSheet field) {
		super.createBindings(yField, field, null);
	}

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

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

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.osbp.runtime.web.ecview.presentation.vaadin.common.
	 * AbstractVaadinWidgetPresenter#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 (componentBase != null) {

			// unbind all active bindings
			unbind();

			ComponentContainer parent = ((ComponentContainer) componentBase
					.getParent());
			if (parent != null) {
				parent.removeComponent(componentBase);
			}

			// remove assocations
			unassociateWidget(componentBase);
			unassociateWidget(tabSheet);

			componentBase = null;
			tabSheet = null;

			// unrender the tabs
			unrenderTabs();
		}
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see
	 * org.eclipse.osbp.ecview.core.ui.core.editparts.extension.presentation
	 * .ITabSheetPresentation#renderTabs(boolean)
	 */
	@Override
	public void renderTabs(boolean force) {
		if (force) {
			unrenderTabs();
		}

		refreshUI();
	}

	/**
	 * Unrender tab.
	 *
	 * @param editpart
	 *            the editpart
	 */
	public void unrenderTab(ITabEditpart editpart) {
		if (editpart.isRendered()) {
			Component c = (Component) editpart.getWidget();
			tabSheet.removeTab(tabSheet.getTab(c));
			editpart.unrender();

			renderedTabs.remove(editpart);
		}
	}

	/**
	 * Will unrender all tabs.
	 */
	protected void unrenderTabs() {
		try {
			for (ITabEditpart editpart : renderedTabs) {
				if (editpart.isRendered()) {
					editpart.unrender();
				}
			}
		} finally {
			renderedTabs.clear();
		}
	}

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

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

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

}
