/*******************************************************************************
 * Copyright (c) 2012 Rushan R. Gilmullin and others.
 * 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:
 *     Rushan R. Gilmullin - initial API and implementation
 *******************************************************************************/

package org.eclipse.osbp.vaaclipse.presentation.renderers;

import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Set;

import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
import javax.inject.Inject;

import org.eclipse.e4.core.di.annotations.Optional;
import org.eclipse.e4.core.services.events.IEventBroker;
import org.eclipse.e4.core.services.log.Logger;
import org.eclipse.e4.ui.model.application.ui.MElementContainer;
import org.eclipse.e4.ui.model.application.ui.MUIElement;
import org.eclipse.e4.ui.model.application.ui.basic.MPartSashContainer;
import org.eclipse.e4.ui.model.application.ui.basic.MPartSashContainerElement;
import org.eclipse.e4.ui.model.application.ui.basic.MWindow;
import org.eclipse.e4.ui.workbench.UIEvents;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.osbp.runtime.designer.api.IDesignerService;
import org.eclipse.osbp.runtime.designer.api.IDesignerService.IDesignListener;
import org.eclipse.osbp.runtime.designer.api.IWidgetDesignConfigurator;
import org.eclipse.osbp.vaaclipse.presentation.widgets.TrimmedWindowContent;
import org.eclipse.osbp.vaaclipse.publicapi.model.Tags;
import org.eclipse.osbp.vaaclipse.widgets.SashWidget;
import org.eclipse.osbp.vaaclipse.widgets.SashWidgetHorizontal;
import org.eclipse.osbp.vaaclipse.widgets.SashWidgetVertical;
import org.eclipse.osbp.vaaclipse.widgets.SplitPositionChangedListener;
import org.osgi.service.event.Event;
import org.osgi.service.event.EventHandler;

import com.vaadin.ui.AbstractComponent;
import com.vaadin.ui.AbstractSplitPanel;
import com.vaadin.ui.Component;
import com.vaadin.ui.ComponentContainer;
import com.vaadin.ui.Panel;
import com.vaadin.ui.VerticalLayout;

public class SashRenderer extends VaadinRenderer implements IDesignListener {

	@Inject
	IEventBroker eventBroker;

	@Inject
	Logger logger;

	@Inject
	@Optional
	private IDesignerService designerService;

	private boolean ignoreSashWeights = false;

	private EventHandler sashWeightHandler = new EventHandler() {
		public void handleEvent(Event event) {

			if (ignoreSashWeights)
				return;

			// Ensure that this event is for a MPartSashContainer
			MUIElement element = (MUIElement) event
					.getProperty(UIEvents.EventTags.ELEMENT);
			MElementContainer<MUIElement> parent = element.getParent();
			if (parent.getRenderer() != SashRenderer.this)
				return;

			MPartSashContainer sash = (MPartSashContainer) (MElementContainer<?>) element
					.getParent();
			setWeights(sash);
		}
	};

	private final EventHandler visibilityHandler = new EventHandler() {
		@Override
		public void handleEvent(Event event) {
			MUIElement changedElement = (MUIElement) event
					.getProperty(UIEvents.EventTags.ELEMENT);

			if ((MElementContainer<?>) changedElement.getParent() instanceof MPartSashContainer) {
				MPartSashContainer sash = (MPartSashContainer) (MElementContainer<?>) changedElement
						.getParent();

				if (sash.getRenderer() == null) {
					return;
				}

				((SashRenderer) sash.getRenderer()).refreshSashContainer(sash);

				boolean visible = false;
				for (MPartSashContainerElement child : sash.getChildren()) {
					if (child.isVisible()) {
						visible = true;
						break;
					}
				}
				if (sash.isVisible() != visible)
					sash.setVisible(visible);
			}
		}
	};

	private Set<MPartSashContainer> sashContainers = new HashSet<>();

	@Override
	public void createWidget(MUIElement element,
			MElementContainer<MUIElement> parent) {
		if (!(element instanceof MPartSashContainer)) {
			return;
		}
		VerticalLayout layout = new VerticalLayout();
		layout.setSizeFull();

		element.setWidget(layout);

		sashContainers.add((MPartSashContainer) element);

		if (designerService != null) {
			designerService.addListener(this);

			if (designerService.isDesignMode()) {
				updateDesigner(true);
			}
		}

	}

	@Override
	public void processContents(final MElementContainer<MUIElement> element) {
		refreshSashContainer((MPartSashContainer) (MElementContainer<?>) element);
	}

	public void generateSplitPanelStructure(MPartSashContainer sash) {
		VerticalLayout layout = (VerticalLayout) sash.getWidget();
		layout.removeAllComponents();

		ComponentContainer sashWidget = null;

		@SuppressWarnings("unchecked")
		List<MPartSashContainerElement> renderableAndVisible = (List<MPartSashContainerElement>) filterRenderableAndVisibleElements(sash);

		if (renderableAndVisible.isEmpty()) {
			sashWidget = new VerticalLayout();
		} else if (renderableAndVisible.size() == 1) {
			sashWidget = new VerticalLayout();
			MPartSashContainerElement child = renderableAndVisible.get(0);
			sashWidget.addComponent((Component) child.getWidget());
		} else {
			sashWidget = sash.isHorizontal() ? new SashWidgetHorizontal()
					: new SashWidgetVertical();
			AbstractSplitPanel currentSashWidget = (AbstractSplitPanel) sashWidget;
			currentSashWidget
					.setLocked(sash.getTags().contains(Tags.NO_RESIZE));
			for (int i = 0; i < renderableAndVisible.size(); i++) {
				MPartSashContainerElement child = renderableAndVisible.get(i);

				if (currentSashWidget.getFirstComponent() == null) {
					currentSashWidget.setFirstComponent((Component) child
							.getWidget());
				} else {
					if (i == renderableAndVisible.size() - 1) {
						currentSashWidget.setSecondComponent((Component) child
								.getWidget());
					} else {
						AbstractSplitPanel newSashWidget = sash.isHorizontal() ? new SashWidgetHorizontal()
								: new SashWidgetVertical();
						newSashWidget.setLocked(sash.getTags().contains(
								Tags.NO_RESIZE));
						newSashWidget.setFirstComponent((Component) child
								.getWidget());
						currentSashWidget.setSecondComponent(newSashWidget);
						currentSashWidget = newSashWidget;
					}
				}
			}
		}

		sashWidget.setSizeFull();
		layout.addComponent(sashWidget);

		setWeights(sash);
	}

	@Override
	public void notify(IDesignerService.DesignEvent event) {
		updateDesigner(event.getType() == IDesignerService.EventType.ENABLED);
	}

	private void updateDesigner(boolean enabled) {
		for (MPartSashContainer container : sashContainers) {
			for (MPartSashContainerElement child : container.getChildren()) {
				if (child.getWidget() != null && child.isToBeRendered()) {
					updateDesigner(enabled, child);
				}
			}
		}
	}

	private void updateDesigner(boolean enabled, MPartSashContainerElement child) {
		IWidgetDesignConfigurator designConfigurator = context
				.get(IWidgetDesignConfigurator.class);
		if (designConfigurator != null) {
			designConfigurator.configure(child.getWidget(), (EObject) child,
					enabled);
		}
	}

	void setWeights(MPartSashContainer sash) {
		@SuppressWarnings("unchecked")
		List<MPartSashContainerElement> renderableAndVisible = (List<MPartSashContainerElement>) filterRenderableAndVisibleElements(sash);
		if (renderableAndVisible.size() < 2)
			return;

		Map<MPartSashContainerElement, Double> weights = new HashMap<MPartSashContainerElement, Double>();
		Map<Component, MPartSashContainerElement> map = new HashMap<Component, MPartSashContainerElement>();
		double total_weight = 0;
		for (MPartSashContainerElement children : renderableAndVisible) {
			String data = children.getContainerData();
			double weight = parseContainerData(data);

			map.put((Component) children.getWidget(), children);
			weights.put(children, weight);
			total_weight += weight;
		}

		if (total_weight == 0.0) // all child elements has zero weight
			total_weight = 1.0;

		AbstractSplitPanel topSashWidget = (AbstractSplitPanel) ((VerticalLayout) sash
				.getWidget()).getComponent(0);
		AbstractSplitPanel currentSashWidget = topSashWidget;
		while (true) {
			MPartSashContainerElement e1 = map.get(currentSashWidget
					.getFirstComponent());
			// the first - is always element
			double w = weights.get(e1);
			double pos = (w / total_weight) * 100;
			currentSashWidget.setSplitPosition((float) pos);

			if (map.containsKey(currentSashWidget.getSecondComponent()))
				break;

			currentSashWidget = (AbstractSplitPanel) currentSashWidget
					.getSecondComponent();
			total_weight = total_weight - w;
		}
	}

	public void refreshSashContainer(MPartSashContainer sash) {

		// sashContainersMap.remove(sash);

		generateSplitPanelStructure(sash);
		addSplitPaneListener(sash);
	}

	@PostConstruct
	void postConstruct() {
		eventBroker.subscribe(UIEvents.UIElement.TOPIC_CONTAINERDATA,
				sashWeightHandler);
		eventBroker.subscribe(UIEvents.UIElement.TOPIC_VISIBLE,
				visibilityHandler);
		eventBroker.subscribe(UIEvents.ElementContainer.TOPIC_CHILDREN,
				childrenMoveUpdater);
	}

	@PreDestroy
	public void preDestroy() {

		if (designerService != null) {
			designerService.removeListener(this);
		}

		eventBroker.unsubscribe(sashWeightHandler);
		eventBroker.unsubscribe(visibilityHandler);
		eventBroker.unsubscribe(childrenMoveUpdater);
	}

	private EventHandler childrenMoveUpdater = new EventHandler() {
		public void handleEvent(Event event) {
			// Ensure that this event is for a MMenuItem
			if (!(event.getProperty(UIEvents.EventTags.ELEMENT) instanceof MPartSashContainer))
				return;

			MPartSashContainer sash = (MPartSashContainer) event
					.getProperty(UIEvents.EventTags.ELEMENT);
			String type = (String) event.getProperty(UIEvents.EventTags.TYPE);

			// on move, we unrender an render the UI again
			//
			if (UIEvents.EventTypes.MOVE.equals(type)) {
				// refreshSashContainer(sash);
			}
		}
	};

	@Override
	public void hookControllerLogic(MUIElement element) {
		// Controller logic is added in refreshSashContainer method. The widget
		// hierarchy regenerated on each add and remove gui,
		// so listeners must added each time when sash widget created
	}

	public void addSplitPaneListener(MUIElement element) {
		final MPartSashContainer sash = (MPartSashContainer) element;

		List<MPartSashContainerElement> renderableAndVisible = (List<MPartSashContainerElement>) filterRenderableAndVisibleElements(sash);

		if (renderableAndVisible.size() > 1) {
			for (MPartSashContainerElement child : renderableAndVisible) {
				Component childComponent = (Component) child.getWidget();
				if (childComponent.getParent() instanceof SashWidget) {
					SashWidget sashWidget = (SashWidget) childComponent
							.getParent();
					sashWidget.addListener(new SplitPositionChangedListener() {

						@Override
						public void processEvent(AbstractSplitPanel splitPanel,
								float newSplitPos) {
							AbstractComponent firstWidget = (AbstractComponent) splitPanel
									.getFirstComponent();

							// filter renderable and visible again (list can be
							// changed)
							List<MPartSashContainerElement> renderableAndVisible = (List<MPartSashContainerElement>) filterRenderableAndVisibleElements(sash);
							MPartSashContainerElement firstChild = null;
							double rest_weight = 0;
							List<MPartSashContainerElement> restChilds = new LinkedList<MPartSashContainerElement>();
							for (int i = 0; i < renderableAndVisible.size(); i++) {
								MPartSashContainerElement child = renderableAndVisible
										.get(i);
								if (firstWidget.equals(child.getWidget())) {
									firstChild = child;
								}

								if (firstChild != null) {
									try {
										double w = parseContainerData(child
												.getContainerData());
										rest_weight += w;
									} catch (NumberFormatException e) {
										logger.error("Changing weights of SashContainer's childs is failed. Can not parse children container data");
										return;
									}

									restChilds.add(child);
								}
							}

							if (restChilds.size() > 1) {
								// String debugstr = "weights: ";
								ignoreSashWeights = true;

								double rest_weight_except_first = rest_weight
										- parseContainerData(firstChild
												.getContainerData());
								double newW1 = (newSplitPos / 100)
										* rest_weight;
								double new_rest_weight_except_first = rest_weight
										- newW1;
								long longVal1 = Math.round(newW1);
								firstChild.setContainerData(Long
										.toString(longVal1));
								// debugstr += longVal1;

								// if the weight of remainder (except first) is
								// not zero, then we distribute the new space
								// appropriate weights
								if (rest_weight_except_first > 0.0) {
									for (int i = 1; i < restChilds.size(); i++) {
										MPartSashContainerElement child = restChilds
												.get(i);
										double w = parseContainerData(child
												.getContainerData());
										double newW = (w / rest_weight_except_first)
												* new_rest_weight_except_first;
										long longVal = Math.round(newW);

										child.setContainerData(Long
												.toString(longVal));
										// debugstr += ", " + longVal;
									}
								} else // otherwise we assign all new space to
										// the last component
								{
									MPartSashContainerElement rest1 = restChilds
											.get(restChilds.size() - 1);
									rest1.setContainerData(Long.toString(Math
											.round(new_rest_weight_except_first)));
								}

								ignoreSashWeights = false;

								// System.out.println(debugstr);

								// ATTENTION! Really line below is not required
								// if code above works correctly.
								// But if there are any wrong behaviour appear
								// then we have wrong synchronized state
								// that may caused side effects, so we do back
								// syncronization (and bug if it occur become
								// obvious).
								// This is also zeroed weight mismatch occuring
								// when double rounded (and possible when vaadin
								// process changes),
								// so we avoid mismatch accumulating.
								// Most likely in the future this will be
								// deleted (when this code will be proved that
								// all ok).
								setWeights(sash);
							} else {
								logger.error("Changing SashContainer child weights is failed. User changes is not processed correctly");
							}

							// and last thing what we must do - tell the
							// WorkbenchWindow to recalculate bounds of it
							// content
							// (because bounds of some content of workbench
							// window changed after sash widget split position
							// changed)
							MWindow window = modelService
									.getTopLevelWindowFor(sash);
							TrimmedWindowContent windowContent = (TrimmedWindowContent) ((Panel) window
									.getWidget()).getContent();
							windowContent.invalidateBounds();
						}
					});
				} else {
					logger.error("Error in  widget hierarchy detected - if sash container has more than one element its child widget must has SashWidget as a parent");
				}
			}
		}
	}

	private double parseContainerData(String containerData) {
		if (containerData == null)
			return 0.0d;

		containerData = containerData.trim();

		try {
			return Double.parseDouble(containerData);
		} catch (NumberFormatException e) {
			return 0.0d;
		}
	}

	@Override
	public void addChildGui(MUIElement child,
			MElementContainer<MUIElement> element) {
		if (!(child instanceof MPartSashContainerElement)
				|| !((MElementContainer<?>) element instanceof MPartSashContainer))
			return;

		refreshSashContainer((MPartSashContainer) (MElementContainer<?>) element);

		if (designerService != null && designerService.isDesignMode()) {
			updateDesigner(designerService.isDesignMode(),
					(MPartSashContainerElement) child);
		}
	}

	@Override
	public void removeChildGui(MUIElement child,
			MElementContainer<MUIElement> element) {
		if (!(child instanceof MPartSashContainerElement)
				|| !((MElementContainer<?>) element instanceof MPartSashContainer))
			return;

		refreshSashContainer((MPartSashContainer) (MElementContainer<?>) element);
	}
}
