package eu.ydp.empiria.player.client.controller.extensions.internal;

import com.google.gwt.core.client.JavaScriptObject;
import com.google.inject.Inject;

import eu.ydp.empiria.player.client.controller.communication.DisplayOptions;
import eu.ydp.empiria.player.client.controller.communication.FlowOptions;
import eu.ydp.empiria.player.client.controller.delivery.DeliveryEngineSocket;
import eu.ydp.empiria.player.client.controller.events.delivery.DeliveryEvent;
import eu.ydp.empiria.player.client.controller.events.delivery.DeliveryEventType;
import eu.ydp.empiria.player.client.controller.extensions.types.DeliveryEngineSocketUserExtension;
import eu.ydp.empiria.player.client.controller.extensions.types.DeliveryEventsListenerExtension;
import eu.ydp.empiria.player.client.controller.extensions.types.PlayerJsObjectModifierExtension;
import eu.ydp.empiria.player.client.util.events.bus.EventsBus;
import eu.ydp.empiria.player.client.util.events.media.MediaEvent;
import eu.ydp.empiria.player.client.util.events.media.MediaEventHandler;
import eu.ydp.empiria.player.client.util.events.media.MediaEventTypes;

public class PlayerCoreApiExtension extends
		InternalExtension implements DeliveryEngineSocketUserExtension, PlayerJsObjectModifierExtension, DeliveryEventsListenerExtension, MediaEventHandler {

	@Inject
	private EventsBus eventsBus;
	
	private JavaScriptObject playerJsObject;
	private DeliveryEngineSocket deliveryEngineSocket;
	
	@Override
	public void init() {
		initExportStateStringJs(playerJsObject);
		eventsBus.addHandler(MediaEvent.getType(MediaEventTypes.ON_MOBILE_FULL_SCREEN_OPEN), this);
	}

	@Override
	public void setDeliveryEngineSocket(DeliveryEngineSocket des) {
		deliveryEngineSocket = des;
	}

	@Override
	public void setPlayerJsObject(JavaScriptObject playerJsObject) {
		this.playerJsObject = playerJsObject;
	}

	@Override
	public void onDeliveryEvent(DeliveryEvent deliveryEvent) {
		if (deliveryEvent.getType() == DeliveryEventType.ASSESSMENT_LOADING){
			setOptions();
		}
		if (deliveryEvent.getType() == DeliveryEventType.ASSESSMENT_STARTING){
			importInitialItemIndex();
			importState();
		}
	}
	
	@Override
	public void onMediaEvent(MediaEvent event) {
		invokeFullscreenAction(playerJsObject);
	}
	
	private void setOptions(){
		JavaScriptObject flowOptionsJs = callImportFlowOptionsJs(playerJsObject);
		
		if (flowOptionsJs != null){
			FlowOptions flowOptions = FlowOptions.fromJsObject(flowOptionsJs);
			deliveryEngineSocket.setFlowOptions(flowOptions);
		}

		JavaScriptObject displayOptionsJs = callImportDisplayOptionsJs(playerJsObject);
		
		if (displayOptionsJs != null){
			DisplayOptions displayOptions = DisplayOptions.fromJsObject(displayOptionsJs);
			deliveryEngineSocket.setDisplayOptions(displayOptions);
		}
	}
	
	private native JavaScriptObject callImportFlowOptionsJs(JavaScriptObject playerJsObject)/*-{
		if (typeof playerJsObject.importFlowOptions == 'function')
			return playerJsObject.importFlowOptions();
		return null;
	}-*/;
	
	private native JavaScriptObject callImportDisplayOptionsJs(JavaScriptObject playerJsObject)/*-{
		if (typeof playerJsObject.importDisplayOptions == 'function')
			return playerJsObject.importDisplayOptions();
		return null;
	}-*/;
	
	private void importState(){
		String state = callImportStateStringJs(playerJsObject);
		if (!"".equals(state)){
			deliveryEngineSocket.setStateString(state);
		}
	}	

	private native String callImportStateStringJs(JavaScriptObject playerJsObject)/*-{
		if (typeof playerJsObject.importStateString == 'function')
			return playerJsObject.importStateString();
		return "";
	}-*/;

	private String exportState(){
		return deliveryEngineSocket.getStateString();
	}

	private native void initExportStateStringJs(JavaScriptObject playerJsObject)/*-{
		var instance = this;
		playerJsObject.exportStateString = function(){
			return instance.@eu.ydp.empiria.player.client.controller.extensions.internal.PlayerCoreApiExtension::exportState()();
		}
	}-*/;
	
	private void importInitialItemIndex(){
		int importedItemIndex = callImportInitialItemIndex(playerJsObject);
		Integer itemIndex = (importedItemIndex > -1) ? Integer.valueOf(importedItemIndex) : null;
		deliveryEngineSocket.setInitialItemIndex(itemIndex);
	}
	
	private native int callImportInitialItemIndex(JavaScriptObject playerJsObject)/*-{
		var itemIndex = -1;
		if (typeof playerJsObject.importInitialItemIndex == 'function'){
			var importedIndex =  playerJsObject.importInitialItemIndex();
			if(!isNaN(importedIndex)){
				itemIndex = parseInt(importedIndex);
			}			
		}
		
		return itemIndex;		
				
	}-*/;
	
	private native String invokeFullscreenAction(JavaScriptObject playerJsObject)/*-{
		if (typeof playerJsObject.invokeAction == 'function') {
			playerJsObject.invokeAction('fullscreen');
		}
	}-*/;
}

@@ -911,221 +911,8 @@
 us;%0D
-%0Aimport eu.ydp.empiria.player.client.util.events.media.MediaEvent;%0D%0Aimport eu.ydp.empiria.player.client.util.events.media.MediaEventHandler;%0D%0Aimport eu.ydp.empiria.player.client.util.events.media.MediaEventTypes;%0D
 %0A%0D%0Ap
@@ -1089,27 +1089,8 @@
 sion
-, MediaEventHandler
  %7B%0D%0A
@@ -1317,103 +1317,8 @@
 );%0D%0A
-%09%09eventsBus.addHandler(MediaEvent.getType(MediaEventTypes.ON_MOBILE_FULL_SCREEN_OPEN), this);%0D%0A
 %09%7D%0D%0A
@@ -1868,117 +1868,8 @@
 %0A%09%0D%0A
-%09@Override%0D%0A%09public void onMediaEvent(MediaEvent event) %7B%0D%0A%09%09invokeFullscreenAction(playerJsObject);%0D%0A%09%7D%0D%0A%09%0D%0A
 %09pri
@@ -4302,213 +4302,7 @@
 /;%0D%0A
-%09%0D%0A%09private native String invokeFullscreenAction(JavaScriptObject playerJsObject)/*-%7B%0D%0A%09%09if (typeof playerJsObject.invokeAction == 'function') %7B%0D%0A%09%09%09playerJsObject.invokeAction('fullscreen');%0D%0A%09%09%7D%0D%0A%09%7D-*/;%0D%0A
 %7D%0D%0A

remove fullscreen event handling from PlayerCoreApiExtension issue YPUB-5142