var SPVideo = function(container,playback,callbacks,flashPlayer,debug)  {
	
	
	this.name = 'SPVideo';
	
	// Init SPDebug
	SPDebug.debug = debug;
	this.debug = new SPDebug.construct(this.name);
	
	// Create self reference
	var self = this;
	
	this.config = {
		container:null,
		flashvars:null,
		playback:null,
		attributes:null,
		flashPlayer:null
	};
	
	// Set up config
	this.config.container	= container;
	this.config.playback	= playback;
	this.config.flashPlayer	= flashPlayer;
	this.callbacks			= callbacks;
	
	// Set default attributes in config.playback.attributes
	this.config.playback.attributes = {
		name: container,
		id: container
	}
	
	// Set default attributes in config.playback.params
	if (!this.config.playback.params) {
		this.config.playback.params = {
			allowScriptAccess:'always',
			allowFullScreen:'true'
		}
	}
	
	this.__construct = function() {
		
		if (this.callbacks) {
			this.onError 	= this.callbacks.onError;
			this.onSuccess	= this.callbacks.onSuccess;
		}
		
		// Detect iPad/iPhone/iPod by looking at userAgent header.
		if( navigator.userAgent.match(/iP(ad|hone|od)/i) )  {
			
			self.debug.say('Render HTML5');
			var container = $('#'+self.config.container);
			
			// Attempt to create HTML5 video.
			var html5 = new SPVideo.HTML5(self.config,{
				
					onSuccess:function() {
						this.debug.say('HTML5 success');
						self.onSuccess();
					},
				
					onError:function(error) {
						this.debug.say('HTML5 failure:'+error);
						self.onError(error);
						
					}
				
				}
				
			);
			
		}
		// If device isnt iPad/iPhone/iPod, render flash
		else {
			this.debug.say('Render Flash');
			// Attempt to render flash player
			
			var flash = new SPVideo.Flash(self.config,{
			
				onSuccess: function () {
					this.debug.say('Flash success');
					self.onSuccess();
				},
				onError: function(error) {
					this.debug.say('Flash failure:'+error);
					self.onError(error);
				}
	
			});
		
		}
	
	}
	
	// ----------------------------------
	// Error handling
	// ----------------------------------
	
	this.onError = function(error) {
		
		this.debug.say('Empty onError callback:'+error);
		
		var container = $('#'+self.config.container);
		
		if (error === SPVideo.Flash.exceptions.FlashRenderUnsuccessful) {
			// Render flash download information
			container.html('<p>In order to watch videos on this site, you need to download the latest version of Adobe Flash Player. Get it <a href="http://get.adobe.com/flashplayer/">here</a>.</p>');
		}

		if (error === SPVideo.HTML5.exceptions.VideoNotFound || error === SPVideo.HTML5.exceptions.NoValidVideoFound) {
			// Render this video is not available.
			container.html('<p>this video is not available for your device</p>');
		}
		
		
	};
	
	this.onSuccess = function(message) {
		
		this.debug.say('Empty onSuccess callback');
	};
	
	// ----------------------------------
	// Call construct
	// ----------------------------------	
	this.__construct();
};

SPDebug = {
	
	debug:false,
	name: null,
	
	construct: function(name) {
		
		var self = this;
		this.name = name;
				
		this.say = function(message) {

			if (SPDebug.debug)
				console.log(self.name +" -> " + message);
		
		}
	
	}
};

SPVideo.HTML5 = function(config,callbacks) {
	
	this.jsonPath 	= 'http://apps.streamingbolaget.se/apps/streamplayer/2/embed/json.php';
	this.name 		= 'SPVideo.HTML5';
	this.config		= config;
	this.callbacks 	= callbacks;
	this.debug 		= new SPDebug.construct(this.name);
	
	
	this.__construct = function() {
		
		this.debug.say('Construct');
		
		// Create json path
		if (this.config.playback.flashvars.fqdn) {
			this.jsonPath = 'http://'+this.config.playback.flashvars.fqdn+'/apps/streamplayer/2/embed/json.php';
		}
		
		// Register callbacks
		this.onError 	= this.callbacks.onError;
		this.onSuccess	= this.callbacks.onSuccess;
		
		this.video = $(document.createElement('video'));
		this.playerContainer = $('#'+this.config.container);
		
		var self = this;
		var flashvars = this.config.playback.flashvars;
		var prependPath = 'http://'+flashvars.fqdn+'/resources/';
		var xmlPath = 'http://'+flashvars.fqdn+'/contents/'+flashvars.content+'.xml';
		
		if (this.video) {
			
			// Fetch XML.
			$.getJSON(this.jsonPath + '?xml=' + escape(xmlPath) + '&callback=?', function(jqXHR, textStatus, errorThrown) {
				
				self.debug.say('JSON Callback');
				
				var videoPath = prependPath+jqXHR.resources['video-360p'];
				var posterPath = prependPath+jqXHR.resources['poster'];
				
				var isValidFileExt = videoPath.indexOf('.mp4') > -1;
				
				// if this file ext is invalid, throw error and return.
				if (!isValidFileExt) {
					self.onError(SPVideo.HTML5.exceptions.NoValidVideoFound);
					return;
				}

				self.setupHTML5VideoElement();
				self.prepareHTML5VideoPlayback(posterPath,videoPath);

				// Monitor video player for error
				self.video.attr('onerror',function(e){
					if (this.networkState == this.NETWORK_NO_SOURCE) {
					//	self.onError(SPVideo.HTML5.exceptions.VideoNotFound)
					}
					
				});
				
			
			});
		}
		else {
			
			this.onError(SPVideo.HTML5.exceptions.CannotRenderHTMLVideo);
			
			
		}
		
	};

	// ----------------------------------
	// HTML Video Element preparation
	// ----------------------------------
	
	this.prepareHTML5VideoPlayback = function(posterPath,videoPath) {

		// Set the player playback data.
		this.video.attr('poster',posterPath);
		this.video.attr('src',videoPath);
		
	};
	
	this.setupHTML5VideoElement = function() {
				
		// Inherit width/height of player window.
		this.video.width(this.playerContainer.width());
		this.video.height(Math.round(this.playerContainer.width()/(16/9)));
		
		// Set attributes for video playback
		this.video.attr('controls','controls');
		this.video.attr('autoplay','autoplay');
		this.video.attr('type','video/mp4');
		
		this.playerContainer.html(this.video);
		
	};
	
	
	// ----------------------------------
	// Error handling
	// ----------------------------------
	
	this.onError = function(event) {
		
		this.debug.say('Empty onError callback');
		
	};
	
	this.onSuccess = function(event) {
		
		this.debug.say('Empty onSuccess callback');
	};
	
	// ----------------------------------
	// Call Construct
	// ----------------------------------
	this.__construct();
	
};

SPVideo.HTML5.exceptions = {

	VideoNotFound: 'VideoNotFound',
	CannotRenderHTMLVideoElement: 'CannotRenderHTMLVideoElement',
	NoValidVideoFound:'NoValidVideoFound'

};

SPVideo.Flash = function(configObject,callbacks) {
	
	// ----------------------------------
	// Constants
	// ----------------------------------	
	var self 		= this;
	this.name 		= 'SpVideo.flash';
	this.config 	= configObject;
	this.callbacks 	= callbacks;
	this.debug 		= new SPDebug.construct(this.name);
	
	// ----------------------------------
	// Declarations
	// ----------------------------------
		
	// Set flash player defaults
	if (!this.config.flashPlayer) {
		
		this.config.flashPlayer = {
			width: 600,
			height: 363,
			source: 'http://' + this.config.playback.flashvars.fqdn + '/player/2/content.swf'
		}
		
	}
	
	// Inherit dimensions if available
	var player = $('#'+this.config.container);
	
	if(this.config.playback.width) {
		this.config.flashPlayer.width = this.config.playback.width;
	} else {
		this.config.flashPlayer.width = player.width();
	}
	
	if(this.config.playback.height) {
		this.config.flashPlayer.height = this.config.playback.height;		
	} else {
		this.config.flashPlayer.height = player.height();
	}
	
	// ----------------------------------
	// Construct
	// ----------------------------------
	this.__construct = function() {
		
		this.debug.say('render flash video');
		
		// Register callbacks
		this.onError 	= this.callbacks.onError;
		this.onSuccess	= this.callbacks.onSuccess;
		
		var expressInstallPath = 'http://' + this.config.playback.flashvars.fqdn + '/apps/streamplayer/2/embed/expressInstall.swf';
		
		// Init flash
		swfobject.switchOffAutoHideShow();
		swfobject.embedSWF(this.config.flashPlayer.source,this.config.container,this.config.flashPlayer.width,this.config.flashPlayer.height,"10.0.0",expressInstallPath,this.config.playback.flashvars,this.config.playback.params,this.config.playback.attributes,function(e) {
			
			
			// The flash could not render
			if (!e.success) {
				
				self.onError(SPVideo.Flash.exceptions.FlashRenderUnsuccessful);
				return;
			}
			
			
		});
		
		
	}
	
	// ----------------------------------
	// Error handling
	// ----------------------------------
	
	this.onError = function(event) {
		
		this.debug.say('Empty onError callback');
		
	}
	
	this.onSuccess = function(event) {
		
		this.debug.say('Empty onSuccess callback');
		
	}
		
	// ----------------------------------
	// Call Construct
	// ----------------------------------
	this.__construct();
	
}

SPVideo.Flash.exceptions = {

	FlashRenderUnsuccessful: 'FlashRenderUnsuccessful'

};
