/*******************************************************************************
 * 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 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:
 *     Rushan R. Gilmullin - initial API and implementation
 *******************************************************************************/

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

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

import org.eclipse.e4.core.services.events.IEventBroker;
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.MUILabel;
import org.eclipse.e4.ui.model.application.ui.SideValue;
import org.eclipse.e4.ui.model.application.ui.advanced.MPerspective;
import org.eclipse.e4.ui.model.application.ui.advanced.MPerspectiveStack;
import org.eclipse.e4.ui.model.application.ui.advanced.MPlaceholder;
import org.eclipse.e4.ui.model.application.ui.basic.MPart;
import org.eclipse.e4.ui.model.application.ui.basic.MPartStack;
import org.eclipse.e4.ui.model.application.ui.basic.MTrimBar;
import org.eclipse.e4.ui.model.application.ui.basic.MWindow;
import org.eclipse.e4.ui.model.application.ui.menu.MToolBar;
import org.eclipse.e4.ui.workbench.IPresentationEngine;
import org.eclipse.e4.ui.workbench.UIEvents;
import org.eclipse.e4.ui.workbench.modeling.EModelService;
import org.eclipse.e4.ui.workbench.modeling.EPartService;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.osbp.vaaclipse.api.Behaviour;
import org.eclipse.osbp.vaaclipse.presentation.widgets.TrimmedWindowContent;
import org.eclipse.osbp.vaaclipse.widgets.FastView;
import org.osgi.service.event.EventHandler;

import com.vaadin.event.MouseEvents.ClickEvent;
import com.vaadin.event.MouseEvents.ClickListener;
import com.vaadin.ui.Component;
import com.vaadin.ui.Panel;
import com.vaadin.ui.UI;
import com.vaadin.ui.VerticalLayout;

/**
 * @author rushan
 *
 */
public class SingleElementFastViewManager {

	@Inject
	UI vaadinUI;

	@Inject
	Behaviour behaviour;

	@Inject
	MUIElement minimizedElement;
	@Inject
	MTrimBar trimBar;
	@Inject
	MToolBar toolBar;

	private MWindow window;
	private Panel vaadinWindow;

	// --------------------------------------------
	// --------------------------------------------

	private static final String STATE_XSIZE = "XSize"; //$NON-NLS-1$

	private static final String STATE_YSIZE = "YSize"; //$NON-NLS-1$

	private boolean isShowing = false;
	private FastView hostPane;

	@Inject
	EModelService modelService;

	@Inject
	EPartService partService;

	@Inject
	protected IEventBroker eventBroker;

	/**
	 * This is the old way to subscribe to UIEvents. You should consider using
	 * the new way as shown by handleTransientDataEvents() and described in the
	 * article at http://wiki.eclipse.org/Eclipse4/RCP/Event_Model
	 */
	private EventHandler closeHandler = new EventHandler() {
		public void handleEvent(org.osgi.service.event.Event event) {
			if (!isShowing)
				return;

			// The only time we don't close is if I've selected my tab.
			MUIElement changedElement = (MUIElement) event
					.getProperty(UIEvents.EventTags.ELEMENT);

			// Perspective changed, close the visible stacks
			if (changedElement instanceof MPerspectiveStack) {
				showStack(false);
				return;
			}

			if (changedElement == getLeafPart(minimizedElement)) {
				fixToolItemSelection(changedElement);
				return;
			}

			showStack(false);
		}
	};

	private void fixToolItemSelection(MUIElement element) {
		// TODO: implement correctly this method
		// if (trimStackTB == null || trimStackTB.isDisposed())
		// return;
		//
		// if (isEditorStack()) {
		// trimStackTB.getItem(1).setSelection(element != null);
		// if (element != null)
		// trimStackTB.getItem(1).setData(element);
		// } else if (isPerspectiveStack()) {
		// for (ToolItem item : trimStackTB.getItems()) {
		// boolean result = item.getData() == null ? false : item.getData() ==
		// element;
		// item.setSelection(result);
		// }
		// } else {
		// for (ToolItem item : trimStackTB.getItems()) {
		// boolean result = item.getData() == null ? false : item.getData() ==
		// element;
		// item.setSelection(result);
		// }
		// }

	}

	private boolean isEditorStack() {
		return minimizedElement instanceof MPlaceholder;
	}

	private boolean isPerspectiveStack() {
		return minimizedElement instanceof MPerspectiveStack;
	}

	private MPart getLeafPart(MUIElement element) {
		if (element instanceof MPlaceholder)
			return getLeafPart(((MPlaceholder) element).getRef());

		if (element instanceof MElementContainer<?>)
			return getLeafPart(((MElementContainer<?>) element)
					.getSelectedElement());

		if (element instanceof MPart)
			return (MPart) element;

		return null;
	}

	private EventHandler openHandler = new EventHandler() {

		public void handleEvent(org.osgi.service.event.Event event) {
			if (isShowing)
				return;

			MPerspective currentPerspective = modelService
					.getPerspectiveFor(minimizedElement);
			MPerspective activePerspective = modelService
					.getActivePerspective(window);

			if (currentPerspective != activePerspective)
				return;

			MPart changedElement = (MPart) event
					.getProperty(UIEvents.EventTags.ELEMENT);

			// Open if shared area
			if (getLeafPart(minimizedElement) == changedElement) {
				showStack(true);
				return;
			}

			MUIElement selectedElement = null;

			if (minimizedElement instanceof MPlaceholder) {
				selectedElement = ((MPlaceholder) minimizedElement).getRef();
			} else if (minimizedElement instanceof MPartStack) {
				selectedElement = ((MPartStack) minimizedElement)
						.getSelectedElement();
			}

			if (selectedElement == null)
				return;

			if (selectedElement instanceof MPlaceholder)
				selectedElement = ((MPlaceholder) selectedElement).getRef();

			if (changedElement != selectedElement)
				return;

			showStack(true);
		}
	};

	/**
	 * This is the old way to subscribe to UIEvents. You should consider using
	 * the new way as shown by handleTransientDataEvents() and described in the
	 * article at http://wiki.eclipse.org/Eclipse4/RCP/Event_Model
	 */
	private EventHandler toBeRenderedHandler = new EventHandler() {
		public void handleEvent(org.osgi.service.event.Event event) {
			if (minimizedElement == null || trimBar == null)
				return;

			MUIElement changedElement = (MUIElement) event
					.getProperty(UIEvents.EventTags.ELEMENT);

			// if our stack is going away, so should we
			if (changedElement == minimizedElement
					&& !minimizedElement.isToBeRendered()) {
				if (hostPane != null)
					vaadinUI.removeWindow(hostPane);
				hostPane = null;
				return;
			}
		}
	};

	@PostConstruct
	void postConstruct() {

		if (window == null)
			window = (MWindow) (trimBar.getParent() != null ? (MElementContainer<?>) trimBar
					.getParent() : ((EObject) trimBar).eContainer());
		vaadinWindow = (Panel) window.getWidget();

		eventBroker.subscribe(UIEvents.UIElement.TOPIC_TOBERENDERED,
				toBeRenderedHandler);
		eventBroker.subscribe(UIEvents.UILifeCycle.BRINGTOTOP, openHandler);
		eventBroker.subscribe(UIEvents.UILifeCycle.ACTIVATE, closeHandler);
	}

	void dispose() {
		showStack(false);

		eventBroker.unsubscribe(toBeRenderedHandler);
		eventBroker.unsubscribe(openHandler);
		eventBroker.unsubscribe(closeHandler);
	}

	/**
	 * This is the old way to subscribe to UIEvents. You should consider using
	 * the new way as shown by handleTransientDataEvents() and described in the
	 * article at http://wiki.eclipse.org/Eclipse4/RCP/Event_Model
	 */
	@PreDestroy
	void removeListeners() {
		eventBroker.unsubscribe(openHandler);
		eventBroker.unsubscribe(closeHandler);
	}

	private String getLabelText(MUILabel label) {
		// Use override text if available
		if (label instanceof MUIElement) {
			String text = getOverrideTitleToolTip((MUIElement) label);
			if (text != null)
				return text;
		}

		String string = label.getLabel();
		return string == null ? "" : string; //$NON-NLS-1$
	}

	private String getOverrideTitleToolTip(MUIElement element) {
		String result = null;

		Object stringObject = element.getTransientData().get(
				IPresentationEngine.OVERRIDE_TITLE_TOOL_TIP_KEY);
		if (stringObject != null && stringObject instanceof String)
			result = (String) stringObject;

		return result;
	}

	private MUILabel getLabelElement(MUIElement element) {
		if (element instanceof MPlaceholder)
			element = ((MPlaceholder) element).getRef();

		return (MUILabel) (element instanceof MUILabel ? element : null);
	}

	/**
	 * Create the popup menu that will appear when a minimized part has been
	 * selected by the cursor.
	 */
	// private void createPopupMenu() {
	// trimStackMenu = new Menu(trimStackTB);
	// trimStackTB.setMenu(trimStackMenu);
	//
	// MenuItem closeItem = new MenuItem(trimStackMenu, SWT.NONE);
	// closeItem.setText(Messages.TrimStack_CloseText);
	// closeItem.addListener(SWT.Selection, new Listener() {
	// public void handleEvent(Event event) {
	// partService.hidePart((MPart) selectedToolItem.getData());
	// }
	// });
	// }

	ClickListener layoutClickListener = new ClickListener() {

		@Override
		public void click(ClickEvent event) {
			if (isShowing)
				showStack(false);
			partService.requestActivation();
		}
	};

	public synchronized void showStack(boolean show) {
		Component ctf = (Component) minimizedElement.getWidget();

		if (show && !isShowing) {
			hostPane = getHostPane();
			VerticalLayout vl = new VerticalLayout();
			vl.setSizeFull();
			hostPane.setContent(vl);

			ctf.setVisible(true);

			TrimmedWindowContent windowContent = (TrimmedWindowContent) vaadinWindow
					.getContent();
			VerticalLayout clientArea = windowContent.getClientArea();

			hostPane.setTrimmedWindowClientArea(clientArea);
			// hostPane.setContent(ctf);
			vl.addComponent(ctf);

			vaadinUI.addWindow(hostPane);
			vaadinWindow.addClickListener(layoutClickListener);

			isShowing = true;
		} else if (!show && isShowing) {
			if (hostPane != null) {
				vaadinUI.removeWindow(hostPane);
				// capture the current shell's bounds
				toolBar.getPersistedState().put(STATE_XSIZE,
						Float.toString(Float.valueOf(hostPane.getWidth())));
				toolBar.getPersistedState().put(STATE_YSIZE,
						Float.toString(Float.valueOf(hostPane.getHeight())));
			}

			fixToolItemSelection(null);

			vaadinWindow.removeClickListener(layoutClickListener);

			partService.requestActivation();

			isShowing = false;
		}
	}

	private FastView getHostPane() {
		if (hostPane != null)
			return hostPane;

		// Create one
		hostPane = new FastView();
		hostPane.setSide(trimBar.getSide().getValue());
		hostPane.setClosable(false);
		hostPane.setDraggable(false);
		if (trimBar.getSide() == SideValue.RIGHT)
			hostPane.setResizable(false);
		// hostPane.setResizeLazy(true);
		hostPane.setStyleName("loading-window");

		// TODO: implement closing by esc
		// hostPane.addListener(SWT.Traverse, new Listener() {
		// public void handleEvent(Event event) {
		// if (event.character == SWT.ESC) {
		// partService.requestActivation();
		// }
		// }
		// });

		return hostPane;
	}

}
