/**
 *                                                                            
 *  Copyright (c) 2011, 2016 - 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.ecview.extension.presentation.vaadin.strategy;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.Locale;
import java.util.Map;

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.IKeyStrokeDefinitionEditpart;
import org.eclipse.osbp.ecview.core.common.model.core.YAlignment;
import org.eclipse.osbp.ecview.extension.editparts.IStrategyLayoutEditpart;
import org.eclipse.osbp.ecview.extension.editparts.presentation.IStrategyLayoutPresentation;
import org.eclipse.osbp.ecview.extension.model.YStrategyLayout;
import org.eclipse.osbp.runtime.common.keystroke.KeyStrokeCallback;
import org.eclipse.osbp.runtime.common.keystroke.KeyStrokeDefinition;
import org.eclipse.osbp.runtime.web.ecview.presentation.vaadin.IConstants;
import org.eclipse.osbp.runtime.web.ecview.presentation.vaadin.common.AbstractEmbeddedWidgetPresenter;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.vaadin.event.ActionManager;
import com.vaadin.event.ShortcutListener;
import com.vaadin.ui.AbstractComponent;
import com.vaadin.ui.Component;
import com.vaadin.ui.Panel;
import com.vaadin.ui.VerticalLayout;

/**
 * This presenter is responsible to render a text field on the given layout.
 */
public class StrategyLayoutPresentation extends
		AbstractEmbeddedWidgetPresenter<Panel> implements
		IStrategyLayoutPresentation<Panel> {

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

	/** The root panel. */
	private Panel rootPanel;
	
	/** The root layout. */
	private VerticalLayout rootLayout;
	
	/** The model access. */
	private ModelAccess modelAccess;

	/** The content editpart. */
	private IEmbeddableEditpart contentEditpart;

	/** The callbacks. */
	private Map<KeyStrokeCallback, ShortcutListener> callbacks;

	/**
	 * The constructor.
	 * 
	 * @param editpart
	 *            The editpart of that editpart.
	 */
	public StrategyLayoutPresentation(IElementEditpart editpart) {
		super((IStrategyLayoutEditpart) editpart);
		this.modelAccess = new ModelAccess(
				(YStrategyLayout) 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 layout
	 * and added to it again afterwards.
	 */
	protected void refreshUI() {
		rootLayout.removeAllComponents();

		if (contentEditpart != null) {
			Component contentComp = (Component) contentEditpart
					.render(rootLayout);
			rootLayout.addComponent(contentComp);
		}
	}

	/* (non-Javadoc)
	 * @see org.eclipse.osbp.ecview.extension.editparts.presentation.IStrategyLayoutPresentation#registerKeyStroke(org.eclipse.osbp.ecview.core.common.editpart.IKeyStrokeDefinitionEditpart, org.eclipse.osbp.runtime.common.keystroke.KeyStrokeCallback)
	 */
	@SuppressWarnings("serial")
	@Override
	public void registerKeyStroke(
			IKeyStrokeDefinitionEditpart keyStrokeDefEditpart,
			final KeyStrokeCallback callback) {

		if (callbacks != null && callbacks.containsKey(callback)) {
			return;
		}

		KeyStrokeDefinition def = keyStrokeDefEditpart.getDefinition();
		ShortcutListener listener = new ShortcutListener(def.getCaption(),
				def.getKeyCode(), def.getModifierKeys()) {
			@Override
			public void handleAction(Object sender, Object target) {
				callback.callback(sender, target);
			}
		};

		if (callbacks == null) {
			callbacks = new HashMap<KeyStrokeCallback, ShortcutListener>();
		}
		callbacks.put(callback, listener);

		if (isRendered()) {
			// TODO change me later when bug is fixed
			// visibility bug in Vaadin. 2 actionManager instances available
			// for add and remove.
			ActionManager manager = getActionManager();
			manager.addAction(listener);
		}
	}

	/* (non-Javadoc)
	 * @see org.eclipse.osbp.ecview.extension.editparts.presentation.IStrategyLayoutPresentation#unregisterKeyStroke(org.eclipse.osbp.runtime.common.keystroke.KeyStrokeCallback)
	 */
	@Override
	public void unregisterKeyStroke(KeyStrokeCallback callback) {
		ShortcutListener listener = callbacks.remove(callback);
		if (listener != null) {
			if (callbacks != null) {
				callbacks.remove(callback);
			}
			if (isRendered()) {
				// TODO change me later when bug is fixed
				// visibility bug in Vaadin. 2 actionManager instances available
				// for add and remove.
				ActionManager manager = getActionManager();
				manager.removeAction(listener);
			}
		}
	}

	/**
	 * Temporary for Vaadin bug.
	 *
	 * @return the action manager
	 */
	protected ActionManager getActionManager() {
		ActionManager actionManager = null;
		try {
			Method m = AbstractComponent.class.getDeclaredMethod(
					"getActionManager", new Class[0]);
			if (!m.isAccessible()) {
				m.setAccessible(true);
			}
			actionManager = (ActionManager) m.invoke(rootPanel, new Object[0]);
		} catch (NoSuchMethodException e) {
			LOGGER.error("{}", e);
		} catch (IllegalAccessException e) {
			LOGGER.error("{}", e);		
		} catch (InvocationTargetException e) {
				LOGGER.error("{}", e);		}
		return actionManager;
	}

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

			associateWidget(rootLayout, modelAccess.yLayout);

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

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

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

			if (modelAccess.isCssClassValid()) {
				rootLayout.addStyleName(modelAccess.getCssClass());
			} else {
				rootLayout.addStyleName(CSS_CLASS_CONTROL);
			}
			rootLayout.addStyleName(IConstants.CSS_CLASS_HORIZONTALLAYOUT);

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

			// activate callbacks
			if (callbacks != null) {
				ActionManager manager = getActionManager();
				for (ShortcutListener listener : callbacks.values()) {
					manager.addAction(listener);
				}
			}

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

		return rootPanel;
	}

	/* (non-Javadoc)
	 * @see org.eclipse.osbp.ecview.extension.editparts.presentation.IStrategyLayoutPresentation#setContent(org.eclipse.osbp.ecview.core.common.editpart.IEmbeddableEditpart)
	 */
	@Override
	public void setContent(IEmbeddableEditpart contentEditpart) {
		if (this.contentEditpart == contentEditpart) {
			return;
		}

		if (this.contentEditpart != null) {
			this.contentEditpart.requestUnrender();
		}

		this.contentEditpart = contentEditpart;

		if (isRendered() && this.contentEditpart != null) {
			refreshUI();
		}
	}

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

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

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

			if (callbacks != null) {
				callbacks.clear();
				callbacks = null;
			}
		} finally {
			super.internalDispose();
		}
	}

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

			// unbind all active bindings
			unbind();

			// remove assocations
			unassociateWidget(rootPanel);

			// unrender the children
			unrenderContent();

			if (callbacks != null) {
				ActionManager manager = getActionManager();
				for (ShortcutListener listener : callbacks.values()) {
					manager.removeAction(listener);
				}
			}

			rootLayout.removeAllComponents();
			rootPanel = null;
			rootLayout = null;
		}
	}

	/**
	 * Render children.
	 *
	 * @param force
	 *            the force
	 */
	public void renderChildren(boolean force) {
		if (force) {
			unrenderContent();
		}

		refreshUI();
	}

	/**
	 * Will unrender the content.
	 */
	protected void unrenderContent() {
		if (contentEditpart != null && contentEditpart.isRendered()) {
			contentEditpart.requestUnrender();
		}
	}

	/**
	 * An internal helper class.
	 */
	private static class ModelAccess {
		
		/** The y layout. */
		private final YStrategyLayout yLayout;

		/**
		 * Instantiates a new model access.
		 *
		 * @param yLayout
		 *            the y layout
		 */
		public ModelAccess(YStrategyLayout 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.YStrategyLayout#isSpacing()
		 */
		public boolean isSpacing() {
			return false;
		}

		/**
		 * 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.YStrategyLayout#isMargin()
		 */
		public boolean isMargin() {
			return false;
		}
	}

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