package org.eclipse.osbp.xtext.action.common;

import java.util.Locale;

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

import org.eclipse.e4.core.contexts.IEclipseContext;
import org.eclipse.e4.core.services.events.IEventBroker;
import org.eclipse.osbp.ui.api.e4.IE4Dialog;
import org.eclipse.osbp.ui.api.metadata.IDSLMetadataService;
import org.eclipse.osbp.ui.api.themes.EnumCssClass;
import org.eclipse.osbp.ui.api.user.IUser;
import org.eclipse.osbp.vaaclipse.addons.common.api.IE4Topics;
import org.eclipse.osbp.vaaclipse.addons.common.api.ResourceUtil;
import org.osgi.service.event.Event;
import org.osgi.service.event.EventHandler;

import com.vaadin.server.ThemeResource;
import com.vaadin.ui.ComponentContainer;
import com.vaadin.ui.HorizontalLayout;
import com.vaadin.ui.Image;
import com.vaadin.ui.UI;

public class DialogStateHandler implements IUser.UserLocaleListener {
	
	@Inject
	IEclipseContext eclipseContext;
	
	private Image mode;
	private Image state;
	private Image validity;
	private IDSLMetadataService dslMetadataService;
	private IUser user;
	private IEventBroker eventBroker;
	private IE4Dialog dialog;
	private EventHandler stateHandler;
	private String currentMode;
	private String currentState;
	private String currentValidity;

	private static final String iconPath = "plugin/org.eclipse.osbp.xtext.action/images/%s.png";

	@PostConstruct
	public void init(final ComponentContainer container) {
		eventBroker = eclipseContext.get(IEventBroker.class);
		dslMetadataService = eclipseContext.get(IDSLMetadataService.class);
		user = eclipseContext.get(IUser.class);
		dialog = eclipseContext.get(IE4Dialog.class);
		stateHandler = new EventHandler() {
			@Override
			public void handleEvent(Event event) {
				refreshState(event);
			}			
		};
		eventBroker.subscribe(IE4Topics.ToolBarEvents.NOTIFY_TOOLBAR_DIALOG_STATE, stateHandler);
		HorizontalLayout stateLine = new HorizontalLayout();
		stateLine.addStyleName(EnumCssClass.TOOLBAR_STATE_CONTAINER.toString());
		mode = new Image();
		mode.addStyleName(EnumCssClass.TOOLBAR_STATE.toString());
		state = new Image();
		state.addStyleName(EnumCssClass.TOOLBAR_STATE.toString());
		validity = new Image();
		validity.addStyleName(EnumCssClass.TOOLBAR_STATE.toString());
		stateLine.addComponent(mode);
		stateLine.addComponent(state);
		stateLine.addComponent(validity);
		container.addComponent(stateLine);
		user.addUserLocaleListener(this);
	}
	
	@PreDestroy
	public void dispose() {
		eventBroker.unsubscribe(stateHandler);
		user.removeUserLocaleListener(this);
	}

	protected void refreshState(Event event) {
		synchronized (this) {
			if(dialog.getStateLabelUUID() != null && dialog.getStateLabelUUID().equals(event.getProperty(IE4Topics.ToolBarEvents.STATE_UUID))) {
				UI.getCurrent().accessSynchronously(() -> {
					switch(IE4Topics.ToolBarEvents.Labels.valueOf((String)event.getProperty(IE4Topics.ToolBarEvents.STATE_LABEL))) {
					case MODE:
						currentMode = (String)event.getProperty(IE4Topics.ToolBarEvents.STATE_STATE); 
						mode.setDescription(dslMetadataService.translate(user.getLocale().toLanguageTag(), (String)event.getProperty(IE4Topics.ToolBarEvents.STATE_STATE)));
						mode.setIcon(new ThemeResource(String.format(iconPath, ((String)event.getProperty(IE4Topics.ToolBarEvents.STATE_STATE)).toLowerCase())));
						break;
					case STATE:
						currentState = (String)event.getProperty(IE4Topics.ToolBarEvents.STATE_STATE); 
						state.setDescription(dslMetadataService.translate(user.getLocale().toLanguageTag(), (String)event.getProperty(IE4Topics.ToolBarEvents.STATE_STATE)));
						state.setIcon(new ThemeResource(String.format(iconPath, ((String)event.getProperty(IE4Topics.ToolBarEvents.STATE_STATE)).toLowerCase())));
						break;
					case VALIDITY:
						currentValidity = (String)event.getProperty(IE4Topics.ToolBarEvents.STATE_STATE); 
						validity.setDescription(dslMetadataService.translate(user.getLocale().toLanguageTag(), (String)event.getProperty(IE4Topics.ToolBarEvents.STATE_STATE)));
						validity.setIcon(new ThemeResource(String.format(iconPath, ((String)event.getProperty(IE4Topics.ToolBarEvents.STATE_STATE)).toLowerCase())));
						break;
					default:
						break;
					}
				});
			}
		}
	}

	@Override
	public void localeChanged(Locale locale) {
		mode.setDescription(dslMetadataService.translate(user.getLocale().toLanguageTag(), currentMode));
		state.setDescription(dslMetadataService.translate(user.getLocale().toLanguageTag(), currentState));
		validity.setDescription(dslMetadataService.translate(user.getLocale().toLanguageTag(), currentValidity));
	}
}
