package org.eclipse.osbp.utils.vaadin.bpmn;

import java.util.Locale;
import java.util.UUID;

import org.eclipse.e4.core.contexts.IEclipseContext;
import org.eclipse.e4.core.di.extensions.EventUtils;
import org.eclipse.e4.core.services.events.IEventBroker;
import org.eclipse.osbp.bpm.api.IBPMEngine;
import org.eclipse.osbp.bpm.api.IBlipBPMFunctionProvider;
import org.eclipse.osbp.eventbroker.EventBrokerMsg;
import org.eclipse.osbp.runtime.common.event.EventDispatcherEvent;
import org.eclipse.osbp.runtime.common.event.IEventDispatcher;
import org.eclipse.osbp.runtime.common.event.EventDispatcherEvent.EventDispatcherCommand;
import org.eclipse.osbp.ui.api.metadata.IDSLMetadataService;
import org.eclipse.osbp.ui.api.user.IUser;
import org.eclipse.osbp.utils.vaadin.YesNoDialog;
import org.osgi.service.event.EventHandler;
import org.slf4j.Logger;

import com.vaadin.annotations.JavaScript;
import com.vaadin.ui.AbstractJavaScriptComponent;
import com.vaadin.ui.JavaScriptFunction;
import com.vaadin.ui.UI;
import com.vaadin.ui.Window;

import elemental.json.JsonArray;

@JavaScript({ "theme://plugin/net.osbee.utils.js/net/osbee/utils/js/mxBasePaths.js",
		"theme://plugin/net.osbee.utils.js/net/osbee/utils/js/mxClient.js",
		"theme://plugin/org.eclipse.osbp.utils.js/org/eclipse/osbp/utils/js/d3.min.js",
		"theme://plugin/org.eclipse.osbp.utils.js/org/eclipse/osbp/utils/js/mootools-core-1.4.5-full-compat.js",
		"theme://plugin/net.osbee.utils.js/net/osbee/utils/js/ccMxClient.js", "js/BpmnRendererJsClass.js" })
public class BpmnRenderer extends AbstractJavaScriptComponent implements IUser.UserLocaleListener, IEventDispatcher.Receiver {
	private static final long serialVersionUID = 1025480199756469267L;
	private static Logger log = org.slf4j.LoggerFactory.getLogger(BpmnRenderer.class);

	private transient BpmnConverter bpmnConverter;
	private transient IBPMEngine bpmEngine;
	private transient IBlipBPMFunctionProvider blip;
	private transient IDSLMetadataService dslMetadataService;
	private transient IUser user;
	private String processId;
	private YesNoDialog yesnoDialog;
	private transient EventHandler dispatchYesNo;
	private String startProcessText;
	private String answerYesText;
	private String answerNoText;
	private Locale locale;
	private YesNoDialog yesnoWindow;
	private String yesNoUuid;
	private IEventDispatcher eventDispatcher;

	@Override
	public boolean equals(Object obj) {
		return super.equals(obj);
	}

	@Override
	public int hashCode() {
		return super.hashCode();
	}

	public BpmnRenderer(IBPMEngine bpmEngine, IBlipBPMFunctionProvider blip, IEclipseContext context) {
		this.bpmEngine = bpmEngine;
		this.blip = blip;
		user = context.get(IUser.class);
		dslMetadataService = context.get(IDSLMetadataService.class);
		eventDispatcher = context.get(IEventDispatcher.class);
		user.addUserLocaleListener(this);
	    locale = user.getLocale();
	    eventDispatcher.addEventReceiver(this);
	    yesnoDialog = new YesNoDialog();
	    localeChanged(locale);
		
		bpmnConverter = new BpmnConverter();
		addFunction("onStartClick", new JavaScriptFunction() {
			@Override
	    	public void call(JsonArray arguments){
	    		// ask to start process
				yesNoUuid = UUID.randomUUID().toString();
				yesnoWindow = yesnoDialog.init(eventDispatcher, BpmnRenderer.this.getClass().getCanonicalName(), yesNoUuid, null, startProcessText, answerYesText, answerNoText);
				UI.getCurrent().addWindow(yesnoWindow);
	    	}
	    });
		addFunction("onSelectedClick", new JavaScriptFunction() {
			@Override
			public void call(JsonArray arguments){
				// start task
			}
		});
	}

	public void drawBpmn(String processId) {
		log.debug("start creating bpmn");
		bpmnConverter.clearBPMN();
		// get the result
		if (processId != null) {
			log.debug("start loading bpmn");
			if (bpmEngine != null) {
				bpmnConverter.loadBPMN(bpmEngine.getResourceName(processId));
			} else {
				log.debug("bpm not licensed");
			}
			setSizeFull();
			getState().bpmnCreationCode = bpmnConverter.getBpmnJsCreationCode();
			log.debug("finished creating bpmn");
		}
		this.processId = processId;
	}

	@Override
	public BpmnRenderState getState() {
		return (BpmnRenderState) super.getState();
	}

	public void setSelectedCell(String selectedCell) {
		getState().selectedCell = selectedCell;
	}
	
	public void dispose() {
		user.removeUserLocaleListener(this);
	    eventDispatcher.removeEventReceiver(this);
	}

	@Override
	public void localeChanged(Locale locale) {
	    this.locale = locale;
	    startProcessText = dslMetadataService.translate(locale.toLanguageTag(),"startProcessText");
	    answerYesText = dslMetadataService.translate(locale.toLanguageTag(),"yes");
	    answerNoText = dslMetadataService.translate(locale.toLanguageTag(),"no");
	}

	@Override
	public void receiveEvent(EventDispatcherEvent event) {
		if(event.getCommand() == EventDispatcherCommand.YES && event.getSender().equals(getClass().getCanonicalName()) && event.getTopic().equals(yesNoUuid)) {
			if(yesnoWindow != null) {
				yesnoWindow.close();
				UI.getCurrent().removeWindow(yesnoWindow);
				yesnoWindow = null;
			}
			blip.startProcess(processId);
		}
		if(event.getCommand() == EventDispatcherCommand.NO && event.getSender().equals(getClass().getCanonicalName()) && event.getTopic().equals(yesNoUuid)) {
			if(yesnoWindow != null) {
				yesnoWindow.close();
				UI.getCurrent().removeWindow(yesnoWindow);
				yesnoWindow = null;
			}
		}
	}
}
