﻿function handleLoad() {	
	var mediaURL = "assets/undersail.wmv";
	var address = window.location.href;
	var index = address.lastIndexOf("?media=");
	if (index != -1)
		mediaURL = address.substr(index + 7);
		
	playerSkin = new sleekVideoPlayer(document.getElementById("wpfeControl"), mediaURL);
}

function sleekVideoPlayer(wpfeControl, videoSource) {
	this.wpfeControl = wpfeControl;
	
	this.mediaElement = wpfeControl.findName("MediaElement");
	this.playhead = wpfeControl.findName("Playhead");
	this.border = wpfeControl.findName("rectangle");
	this.playControls = wpfeControl.findName("PlayControls");
	this.root = wpfeControl.findName("Root");
	this.close = wpfeControl.findName("Close");
	this.timeText = wpfeControl.findName("TimeText");
	this.toBeLoadedPath = wpfeControl.findName("ToBeLoadedPath");
	this.loadedPath = wpfeControl.findName("LoadedPath");
	
	this.expandAnimation = wpfeControl.findName("Expand");
	this.collapseAnimation = wpfeControl.findName("Collapse");
	this.closeInAnimation = wpfeControl.findName("CloseIn");
	this.closeOutAnimation = wpfeControl.findName("CloseOut");
	this.fadeInAnimation = wpfeControl.findName("FadeIn");
	this.fadeOutAnimation = wpfeControl.findName("FadeOut");
	
	setCallback(this.wpfeControl, "fullScreenChanged", delegate(this, this.fullScreenChanged));
	setCallback(this.root, "mouseEnter", delegate(this, this.handleMouseEnter));
	setCallback(this.root, "mouseLeave", delegate(this, this.handleMouseLeave));
	setCallback(this.playControls, "mouseLeftButtonDown", delegate(this, this.handlePlayheadPress));
	setCallback(this.playControls, "mouseLeftButtonUp", delegate(this, this.handlePlayheadRelease));
	setCallback(this.playControls, "mouseMove", delegate(this, this.handlePlayheadDrag));
	setCallback(this.mediaElement, "downloadProgressChanged", delegate(this, this.handleDownloadProgressChanged));
	setCallback(this.mediaElement, "mouseLeftButtonUp", delegate(this, this.handleMouseUp));
	setCallback(this.close, "mouseEnter", delegate(this, this.handleCloseEnter));
	setCallback(this.close, "mouseLeave", delegate(this, this.handleCloseLeave));
	setCallback(this.close, "mouseLeftButtonDown", delegate(this, this.handleCloseClick));
	
	this.mediaElement.Source = videoSource;
	this.play();
}

sleekVideoPlayer.prototype.isDraggingPlayhead = false;
sleekVideoPlayer.prototype.interval = 10;
sleekVideoPlayer.prototype.downloadProgress = 0;
sleekVideoPlayer.prototype.onClose = null;
sleekVideoPlayer.prototype.hasPlayed = false;

sleekVideoPlayer.prototype.handleMouseEnter = function() {
	this.expandAnimation.begin();
	this.collapseAnimation.stop();
}

sleekVideoPlayer.prototype.handleMouseLeave = function() {
	this.collapseAnimation.begin();
	this.expandAnimation.stop();
}

sleekVideoPlayer.prototype.handlePlayheadPress = function(sender, eventArgs) {
	this.isDraggingPlayhead = true;
	this.playControls.captureMouse();
	
	this.seekFromMouse(eventArgs.X);
}

sleekVideoPlayer.prototype.handlePlayheadRelease = function() {
	this.isDraggingPlayhead = false;
	this.playControls.releaseMouseCapture();
	this.mediaElement.play();
}

sleekVideoPlayer.prototype.handlePlayheadDrag = function(sender, eventArgs) {
	if (this.isDraggingPlayhead) {
	    this.mediaElement.pause();
		this.seekFromMouse(eventArgs.X);
	}
}

sleekVideoPlayer.prototype.handleCloseEnter = function() {
	this.closeInAnimation.begin();
	this.closeOutAnimation.stop();
}

sleekVideoPlayer.prototype.handleCloseLeave = function() {
	this.closeOutAnimation.begin();
	this.closeInAnimation.stop();
}

sleekVideoPlayer.prototype.handleCloseClick = function() {
	this.mediaElement.stop();
	if (this.onClose != null)
		this.onClose();
}

sleekVideoPlayer.prototype.stop = function() {
	this.refreshPlayTime();
	
	window.clearInterval(this.timerID);
	
	this.mediaElement.stop();
}

sleekVideoPlayer.prototype.play = function() {
	this.timerID = window.setInterval(delegate(this, this.handleInterval), this.interval);
	
	if (this.hasPlayed) {
		this.mediaElement.play();
	}
	this.hasPlayed = true;
}

sleekVideoPlayer.prototype.pause = function() {
	this.mediaElement.pause();
}

sleekVideoPlayer.prototype.fadeOut = function() {
	this.fadeOutAnimation.begin();
	this.fadeInAnimation.stop();
}

sleekVideoPlayer.prototype.handleInterval = function(e) {
	this.refreshPlayTime();
}

sleekVideoPlayer.prototype.refreshPlayTime = function() {
	var currentPosition = 0;
	
	var position = this.mediaElement.position;
	if (position != null)
		currentPosition = position.seconds;
	
	this.timeText.Text = this.formatTime(currentPosition * 1000);
	
	this.updatePlayhead(currentPosition);
}
	
sleekVideoPlayer.prototype.handleDownloadProgressChanged = function(sender, eventArgs) {
	this.updateDownloadProgress();
}

sleekVideoPlayer.prototype.handleMouseUp = function(sender, args) {
    this.wpfeControl.fullScreen = true;
}

sleekVideoPlayer.prototype.fullScreenChanged = function(sender, args) {
    if ( this.wpfeControl.fullScreen )
    {
        this.close.opacity = 0;
        this.border.opacity = 0;
        this.playControls.opacity = 0;
        
        this.mediaElement.width = this.wpfeControl.actualWidth;
        this.mediaElement.height = this.wpfeControl.actualHeight;
        this.mediaElement["canvas.top"] = 0;
        this.mediaElement["canvas.left"] = 0;
    }
    else
    {
        this.close.opacity = 1;
        this.border.opacity = 1;
        this.playControls.opacity = 1;
        
        this.mediaElement["canvas.left"] = 0;
        this.mediaElement["canvas.top"] = 8;
        this.mediaElement.width = 400;
        this.mediaElement.height = 288;
    }
}

sleekVideoPlayer.prototype.updatePlayhead = function(time) {
	var offset = 0;
	
	var naturalDuration = this.mediaElement.naturalDuration;
	if (naturalDuration != null)
	{
		var mediaDuration = naturalDuration.seconds;
		
		var percent = time / mediaDuration;
		var playheadWidth = this.playhead.width;
		var playAreaWidth = this.toBeLoadedPath.width - playheadWidth;
		offset = playAreaWidth * percent;
	}
	this.playhead["Canvas.left"] = offset;
}

sleekVideoPlayer.prototype.seekFromMouse = function(mousePosX) {
	var mediaDuration = this.mediaElement.naturalDuration.seconds;
	var playheadWidth = this.playhead.width;
	var playAreaWidth = this.toBeLoadedPath.width - playheadWidth;
	
	var currentPlayTime = (mousePosX - 8 - playheadWidth / 2) / playAreaWidth * mediaDuration;
	
	if (currentPlayTime > mediaDuration)
		currentPlayTime = mediaDuration;
	else if (currentPlayTime < 0)
		currentPlayTime = 0;
	
	var position = this.mediaElement.position;
	position.seconds = currentPlayTime;
	this.mediaElement.position = position;
	
	this.updatePlayhead(position);
}

sleekVideoPlayer.prototype.updateDownloadProgress = function() {
	this.loadedPath.width = this.toBeLoadedPath.width * this.mediaElement.downloadProgress;
}

sleekVideoPlayer.prototype.formatTime = function(time) {
	var timeString = "";
	timeString += Math.floor(time / 60000);
	if (timeString.length == 1)
		timeString = "0" + timeString;
		
	timeString += ":";
	var seconds = Math.floor(time / 1000.0) % 60;
	if (seconds < 10)
		timeString += "0";
	
	timeString += seconds;
	
	return timeString;
}


/// Helper method for creating per-object callbacks
/// @param target object to invoke the callback on
/// @param callback method to be called on the object
function delegate(target, callback) {
	var func = function() {
		callback.apply(target, arguments);
	}
	return func;
}

/// Hook up the specified event to the specified delegate.
/// Allows javascript delegates to be used and dynamically
/// creates the global method.
/// @param target WPF/e element to set the event on
/// @param eventName name of the event to set, ie "MouseEnter"
/// @param delegate function to call when the event occurs.
function setCallback(target, eventName, delegate) {
	if (!window.methodID)
		window.methodID = 0;
	
	var callbackName = "uniqueCallback" + (window.methodID++);
	eval(callbackName + " = delegate;");
	
	target[eventName] = "javascript:" + callbackName;
}
