/**
 * jQuery audiorecorder plugin
 * @version		$Id: jquery.maxlength.js 18 2009-05-16 15:37:08Z emil@anon-design.se $
 * @package		jQuery audiorecorder
 * @copyright	Copyright (C) 2010 Mark Lynch / http://www.learnosity.com
 * @license		Released under the MIT, BSD, and GPL Licenses.
 * 
 * 
 * Usage:
 * Attach audio recorder to input nodes where you want to record the filename of the recorded audio.
 * 
 * <input type="text" class="recorder" id="audio_1">
 * 
 * jQuery('.recorder').audiorecorder();
 * jQuery('.player').audioplayer();
 * 
 * Note jquery swfobject must be loaded before this
 */

(function($){
	var opts;

	//The input field of the current control that is being used
	var currentControl;
	var mp3url;
	var swf; 
	
	//Arrays which holds references to all active controls
	var allPlayControls = [];
	var allRecControls = [];
	
	
	$.fn.audioplayer = function(options) {  
		// Extend our default options with those provided.
		// Note that the first arg to extend is an empty object -
		// this is to keep from overriding our "defaults" object.
		opts = $.extend({}, $.fn.audiorecorder.defaults, $.fn.audioplayer.defaults, opts, options);
		
		$.fn.audiorecorder.doSwfSetup(opts);
		
		
		//Loop over each item to add a recorder to (should be input type)
		return this.each(function() {
			//console.log(this);
				
			//Register control
			allPlayControls.push(this);
			
			
			$(this).click(function(e){
				e.preventDefault();
				$.fn.audiorecorder.impl.startStopPlayer(this);
			});
			
		});
	};
	
	// plugin defaults - added as a property on our plugin function
	$.fn.audioplayer.defaults = {
		swf: 'audiorecorder/JSAudioRecorder.swf',
		startupCheckTime: 200
	};
  
	
	$.fn.audiorecorder = function(options) {  
	 
		// Extend our default options with those provided.
		// Note that the first arg to extend is an empty object -
		// this is to keep from overriding our "defaults" object.
		opts = $.extend({}, $.fn.audiorecorder.defaults, $.fn.audioplayer.defaults, opts, options);
		
		// Our plugin implementation code goes here.
		
	
		$.fn.audiorecorder.doSwfSetup(opts);
		
		//Loop over each item to add a recorder to (should be input type)
		return this.each(function() {
			//Register control
			allRecControls.push(this);

			//Wrap a div around item and hide form
			$(this).wrap('<div class="audiorecorder_main"></div>'); //.hide();
			
			var recControls = $('<span class="audiorecorder_reccontrols"></span>');
						
			//Then create controls for recorder
			var btnDelete = $("<span class='audiorecorder_btndelete audiorecorder_btn' title='Delete this audio'></span>").click(function(e){
				e.preventDefault();
				currentControl = $(this).siblings('input');
				if(window.confirm("Are you sure you wish to delete this audio file?")){
					$(currentControl).attr('value',"");
					$(btnDelete).hide();
					$(btnPlayMp3).hide();
					$(btnMic).show();
					//If there is a delete function then call it
					if(opts.onDelete){
						opts.onDelete();
					}
				}				
				
			});

			var btnRec = $("<span class='audiorecorder_btnrec audiorecorder_btn' title='Start recording audio'></span>").click(function(e){
				e.preventDefault();
				currentControl = $(this).parent().siblings('input');
				$.fn.audiorecorder.js2flex({cmd:'setFilePrefix',prefix:opts.prefix});
				$.fn.audiorecorder.js2flex({cmd:'record'});
				$(btnRec).hide();
				$(btnStop).show();
			});
			
			var btnStop = $("<span class='audiorecorder_btnstop audiorecorder_btn' title='Stop'></span>").click(function(e){
				e.preventDefault();
				currentControl = $(this).parent().siblings('input');
				$.fn.audiorecorder.js2flex({cmd:'stop'});
				$(btnStop).hide();
				$(btnPlay).show();			
				$(btnOK).show();			
			});
						
			var btnPlay = $("<span class='audiorecorder_btnplay audiorecorder_btn' title='Play audio'></span>").click(function(e){
				e.preventDefault();
				currentControl = $(this).parent().siblings('input');
				$.fn.audiorecorder.js2flex({cmd:'preview'});
				$(btnStop).show();
				$(btnPlay).hide();
			});
			var btnPlayMp3 = $("<span class='audiorecorder_btnplaymp3 audiorecorder_btn' title='Play audio'></span>").click(function(e){
				e.preventDefault();
				
				$.fn.audiorecorder.impl.startStopPlayer($(currentControl));	
				$.fn.audiorecorder.callHandler({e:'mp3Complete'});
						
				currentControl = $(this).siblings('input');
				mp3url = opts.mp3baseurl + $(this).siblings('input').attr('value') + '.mp3'; 
				$.fn.audiorecorder.js2flex({cmd:'playMP3',file:mp3url});
				$(btnStopMp3).show();
				$(btnPlayMp3).hide();
			
			});			
			var btnStopMp3 = $("<span class='audiorecorder_btnstopmp3 audiorecorder_btn' title='Stop'></span>").click(function(e){
				e.preventDefault();
				currentControl = $(this).siblings('input');
				$.fn.audiorecorder.js2flex({cmd:'stopMP3'});
				$(btnPlayMp3).show();
				$(btnStopMp3).hide();

			});			

			
			var btnMic =  $("<span class='audiorecorder_btnmic audiorecorder_btn' title='Record an audio comment'></span>").click(function(e){
				e.preventDefault();
				currentControl = $(this).siblings('input');

				$(btnPlay).hide();
				$(btnStop).hide();
				$(btnOK).hide();		
				$(btnRec).show();		
				$(recControls).show();
				$(btnDelete).hide();
				
				$.fn.audiorecorder.js2flex({cmd:'showPrivacySettings'});
								
				var micAuth = $.fn.audiorecorder.js2flex({cmd:'isMicAuthorised'});
				//alert($.fn.audiorecorder.js2flex);
				//alert(micAuth);
				if(! micAuth){
					var leftPos = Math.round(( $(window).width() - $('#audiorecorderswfdiv').width() ) / 2+$(window).scrollLeft());
					var topPos = Math.round(( $(window).height() - $('#audiorecorderswfdiv').height() ) / 2+$(window).scrollTop());
					$('#audiorecorderswfdiv').css({"left": leftPos+"px"});
					//$('#audiorecorderswfdiv').css({"top": Math.round(topPos)+"px" });
					$('#audiorecorderswfdiv').animate({left: leftPos, top: topPos },500);
				}
				
				//Attempt to connected if not connected
				if(! $.fn.audiorecorder.js2flex({cmd:'isConnected'})){
					$.fn.audiorecorder.js2flex({cmd:'connect',URI:opts.rtmpURI});
				}
			});
			var btnError =  $("<span class='audiorecorder_btnerror audiorecorder_btn'></span>").click(function(e){
				e.preventDefault();
				currentControl = $(this).siblings('input');
				
				//Attempt to connected if not connected
				if(! $.fn.audiorecorder.js2flex({cmd:'isConnected'})){
					$.fn.audiorecorder.js2flex({cmd:'connect',URI:opts.rtmpURI});
					$(btnWait).show();
					$(this).hide();
				}else{
					alert('Error button pressed but already connected');
				}
			});
			var btnOK =  $("<span class='audiorecorder_btnok audiorecorder_btn' title='Save audio comment'></span>").click(function(e){
				e.preventDefault();
				currentControl = $(this).parent().siblings('input');
				var curFileName = $.fn.audiorecorder.js2flex({cmd:'getFilename'});
				//console.log(curFileName);
				$(currentControl).attr('value',curFileName);
						
				$(btnOK).hide();		
				$(btnRec).show();		
				$(recControls).hide();
				$(btnDelete).show();
				$(btnMic).hide();
				$(btnDelete).show();
				
				//If there is a save function then call it
				if(opts.onSave){
					opts.onSave(curFileName);
				}
				
			});
			var btnCancel =  $("<span class='audiorecorder_btncancel audiorecorder_btn' title='Cancel audio comment'></span>").click(function(e){
				e.preventDefault();
				currentControl = $(this).parent().siblings('input');
				$(recControls).hide();
				
			});		
			var btnWait =  $("<span class='audiorecorder_btnwait audiorecorder_btn' title='Waiting...'></span>").click(function(e){
				e.preventDefault();
			});
			
			// Add the controls to the page and then hide appropriately
			$(recControls).append(btnRec).append(btnStop).append(btnPlay).append(btnCancel).append(btnOK);
			$(recControls).hide();

			$(this).after(btnDelete).after(btnError).after(btnWait).after(recControls).after(btnMic).after(btnPlayMp3).after(btnStopMp3);
			$(btnError).hide();
			$(btnWait).hide();
			$(btnStopMp3).hide();

			//If already have a recorder audio then hide Mic and show delete option
			if($(this).attr('value').length){
				$(btnMic).hide();
				$(btnDelete).show();
				$(btnPlayMp3).show();
			}else{
				$(btnMic).show();
				$(btnDelete).hide();
				$(btnPlayMp3).hide();
			}			
		});
	};
	
	
	$.fn.audiorecorder.js2flex = function (o) {
		try
		  {
			var swfID = $('#audiorecorderswfdiv').children()[0].id;
		
			var swf = document.getElementById(swfID);
		
			retObj = swf.js2flex(o);
			//console.log(retObj);
			return retObj;
		  }
		catch(err)
		{
			//console.log('Caught an error: '+err);
		}
		
	};
	
	//Add the appropriate swf file this depends on jquery swfobject
	$.fn.audiorecorder.doSwfSetup = function(opts){
		//Check if swf is already loaded
		if(!swf){
			//Create div to hold swf
			$('body').append('<div id="audiorecorderswfdiv"><span id="audiorecorderswfspan"></span><br />To record Audio you must select Allow above. <br />Select \'Remember\' to stop this dialog coming up every time <br /><a href="javascript:void(0);" class="closeSwf" title="Close This Window"></a></div>');
			
			swf = true;
			swfobject.embedSWF(opts.swf,'audiorecorderswfspan','215','138','10',null,null,null,null,function(e){$.fn.audiorecorder.checkFlashLoaded();});

			$( ".closeSwf" ).bind(
				"click",
				function(objEvent){
					//alert("Close");
					var leftPos = Math.round(( $(window).width() - $('#audiorecorderswfdiv').width() ) / 2+$(window).scrollLeft());
					var topPos = Math.round(( $(window).height() - $('#audiorecorderswfdiv').height() ) / 2+$(window).scrollTop());
					
					$('#audiorecorderswfdiv').css({"top": Math.round(topPos)+"px" });
					
					$('#audiorecorderswfdiv').animate({left: leftPos, top: -topPos },500);
			});
		}
	}

	
	// Polls to check if swf plugin is loaded and available
	$.fn.audiorecorder.checkFlashLoaded =  function(){
		//TODO: This should probably only try for a number of seconds

		var swf = document.getElementById($('#audiorecorderswfspan').get(0).id);
		//console.log(swf);
		//console.log(swf.js2flex);
		//$('#audiorecorderswfdiv').append($('#audiorecorderswfdiv').children()[0].id);
		//$('#audiorecorderswfdiv').append(' Checking..<br>');
		if(swf.js2flex){
			// Swf is loaded - display the record icons
			$.fn.audiorecorder.js2flex({cmd:'setJSHandler',handler:'jQuery.fn.audiorecorder.callHandler'});
			//$('.audiorecorder_main').show();
			
		}else{
			//Try again soon
			setTimeout("jQuery.fn.audiorecorder.checkFlashLoaded()", opts.startupCheckTime);
		}
	}
	

	$.fn.audiorecorder.callHandler =  function(o){
		//Check for event object returned
		if(o.e){
			// console.log(o);
						
			switch(o.e){
			case "connected":
				$(currentControl).siblings('.audiorecorder_btnerror').hide().attr('title','');
				//console.log($(currentControl).siblings('.audiorecorder_btnwait'));
				$(currentControl).siblings('.audiorecorder_btnwait').hide();

				$(currentControl).siblings('.audiorecorder_reccontrols').contents('.audiorecorder_btnrec').show();
				$(currentControl).siblings('.audiorecorder_reccontrols').contents('.audiorecorder_btnplay').hide();
				$(currentControl).siblings('.audiorecorder_reccontrols').contents('.audiorecorder_btnpause').hide();
				$(currentControl).siblings('.audiorecorder_reccontrols').contents('.audiorecorder_btnstop').hide();
				$(currentControl).siblings('.audiorecorder_reccontrols').contents('.audiorecorder_btnok').hide();
				break;
			case "diconnected":
				//console.log(o);
				$(currentControl).siblings('.audiorecorder_btnerror').show().attr('title','Could not connect:Disconnected');
				$(currentControl).siblings('.audiorecorder_reccontrols').hide()
				$(currentControl).siblings('.audiorecorder_btnwait').hide()
				break;
			case "connectionfailed":
				$(currentControl).siblings('.audiorecorder_btnerror').show().attr('title','Could not connect:Connection Failed');
				$(currentControl).siblings('.audiorecorder_reccontrols').hide()
				$(currentControl).siblings('.audiorecorder_btnwait').hide()
				break;
			case "invalidApp":
				$(currentControl).siblings('.audiorecorder_btnerror').show().attr('title','Could not connect:Invalid Application');
				$(currentControl).siblings('.audiorecorder_reccontrols').hide()
				$(currentControl).siblings('.audiorecorder_btnwait').hide()
				break;
			case "onPlayComplete":
				//If not then use sibling selector to reenable play button
				// console.log($(this));				
				$(currentControl).siblings('.audiorecorder_reccontrols').children('.audiorecorder_btnplay').show();
				$(currentControl).siblings('.audiorecorder_reccontrols').children('.audiorecorder_btnstop').hide();
				break;
			case "onMetaData":
				// console.log('onMetaData');
				break;
			case "mp3Complete":
				// console.log('mp3Complete');
							
				if(currentControl.length < 1) currentControl = [ document ];
					
				if($(currentControl).get(0).nodeName == "INPUT"){					
					$(currentControl).siblings('.audiorecorder_btnplaymp3').show();
					$(currentControl).siblings('.audiorecorder_btnstopmp3').hide();					
				}else{
					$.fn.audiorecorder.impl.resetPlayer($(currentControl));
				}
				break;
				
			case "mp3LoadFailed":
				//console.log(o);
				// console.log($(currentControl).nodeName);
				$(currentControl).show();
				$(currentControl).removeClass('playing');
				$(currentControl).siblings('.audiorecorder_btnstopmp3').hide();
				alert('Audio not currently available:\n'+mp3url);
				break;
			case "micMuted":
				//alert('Mic Muted');
				//$('#audiorecorderswfdiv').show();	
				break;
			case "micUnmuted":
				var leftPos = Math.round(( $(window).width() - $('#audiorecorderswfdiv').width() ) / 2+$(window).scrollLeft());
				var topPos = Math.round(( $(window).height() - $('#audiorecorderswfdiv').height() ) / 2+$(window).scrollTop());
			//	$('#audiorecorderswfdiv').hide();
				
				//$('#audiorecorderswfdiv').animate({left: '-1000'},5000).attr('style',"left: -1000px;");
				$('#audiorecorderswfdiv').animate({left: leftPos, top: -topPos },500);
				

				//alert('Mic Un Muted - good to go');
				//jQuery.modal.close();
				break;
			
			}
			
			
		}
		
	};
	
	
	// plugin defaults - added as a property on our plugin function
	$.fn.audiorecorder.defaults = {
		rtmpURI: 'rtmp://localhost/voiceRecorder',
		swf: 'audiorecorder/JSAudioRecorder.swf',
		mp3baseurl: '/assets/',
		prefix: '',
		startupCheckTime: 200,
		onSave: null,
		onDelete: null
	};
	
	$.fn.audiorecorder.impl = {
			//Reset a player object to be ready to play - i.e. if playback has completed
			resetPlayer: function(player){
				$(player).removeClass('playing');
			
				if($.fn.audiorecorder.js2flex({cmd:'isMP3Playing'})){
					$.fn.audiorecorder.js2flex({cmd:'stopMP3'});
					$.fn.audiorecorder.callHandler({e:'mp3Complete'});
				}
				
			},
	
			startStopPlayer: function(player){
				//Check if we are changing controls
				if(currentControl != player){
					$.fn.audiorecorder.impl.resetPlayer($(currentControl));
				}
				
				currentControl = player;
				
				if($.fn.audiorecorder.js2flex({cmd:'isMP3Playing'})){
					$.fn.audiorecorder.js2flex({cmd:'stopMP3'});
					$(player).removeClass('playing');
				}else{
					mp3url = $(player).attr('href');  
					// console.log(mp3url);
					$.fn.audiorecorder.js2flex({cmd:'playMP3',file:mp3url});
					$(player).addClass('playing');
				}
				
			}
			
			
	};
	
// end of closure
})(jQuery);

