package eu.ydp.empiria.player.client.module.media.html5;

import com.google.gwt.dom.client.MediaElement;
import com.google.gwt.media.client.MediaBase;
import com.google.web.bindery.event.shared.HandlerRegistration;

import eu.ydp.empiria.player.client.PlayerGinjector;
import eu.ydp.empiria.player.client.controller.extensions.internal.media.HTML5MediaExecutor;
import eu.ydp.empiria.player.client.module.media.MediaAvailableOptions;
import eu.ydp.empiria.player.client.module.media.MediaWrapper;
import eu.ydp.empiria.player.client.module.object.impl.Media;
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;
import eu.ydp.empiria.player.client.util.events.scope.CurrentPageScope;

/**
 * Wrapper dla elemntow audio i video html5
 *
 */
public class HTML5MediaWrapper implements MediaWrapper<MediaBase>, MediaEventHandler {
	protected MediaBase mediaBase;
	protected String uniqId = null;
	protected final EventsBus eventsBus = PlayerGinjector.INSTANCE.getEventsBus();
	protected HTML5MediaAvailableOptions availableOptions = new HTML5MediaAvailableOptions();
	protected boolean ready = false;
	protected HandlerRegistration handlerRegistration;
	protected HTML5MediaExecutor mediaExecutor;
	protected AttachHandlerImpl attachHandlerImpl; 
	
	public HTML5MediaWrapper(Media media) {
		setMediaObject(media.getMedia());
		
		attachHandlerImpl = new AttachHandlerImpl();
		attachHandlerImpl.setMediaBase(mediaBase);
		attachHandlerImpl.setMediaExecutor(mediaExecutor);
		attachHandlerImpl.setMediaWrapper(this);
		mediaBase.addAttachHandler(attachHandlerImpl);
	}
	
	public void setMediaExecutor(HTML5MediaExecutor mediaExecutor) {
		this.mediaExecutor = mediaExecutor;
		attachHandlerImpl.setMediaExecutor(mediaExecutor);
	}

	@Override
	public MediaAvailableOptions getMediaAvailableOptions() {
		return availableOptions;
	}

	@Override
	public MediaBase getMediaObject() {
		return mediaBase;
	}
	
	public void setMediaObject(MediaBase mediaBase) {
		this.mediaBase = mediaBase;
		mediaBase.setPreload(MediaElement.PRELOAD_METADATA);
		handlerRegistration = eventsBus.addAsyncHandlerToSource(MediaEvent.getType(MediaEventTypes.ON_DURATION_CHANGE), this, this, new CurrentPageScope());
	}

	@Override
	public String getMediaUniqId() {
		if (uniqId == null) {
			uniqId = String.valueOf(new StringBuilder().append(System.currentTimeMillis()).append(Math.random()).toString());
		}
		return uniqId;
	}

	@Override
	public double getCurrentTime() {
		return mediaBase.getCurrentTime();
	}

	@Override
	public double getDuration() {
		double duration = mediaBase.getDuration(); 
		if (Double.isNaN(duration)) {
			return 0;
		} else {
			return duration;
		}
	}

	@Override
	public boolean isMuted() {
		return mediaBase.isMuted();
	}

	@Override
	public double getVolume() {
		return mediaBase.getVolume();
	}

	@Override
	public boolean canPlay() {
		return ready || mediaBase.getReadyState() != MediaElement.HAVE_NOTHING;
	}

	@Override
	public void onMediaEvent(MediaEvent event) {
		if (event.getType() == MediaEventTypes.ON_DURATION_CHANGE) {
			ready = true;
			handlerRegistration.removeHandler();
		}
	}

	@Override
	public int hashCode() {
		int prime = 31;
		int result = 1;
		result = prime * result + getMediaUniqId().hashCode();
		return result;
	}

	@Override
	@SuppressWarnings("PMD")
	public boolean equals(Object obj) {
		if (this == obj) {
			return true;
		}
		if (obj == null) {
			return false;
		}
		if (getClass() != obj.getClass()) {
			return false;
		}
		HTML5MediaWrapper other = (HTML5MediaWrapper) obj;
		if (getMediaUniqId() == null) {
			if (other.getMediaUniqId() != null) {
				return false;
			}
		} else if (!getMediaUniqId().equals(other.getMediaUniqId())) {
			return false;
		}
		return true;
	}

}

@@ -148,16 +148,59 @@
 aBase;%0D%0A
+import com.google.gwt.media.client.Video;%0D%0A
 import c
@@ -1615,16 +1615,49 @@
 );%0D%0A%09%09%0D%0A
+%09%09if (media instanceof Video)%7B%0D%0A%09
 %09%09attach
@@ -1692,24 +1692,25 @@
 lerImpl();%0D%0A
+%09
 %09%09attachHand
@@ -1739,24 +1739,25 @@
 ediaBase);%0D%0A
+%09
 %09%09attachHand
@@ -1796,24 +1796,25 @@
 ecutor);%0D%0A%09%09
+%09
 attachHandle
@@ -1843,16 +1843,17 @@
 this);%0D%0A
+%09
 %09%09mediaB
@@ -1890,24 +1890,29 @@
 dlerImpl);%0D%0A
+%09%09%7D%0D%0A
 %09%7D%0D%0A%09%0D%0A%09publ
@@ -2012,16 +2012,52 @@
 cutor;%0D%0A
+%09%09if (attachHandlerImpl != null)%7B%0D%0A%09
 %09%09attach
@@ -2098,24 +2098,29 @@
 Executor);%0D%0A
+%09%09%7D%0D%0A
 %09%7D%0D%0A%0D%0A%09@Over

fix attach handler for Video bug 72957