/**
 * Copyright (c) 2018 CEA.
 * 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:
 *     CEA - initial API and implementation and/or initial documentation
 */
package org.eclipse.sensinact.studio.view.outdoor;

import java.util.Arrays;
import java.util.List;

import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;

import org.apache.log4j.Logger;
import org.eclipse.jface.dialogs.MessageDialog;
import org.eclipse.sensinact.studio.http.server.GatewayHttpServer;
import org.eclipse.sensinact.studio.http.server.serverstarted.PortUpdate;
import org.eclipse.sensinact.studio.http.server.serverstarted.ResourceAddedUpdate;
import org.eclipse.sensinact.studio.http.server.serverstarted.ServerUpdatedListener;
import org.eclipse.sensinact.studio.http.server.serverstarted.ServerUpdatedManager;
import org.eclipse.sensinact.studio.http.server.serverstarted.UpdateDescriptor;
import org.eclipse.sensinact.studio.model.manager.listener.devicelocation.DeviceLocationListener;
import org.eclipse.sensinact.studio.model.manager.listener.devicelocation.DeviceLocationManager;
import org.eclipse.sensinact.studio.model.resource.utils.DeviceDescriptor;
import org.eclipse.sensinact.studio.model.resource.utils.GPScoordinates;
import org.eclipse.sensinact.studio.preferences.ConfigurationManager;
import org.eclipse.sensinact.studio.webapp.outdoor.Startup;
import org.eclipse.swt.SWT;
import org.eclipse.swt.browser.Browser;
import org.eclipse.swt.browser.ProgressEvent;
import org.eclipse.swt.browser.ProgressListener;
import org.eclipse.swt.dnd.DND;
import org.eclipse.swt.dnd.DropTarget;
import org.eclipse.swt.dnd.DropTargetEvent;
import org.eclipse.swt.dnd.DropTargetListener;
import org.eclipse.swt.dnd.TextTransfer;
import org.eclipse.swt.dnd.Transfer;
import org.eclipse.swt.events.ControlEvent;
import org.eclipse.swt.events.ControlListener;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.ui.PlatformUI;

/**
 * @author Nicolas Hili, Etienne Gandrille
 */
public class OutdoorDeploymentView implements ServerUpdatedListener, DeviceLocationListener {

	private static final Logger logger = Logger.getLogger(OutdoorDeploymentView.class);
	
	public static final String VIEW_ID = "org.eclipse.sensinact.studio.view.outdoor.view";
	
	private static Browser browser;
	private int studioPort = 0;
	private static Composite dndComposite;
	private static Shell dndShell;

	private static boolean browserStarted = false;

	public OutdoorDeploymentView() {
		// stats server
		GatewayHttpServer.getInstance();
	}

	@PostConstruct
	public void createControls(final Composite parent) {
		parent.setLayout(null);
		parent.setLayoutData(new GridData(SWT.LEFT, SWT.TOP, true, true, 1, 1));
		browser = new Browser(parent, SWT.NONE);
		
		// Invisible shell and composite for Drag'n Drop feature
		dndShell = new Shell(Display.getCurrent(), SWT.ON_TOP);
		dndShell.open();
		dndShell.setAlpha(125);
		dndShell.setVisible(false);
		dndComposite = new Composite(dndShell, SWT.NO_BACKGROUND);
		dndComposite.setVisible(false);

		// updates device position on the map
		DeviceLocationManager.getInstance().addDeviceLocationListener(this);

		// swap browserStarted flag to true when browser is ready
		browser.addProgressListener(new BrowserProgressListener());

		// updates dnd elements when browser (more precisely, parent) geometry
		// changes
		parent.addControlListener(new ControlSizePositionListener(parent));

		// drop target configuration
		int operations = DND.DROP_MOVE | DND.DROP_COPY | DND.DROP_DEFAULT;
		Transfer[] transferTypes = new Transfer[] { TextTransfer.getInstance() };
		DropTarget target = new DropTarget(dndComposite, operations);
		target.setTransfer(transferTypes);

		// when a device is dropped, updates its location
		target.addDropListener(new DropListenerForDevices());

		// when the server parameters are updated, the browser URL also
		ServerUpdatedManager.getInstance().addServerUpdatedListener(this);
		serverUpdated(null);
	}

	@PreDestroy
	public void dispose() {
		ServerUpdatedManager.getInstance().removeServerUpdatedListener(this);
	}

	public static void beginDrag() {
		if (browserStarted) {
			dndShell.setVisible(true);
			dndComposite.setVisible(true);
			updateDndInvisibleElementsGeometry();
		}
	}

	public static void endDrag() {
		dndShell.setVisible(false);
		dndComposite.setVisible(false);
	}

	private static void updateDndInvisibleElementsGeometry() {
		Point absolutePos = browser.toDisplay(0, 0);
		dndShell.setBounds(absolutePos.x, absolutePos.y, browser.getBounds().width, browser.getBounds().height);
		dndComposite.setBounds(0, 0, browser.getBounds().width, browser.getBounds().height);
	}

	/* ============== */
	/* DeviceLocation */
	/* ============== */

	@Override
	public void deviceLocationUpdated(final GPScoordinates coordinate, final DeviceDescriptor descriptor) {
		
		System.out.println("before!!");
		Display.getDefault().asyncExec(new Runnable() {

			@Override
			public void run() {
				String dev = "'" + descriptor.toString() + "'";
				String cmd = "updateDeviceLocation(" + coordinate.getLat() + "," + coordinate.getLng() + "," + dev + ");";
				System.out.println(cmd);
				browser.execute(cmd);
			}
		});
		System.out.println("after!!");
		
		
	}

	@Override
	public void deviceRemoved(final DeviceDescriptor descriptor) {
		Display.getDefault().asyncExec(new Runnable() {
			@Override
			public void run() {
				String dev = "'" + descriptor.toString() + "'";
				browser.execute("deleteMarker(" + dev + ");");
			}
		});
	}

	/* =========================== */
	/* Gateway HTTP ServerListener */
	/* =========================== */

	@Override
	public void serverUpdated(UpdateDescriptor descriptor) {
		if (isUpdateNeeded(descriptor)) {
			studioPort = ConfigurationManager.getStudioPort();
			if (studioPort != 0) {
				Display.getDefault().asyncExec(new Runnable() {
					public void run() {
						logger.debug("refresh browser");
						browser.setUrl("http://localhost:" + studioPort + "/webapp/outdoor/static/outdoor.html");
					}
				});
			}
		}
	}

	private boolean isUpdateNeeded(UpdateDescriptor descriptor) {

		if (descriptor == null) {
			// server just started
			return true;
		} else {
			switch (descriptor.getType()) {
			case PORT_UPDATE:
				PortUpdate pu = (PortUpdate) descriptor;
				if (pu.getPort() != 0)
					return true;
				else
					return false;
			case RESOURCE_ADDED:
				ResourceAddedUpdate ra = (ResourceAddedUpdate) descriptor;
				List<String> paths = ra.getRegisteredPath();

				if (! Arrays.asList(Startup.BUNDLE_PATHS).contains(ra.getCurPath()))
					return false;
				
				for (String bundlePath : Startup.BUNDLE_PATHS) {
					if (!paths.contains(bundlePath))
						return false;
				}
				return true;
			default:
				throw new RuntimeException("Should never happend (" + descriptor.getType() + ")");
			}
		}
	}

	/* ================= */
	/* Control listeners */
	/* ================= */

	private final class BrowserProgressListener implements ProgressListener {
		public void changed(ProgressEvent event) {
		}

		public void completed(ProgressEvent event) {
			browserStarted = true;
		}
	}

	private final class ControlSizePositionListener implements ControlListener {
		private final Composite parent;

		private ControlSizePositionListener(Composite parent) {
			this.parent = parent;
		}

		private void update(ControlEvent e) {
			browser.setBounds(0, 0, parent.getBounds().width, parent.getBounds().height);
			if (e.widget instanceof Control) {
				updateDndInvisibleElementsGeometry();
			}
		}

		@Override
		public void controlResized(ControlEvent e) {
			update(e);
		}

		@Override
		public void controlMoved(ControlEvent e) {
			update(e);
		}
	}

	private final class DropListenerForDevices implements DropTargetListener {
		@Override
		public void dragEnter(DropTargetEvent event) {
		}

		@Override
		public void dragLeave(DropTargetEvent event) {
		}

		@Override
		public void dragOperationChanged(DropTargetEvent event) {
		}

		@Override
		public void dragOver(DropTargetEvent event) {
		}

		@Override
		public void drop(DropTargetEvent event) {

			endDrag();

			if (TextTransfer.getInstance().isSupportedType(event.currentDataType)) {
				String dropText = (String) event.data;

				if (event.widget instanceof DropTarget) {					
					// Retrieve lat and lng
					Point relativePos = ((DropTarget) event.widget).getControl().toControl(event.x, event.y);
					String cmd1 = "return computeCoordinates(" + relativePos.x + "," + relativePos.y + ");";
					Object[] coordinates = (Object[]) browser.evaluate(cmd1);
					Double lat = (Double) coordinates[0];
					Double lng = (Double) coordinates[1];

					// Retrieve gateway and device
					String[] tab = dropText.split("/");
					String gateway = tab[0];
					if (gateway.startsWith("["))
						gateway = gateway.substring(1);
					String device = tab[1];
					
					// try to update on server
					boolean locationUpdated = DeviceLocationManager.getInstance().updateLocationInServer(new DeviceDescriptor(gateway, device), new GPScoordinates(lat, lng));
					
					if (locationUpdated) {
						String dev = "'" + gateway + "/" + device + "'";
						String cmd = "return updateDeviceLocation(" + lat + "," + lng + "," + dev + ");";
						System.out.println(cmd);
						browser.evaluate(cmd);
					} else {
						// DropTarget target = (DropTarget) event.getSource();
						// Shell shell = target.getControl().getShell();
						Shell shell = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getShell();						
						MessageDialog.openWarning(shell, "Error", "The location of " + device + " device is NOT updatable");
					}
				}
			}
		}

		@Override
		public void dropAccept(DropTargetEvent event) {
		}
	}
}
