if(jQuery) (function($){
	
	$.extend($.fn, {
		cleverMedia: function(o) {
		
			// Defaults
			if( !o )
				return $(this).data("clevermedia");
			
			
			$(this).each( function() {
				var cm = new CleverMedia(o, this);
				
				cm.init();
				
				$(this).data("clevermedia", cm);
			});
		
			function CleverMedia(options, el)
			{
				// support defaults
				var defaults = {
					callbackPlay: [],
					callbackStop: [],
					callbackPause: [],
					sources: {},
					controlsBelow: false,
					controlsHiding: true,
					flashPlayer: "flowplayer.swf",
					allowFullscreen: true,
					preferFlash: false,
					audioTypes: ['mp3','ogg','wav'],
					videoTypes: ['h264','flv','ogv','webm'],
					typePreference: ['h264','ogv','webm','flv','mp3','ogg','wav'],
					preferredSize: {width:'auto', height:'auto'},
					wrapPlaceholder: true,
					wrapClass: "media_ready",
					autoplay: false
				};
			
			
				this.config = jQuery.extend(defaults, options);
				
				this.media = null;
				this.placeholder = $(el);
				this.id = this.placeholder.attr("id");
				
				this.addCallbackPlay = function(func)
				{
					$.isFunction(func)
						this.config.callbackPlay.push(func);
				}
				
				this.addCallbackPause = function(func)
				{
					$.isFunction(func)
						this.config.callbackPause.push(func);
				}
				
				this.addCallbackStop = function(func)
				{
					$.isFunction(func)
						this.config.callbackStop.push(func);
				}

				
				
				// test if browser supports video and audio tags
				this.supportsVideoTag = !!document.createElement('video').canPlayType;
				this.supportsAudioTag = !!document.createElement('audio').canPlayType;
				
				
				/* scans sources, in preference order, and returns the first valid HTML5 source type */
				this.getFirstPlayableSourceType = function()
				{
				
					var videoPlayer = document.createElement('video');
					var audioPlayer = document.createElement('video');
					
					for (t in this.config.typePreference)
	  				{
	  					var type = this.config.typePreference[t];
	  				
	  					var canPlay = false;
	  					
	  					var source = this.config.sources[type];
	  					
	  					if (!!source)
	  					{
		  					if (this.isVideoType(type) && this.supportsVideoTag)
		  					{
		  						canPlay = videoPlayer.canPlayType(source.mime);
		  					} else if (this.isAudioType(type) && this.supportsAudioTag)
		  					{
		  						canPlay = audioPlayer.canPlayType(source.mime);
		  					}
		  					
		  					if (canPlay == "probably" || canPlay == "maybe")
		  						return type;
	  					}
	  						
	  				}
	  				
	  				// browser didn't show any support for our media
	  				return false;
		    	}
		    	
		    	this.isAudioType = function(type)
		    	{
		    		for (a in this.config.audioTypes)
		    			if (this.config.audioTypes[a] == type)
		    				return true;
		    				
		    		return false;
		    	}
		    	
		    	this.isVideoType = function(type)
		    	{
		    		for (v in this.config.videoTypes)
		    			if (this.config.videoTypes[v] == type)
		    				return true;
		    				
		    		return false;
		    	}
		    	
		    	// ask swfobject if a flash is available
		    	this.hasFlash = function()
		    	{
		    		
		    		if (!$.flash)
		    		{
		    			alert("jquery.swfobject not found");
		    			return false;
		    		}
		    		
		    		return $.flash.hasVersion('9.1.0');
		    	}
		    	
		    	
		    	// insert and configure flash player
		    	this.insertFlashPlayer = function()
		    	{
			    	
			    	for (i in this.config.typePreference)
			    	{
			    	
			    		var type = this.config.typePreference[i]
			    	
			    		if (type == "flv" || type == "mp3")
						{
						
							var source = false;
				    		
				    		if (!!this.config.sources[type])
				    			source = this.config.sources[type];
				    		
				    		
				    		if (source)
				    		{
				    	
				     			var m = this.placeholder.flash({
									swf: this.config.flashPlayer,
									width: this.config.preferredSize.width,
									height: this.config.preferredSize.height,
									allowFullScreen: this.config.allowFullscreen,
									flashvars: { config: "{ playList: [{url:'"+source.url+"'}], initialScale: 'fit', useNativeFullScreen: "+(this.config.allowFullscreen?'true':'false')+", showMenu: false, autoBuffering: false, autoPlay: true, loop: false}" }
								});
								
								//console.log(this.placeholder);
								
								return true;
				    		}
						}
			    	
			    	}
					
					return false;
					
		    	}
		    	
		    	this.insertVideoPlayer = function(sourceType)
		    	{
		    	
		    		var clevermedia = this;
		    	
		    		var source = this.config.sources[sourceType];
		    		
		    		var video = document.createElement('video');
		    		
		    		video.src = source.url;
		    		
		    		$(video).width(this.config.preferredSize.width);
		    		$(video).height(this.config.preferredSize.height);
		    		
		    		video.controls = true;
		    		
		    		video.preload = false;
      				video.autobuffer = false;
      				
      				$(video).attr("poster", source.poster);	
		    		
		    		$(video).insertAfter(this.placeholder);
		    	
		    		this.media = video;
		    		
		    		$(video).bind("play, playing", function(){
		    			clevermedia.triggerCallbackPlay();
		    		});
		    		
		    		$(video).bind("pause", function(){
		    			clevermedia.triggerCallbackPause();
		    		});
		    		
		    		$(video).bind("ended", function(){
		    			clevermedia.triggerCallbackStop();
		    		});
		    	
		    		if (!this.isMobileDevice())
		    		{
		    			this.play();
		    		}
		    		
		    		this.placeholder.hide();
		    	
		    	}
		    	
		    	this.play = function(){
		    	
		    		if (!this.media)
		    		{
		    			this.bind();
		    		}
		    	
		    		this.media.load();
		    		this.media.play();
		    	}
		    	
		    	this.pause = function(){
		    	
		    		if (!this.media)
		    			return;
		    	
		    		this.media.pause();
		    	}
		    	
		    	
		    	this.triggerCallbackPlay = function(){
		    		// trigger the play callback if set
					if (this.config.callbackPlay)
						for (var cb = 0; cb < this.config.callbackPlay.length; cb++)
							this.config.callbackPlay[cb](this);
		    	}
		    	
		    	this.triggerCallbackPause = function(){
		    		// trigger the play callback if set
					if (this.config.callbackPause)
						for (var cb = 0; cb < this.config.callbackPause.length; cb++)
							this.config.callbackPause[cb](this);
		    	}
		    	
		    	this.triggerCallbackStop = function(){
		    		// trigger the play callback if set
					if (this.config.callbackStop)
						for (var cb = 0; cb < this.config.callbackStop.length; cb++)
							this.config.callbackStop[cb](this);
		    	}
		    	
		    	this.insertAudioPlayer = function(sourceType)
		    	{
		    		
		    		var source = this.config.sources[sourceType];
		    		
		    		var audio = document.createElement('audio');
		    		
		    		audio.src = source.url;
		    		
		    		$(audio).width(this.config.preferredSize.width);
		    		
		    		audio.controls = true;
		    		
		    		audio.preload = false;
      				audio.autobuffer = false;
		    		
		    		$(audio).insertAfter(this.placeholder);
		    		
		    		this.media = audio;
		    	
		    		if (!isMobileDevice())
		    		{
		    			this.play();
		    		}
		    			
		    		this.placeholder.hide();
		    		
		    		
		    	}
		    	
		    	this.isMobileDevice = function()
		    	{
		    		return navigator.userAgent.match(/(iPad|iPhone|Android)/i) !== null;
		    	}
		    	
		    	
		    	this.bind = function()
		    	{
		    		var flashSupport = this.hasFlash();
						
					var nativeSourceType = this.getFirstPlayableSourceType();
					
					// use native player if supported
					if (nativeSourceType && (!this.config.preferFlash || !flashSupport))
					{
					
						if (this.isVideoType(nativeSourceType))
							this.insertVideoPlayer(nativeSourceType);
						else
							this.insertAudioPlayer(nativeSourceType);
							
					} else if(flashSupport && ( !!this.config.sources.flv || !!this.config.sources.mp3)){
						this.insertFlashPlayer();
					} else
					{
						// was not able to find a method to embed!
					}
					
					// we cant play the file, remove the bindings
					$(this).unbind('click');
					this.placeholder.find(".play_button").remove();
					
		    	}
		    	
		    	
		    	// initialise	
				this.init = function()
				{
					
					var clevermedia = this;
					
					// allow you to define a single callback
					if ($.isFunction(this.config.callbackPlay))
						this.config.callbackPlay = [this.config.callbackPlay];
					if ($.isFunction(this.config.callbackStop))
						this.config.callbackStop = [this.config.callbackStop];
					if ($.isFunction(this.config.callbackPause))
						this.config.callbackPause = [this.config.callbackPause];
					
					// attach clevermedia to the element
					this.placeholder.data("clevermedia", this);
					
					
					if (this.config.wrapPlaceholder)
					{
					
						var wrap = $("<div>").addClass(this.config.wrapClass).css({position: "relative"}).width(this.placeholder.width());
						
						var play_button = $("<div>").addClass("play_button").html("<span>Click to play</span>");
						
						play_button.width(this.placeholder.width());
						play_button.height(this.placeholder.height());
						
						play_button.css({
							position: "absolute",
							top: 0,
							left: 0,
							cursor: "pointer"
						});
						
						
						wrap.insertAfter(this.placeholder);
						wrap.append(this.placeholder);
						wrap.append(play_button);
						
						this.placeholder = wrap;
						
						wrap.attr("id", clevermedia.id+"wrap")
					}

					
					// dont show placeholder image if mobile device
					// (iphone/android already show a decent placeholder)
					// or if we want it to autoplay
					if (this.isMobileDevice() || this.config.autoplay)
						this.bind();
					else
						this.placeholder.click(function(){
							clevermedia.bind()
						});
									
				}				
				
			
			}

		}
	});
	
})(jQuery);

