/**
 ********************************************************************************
 * Copyright (c) 2017-2020 Robert Bosch GmbH.
 * 
 * This program and the accompanying materials are made
 * available under the terms of the Eclipse Public License 2.0
 * which is available at https://www.eclipse.org/legal/epl-2.0/
 * 
 * SPDX-License-Identifier: EPL-2.0
 * 
 * Contributors:
 *     Robert Bosch GmbH - initial API and implementation
 ********************************************************************************
 */

package org.eclipse.app4mc.emf.viewer.plantuml.views;

import java.util.ArrayDeque;
import java.util.Arrays;
import java.util.Deque;
import java.util.HashMap;
import java.util.Map;

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

import org.eclipse.app4mc.emf.viewer.plantuml.handlers.AbstractPlantUMLHandler;
import org.eclipse.app4mc.emf.viewer.plantuml.handlers.EClassAllReferencesHandler;
import org.eclipse.app4mc.emf.viewer.plantuml.handlers.EClassContentsAndHierarchyHandler;
import org.eclipse.app4mc.emf.viewer.plantuml.handlers.EClassContentsFromReferenceHandler;
import org.eclipse.app4mc.emf.viewer.plantuml.handlers.EClassHierarchyHandler;
import org.eclipse.app4mc.emf.viewer.plantuml.handlers.EObjectRefsHandler;
import org.eclipse.app4mc.emf.viewer.plantuml.handlers.ObjectContentHandler;
import org.eclipse.app4mc.emf.viewer.plantuml.preferences.PreferenceConstants;
import org.eclipse.app4mc.emf.viewer.plantuml.utils.ExecutionCategory;
import org.eclipse.app4mc.emf.viewer.plantuml.utils.ExecutionUtil;
import org.eclipse.e4.core.di.annotations.Optional;
import org.eclipse.e4.core.di.extensions.Preference;
import org.eclipse.e4.core.services.events.IEventBroker;
import org.eclipse.e4.ui.di.Focus;
import org.eclipse.e4.ui.di.PersistState;
import org.eclipse.e4.ui.di.UISynchronize;
import org.eclipse.e4.ui.model.application.ui.basic.MPart;
import org.eclipse.e4.ui.model.application.ui.menu.MDirectToolItem;
import org.eclipse.e4.ui.model.application.ui.menu.MToolBarElement;
import org.eclipse.e4.ui.services.IServiceConstants;
import org.eclipse.e4.ui.workbench.modeling.EPartService;
import org.eclipse.emf.common.util.EList;
import org.eclipse.emf.ecore.EClass;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.swt.SWT;
import org.eclipse.swt.browser.Browser;
import org.eclipse.swt.browser.LocationAdapter;
import org.eclipse.swt.browser.LocationEvent;
import org.eclipse.swt.events.KeyAdapter;
import org.eclipse.swt.events.KeyEvent;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Shell;

import net.sourceforge.plantuml.eclipse.utils.PlantumlConstants;

@SuppressWarnings("restriction")
public class DiagramView {
	
	/**
	 * The ID of the view.
	 */
	public static final String ID = "org.eclipse.app4mc.emf.viewer.plantuml.views.DiagramView";

	private static final String LINKED_KEY = "LINKED_WITH_EDITOR";
	
	private boolean linkedWithEditor = false;

	private Browser browser;

	final HashMap<String, Object> idObjectsMap = new HashMap<>();

	@Inject
	Shell shell;
	
	@Inject
	UISynchronize sync;

	@Inject
	EPartService partService;
	
	@Inject
	IEventBroker broker;
	
	@Inject
	@Optional
	@Preference(
			nodePath = "net.sourceforge.plantuml.eclipse", 
			value = PlantumlConstants.GRAPHVIZ_PATH) 
	String dotPath;
	
	@Inject
	@Optional
	@Preference(
			nodePath = "org.eclipse.app4mc.emf.viewer.plantuml", 
			value = PreferenceConstants.P_FOLDER_PATH) 
	String genFolderPath;
	
	private Deque<String> history = new ArrayDeque<>();
	
	/**
	 * This is a callback that will allow us to create the viewer and initialize it.
	 */
	@PostConstruct
	public void createPartControl(Composite parent, MPart part) {
		Map<String, String> state = part.getPersistedState();
	    String value = state.get(LINKED_KEY);
	    this.linkedWithEditor = value != null && Boolean.valueOf(value);
	    
		this.browser = new Browser(parent, SWT.None);
		this.browser.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));

		this.browser.addKeyListener(new KeyAdapter() {
			
			@Override
			public void keyPressed(KeyEvent e) {
				if (e.character == '\b' && !history.isEmpty()) {
					String previous = history.pop();
					if (previous != null) {
						
						// extract ID from URL
						int lastIndexOf = previous.lastIndexOf('/');

						String id = "";
						if (lastIndexOf != -1) {
							id = previous.substring(lastIndexOf + 1, previous.lastIndexOf('.'));
						}

						// get object of the previous view
						Object eObject = idObjectsMap.get(id);
						if (eObject != null && isLinkedWithEditor()) {
							if (eObject instanceof EClass) {
								updateDiagram((eObject), null);
							} else if (eObject instanceof EObject) {
								updateDiagram(((EObject) eObject).eClass(), (EObject) eObject);
							}
							selectInEditor(eObject);
							
							e.doit = false;
						}
					}
				}
			}
		});
		
		this.browser.addLocationListener(new LocationAdapter() {
			
			@Override
			public void changing(LocationEvent event) {
				String location = event.location;
				if (!location.endsWith(".svg")) {
					int lastIndexOf = location.lastIndexOf('/');

					String id = "";
					if (lastIndexOf != -1) {
						id = location.substring(lastIndexOf + 1, location.length());
					}
				
					Object eObject = idObjectsMap.get(id);
					if (eObject != null) {
						if (eObject instanceof EClass) {
							updateDiagram((eObject), null);
						} else if (eObject instanceof EObject) {
							updateDiagram(((EObject) eObject).eClass(), (EObject) eObject);
						} else if (eObject instanceof EList<?>) {
							// we pass the eObject which is a EList so the ObjectContentHandler can handle the EList special case
							updateDiagram(eObject, null);
						}
						if (isLinkedWithEditor()) {
							selectInEditor(eObject);
						}
					}
				
					event.doit = false;
				}
			}
		});
	}
	
	@Inject
	@Optional
	void handleSelection(@Named(IServiceConstants.ACTIVE_SELECTION) IStructuredSelection selection) {
		if (isLinkedWithEditor() && selection != null && !selection.isEmpty()) {
			Object firstElement = selection.getFirstElement();
			if (firstElement instanceof EObject) {
				updateDiagram(((EObject)firstElement).eClass(), (EObject)firstElement);
			}
		}
	}
	
	private void updateDiagram(Object eClass, EObject eObject) {

		Object selected = eClass;
		
		/*
		 * Regeneration of SVG Buffer for populating content specific to the selection
		 */

		AbstractPlantUMLHandler handler = null;
		if (ExecutionUtil.isExecuting(ExecutionCategory.eClassHierarchy)) {
			handler = new EClassHierarchyHandler();
		} else if (ExecutionUtil.isExecuting(ExecutionCategory.eClassContentsAndHierarchy)) {
			handler = new EClassContentsAndHierarchyHandler();
		} else if (ExecutionUtil.isExecuting(ExecutionCategory.eClassAllReferences)) {
			handler = new EClassAllReferencesHandler();
		} else if (ExecutionUtil.isExecuting(ExecutionCategory.eClassContentsFromReference)) {
			handler = new EClassContentsFromReferenceHandler();
		} else if (ExecutionUtil.isExecuting(ExecutionCategory.eObjectRefs)) {
			handler = new EObjectRefsHandler();
			if (eObject != null) {
				// if the eObject is not null we use this for the visualization, otherwise maybe a collection was selected
				selected = eObject;
			}
		} else {
			/*- EClassContents and EObjectRefs behaviour is included in ObjectContentBuilder java class */
			handler = new ObjectContentHandler();
			if (eObject != null) {
				// if the eObject is not null we use this for the visualization, otherwise maybe a collection was selected
				selected = eObject;
			}
		}
		
		handler.execute(shell, sync, dotPath, genFolderPath, partService, selected, eObject);
	}
	
	/**
	 * This method is used to select specified AMALTHEA element in the Sphinx editor
	 *
	 * @param element
	 */
	private void selectInEditor(Object element) {
		HashMap<String, Object> data = new HashMap<>();
		data.put("modelElements", Arrays.asList(element));
		broker.send("org/eclipse/app4mc/amalthea/editor/SELECT", data);
	}
	
	@Focus
	public void setFocus(MPart activePart) {
		for (MToolBarElement element : activePart.getToolbar().getChildren()) {
			if (element.getElementId().equals("org.eclipse.app4mc.emf.viewer.plantuml.directtoolitem.select")) {
				MDirectToolItem toolItem = (MDirectToolItem) element;
				toolItem.setSelected(linkedWithEditor);
			}
		}
	}

	@PersistState
	public void persistState(MPart part) {
	    Map<String, String> state = part.getPersistedState();
	    state.put(LINKED_KEY, Boolean.toString(linkedWithEditor));
	}
	
	public boolean isLinkedWithEditor() {
		return this.linkedWithEditor;
	}
	
	public void setLinkedWithEditor(boolean linked) {
		this.linkedWithEditor = linked;
	}
	
	public void showDiagram(String fileNamePrefix, Object element, String svgPath, Map<String, Object> id2ObjectsMap) {
		if (this.browser != null && !this.browser.isDisposed()) {
			if (element != null) {
				this.idObjectsMap.put(fileNamePrefix, element);
			}
			this.idObjectsMap.putAll(id2ObjectsMap);
			this.history.add(browser.getUrl());
			this.browser.setUrl(svgPath);
		}
	}
}
