// ##################################### Djingle SDK ########################
// # ----| Copyright (C) Djingle 2008 - info@djngle.com
// ##########################################################################

//misc -------------------

var checkOpSystem = function (c_os) {

	var os_ok=new Array("win95","winMe","win98","win2K","winXP","winVista","Win","MacOSX");

	//alert(in_array(os_ok, c_os));
	if (in_array(os_ok, c_os) !=-1) {
		return true;
	} else {
		return false;
	}
};

/////////////////////////////////////////////////////////////////////////////
// Class DjPlugin: interface for Djingle plugin object
/////////////////////////////////////////////////////////////////////////////

var DjPlugin = function( djPlugin_element_id, instance_id, service_id, service_type ) {

	//### Properties ###########################################################
	this.pluginObject=null;
	this.debugMode=0;
	this.instanceId=0;
	this.serviceId=0;
	this.serviceType=0;
	this.lastPluginError="";
	
	//### Constructor ##########################################################
	this._Initialize = function( djPlugin_element_id, instance_id, service_id, service_type ) {
		if (!djPlugin_element_id) {
			this.returnError("djPlugin_element_id unknown!");
		} else {

			this.pluginObjectName = djPlugin_element_id;
			
			if (getOpSystem()=="MacOSX") {
				//on MacOSX: the wrapper
				var DJPLUGIN = new DJPLUGIN_(this.pluginObjectName);
				this.pluginObject = new DjComModule(DJPLUGIN);
			
			} else {
				//on PC: only the embed object
				this.pluginObject = document.getElementById( this.pluginObjectName );
			}
			
			//this.pluginStatus = 'idontknow';
			if (instance_id) 
				this.instanceId=instance_id;
			else
				this.returnError("instanceId unknown!");
			
			if (service_id) 
				this.setService(service_id, service_type);
			//else -> faire un getServiceList et prendre le 1er
		}
	};
   
	//##########################################################################
	//### Misc. ################################################################
	//##########################################################################
	this.Log = function( str ) {
		if (this.debugMode)
			this.logstr+= str + "\n";
	};

	this.showLog = function( str ) {
		if (this.debugMode)
			alert(this.logstr);
	};
    
    	this.resetLog = function() {
    		if (this.debugMode)
    			this.logstr='';
    	};

	this.setDebugMode = function ( debug_mode ) {
		if (debug_mode)
			this.debugMode=1;
		else 
			this.debugMode=0;
	};
	
	this.returnError = function(err) {
		alert("Error: "+ err);
		//todo: mieux
		return false;
	};
	
	this.testFunction = function(parametre) {
		alert("chez moi ca marche avec ce paramatre : "+parametre);
		return "chez moi ca marche avec ce paramatre : "+parametre;
	};
	
   
	//##########################################################################
	//### Connexion management #################################################
	//##########################################################################	
	this._isConnected = function() {
    		if (this.pluginStatus=="running")
    			return true;
    		return false;
    	};
    	
    	this._connectIfNeedBe = function() {
		this.pluginObject.Connect(this.instanceId);
   	};
    
    	this.connectAndCheckStatus = function() {
        	
		if (this.debugMode)
			document.write("<br /><font color=red>connectAndCheckStatus</font>");
		if (this._isConnected()==false) {
	
			try {
				var connection_test=this.pluginObject.Connect(this.instanceId);
				if (this.debugMode)
					document.write("<br />Connection test = "+connection_test);
				if ( connection_test == 1 ) {
					this.pluginStatus = "running";
				} else if ( connection_test == -1 ) {
					this.pluginStatus = "instance_not_installed";
				} else if ( connection_test == -2 ) {
					this.pluginStatus = "not_running";
				} else if ( connection_test == -9 ) {
					this.pluginStatus = "error";
				} else if ( connection_test == -10 ) {
					//mac only
					this.pluginStatus = 'not_installed';
				}
				//gérer cas "0";
				
			}
			catch(e) {
				if (this.debugMode)
					document.write("<br />Exception raised in Connect: "+e.message);
				this.pluginObject = null;
				this.pluginStatus = 'not_installed';
			}
			
		} else {
			this.pluginStatus = "running";
		}
		if (this.debugMode)
			document.write("<br />pluginStatus = "+this.pluginStatus);
		return true;
	};
	
	this.Start = function () {
	
		try {
			return this.pluginObject.Start();
		}
		catch(e) {
			//alert("Exception raised in Start");
			this.pluginObject = null;
			this.pluginStatus = 'not_installed';
			return false;
		}
	};

	this.Stop = function () {
	
		try {
			this._connectIfNeedBe();
			return this.pluginObject.Stop();
		}
		catch(e) {
			//alert("Exception raised in Stop");
			this.pluginStatus = 'not_running';
			return false;
		}
	};
	
	// ---- setService ---------------------------------------------------
	// -> used to set the current service
	// -------------------------------------------------------------------
	this.setService = function( service_id, service_type ) {

		if (service_id) this.serviceId=service_id;
		this.serviceType=service_type;//'dl'/'djingle'/'rss'
	};
	//##########################################################################
	//### Content list management ##############################################
	//##########################################################################
	// ---- getLocalLibrary ----------------------------------------------
	// -> gets local contents list (present + downloading)
	// -------------------------------------------------------------------
	this.getLocalLibrary = function () {
	
		this.Log('DjPlugin :: getLocalLibrary');
		var contentList = false;
		
		try {
			this._connectIfNeedBe();
			var my_JSON_text = false;
			my_JSON_text = this.pluginObject.GetContentList(this.serviceId, 'json');
	
			//alert("ds getLocalLibrary --> my_JSON_text = "+my_JSON_text);
					
			if ( my_JSON_text )
				eval( "contentList="+my_JSON_text );
			else {
				//error
				this.Log("!!! Error reading content list (GetContentList returned [empty])");
			}
		}
		catch(e) {
			this.Log("!!! Error reading content list :\n"+my_JSON_text+"\n"+e.message);
			this.pluginStatus = 'error';
			// TODO : re-check plugin ?
		}
		return contentList;
	};
	
	// ---- getPendingList -----------------------------------------------
	// -> gets pendings list
	// -------------------------------------------------------------------
	this.getPendingList = function () {

		this.Log('DjPlugin :: getPendingList');
		var contentList = false;
		
		try {
			this._connectIfNeedBe();
			var my_JSON_text = false;
			my_JSON_text = this.pluginObject.GetPendingList(this.serviceId, 'json');	
	
			if ( my_JSON_text )
				eval( "contentList="+my_JSON_text );
			else {
				//error
				this.Log("!!! Error reading pending list (GetPendingList returned [empty])");
			}
		}
		catch(e) {
			this.Log("!!! Error reading content list :\n"+my_JSON_text+"\n"+e.message);
			this.pluginStatus = 'error';
		}
		return contentList;
	};

	// ---- openDesktopInterface -----------------------------------------
	// -> opens widget (if widget handles this functionnality
	// -------------------------------------------------------------------
	this.openDesktopInterface = function( src_layer, interface_name, content_id, parameters ) {

		var tmp=document.getElementById(src_layer);//todo: position interface upon layer position
		if (content_id) {
			//add to params
			parameters.contentId=content_id;
		}
		
		var my_JSON_params = JSON.stringify(parameters);

		//alert(my_JSON_params);
		
		try  {
			this._connectIfNeedBe();
			return this.pluginObject.OpenInterface(interface_name, my_JSON_params);

		} catch (e) {
			this.Log("!!! An error occured while trying to pop the widget!\n"+e.message);
			this.pluginStatus = 'error';
			return false;
		}
	};
	
	//##########################################################################
	//### Download management ##################################################
	//##########################################################################
	// ---- addContentFromXMLInfo ----------------------------------------
	// -> launch content download from XML dl info (do not need a Djingle service)
	// 	-> not used anymore
	// -------------------------------------------------------------------
	this.addContentFromXMLInfo = function( content_info ) {
	
		this.Log("PLUGIN :: addContentFromXMLInfo( content_info="+content_info+" )");
    		try {
    			var content_info_xml = '';
    			if ( content_info ) {

				content_info_xml = // TODO
				    '<content_info>' + 
				    '    <title>'+ content_info.url +'</title>';
				if (content_info.id) {
					content_info_xml+=
				    '    <id>'+ content_info.id +'</id>';
				}
				if (content_info.extern_id) {
					content_info_xml+=
				    '    <extern_id>'+ content_info.extern_id +'</extern_id>';
				}
				content_info_xml+=
				    '    <description>'+ content_info.description +'</description>'+
				    '    <begin></begin>'+
				    '    <end></end>'+
				    '    <preview>'+ content_info.preview +'</preview>'+
				    '    <files>'+
				    '        <file id="main">'+
				    '            <src>'+ content_info.url +'</src>'+	// Should not need escaping // TODO ?
				    '            <dl>'+
				    '                <min_speed>'+ content_info.min_speed +'</min_speed>'+
				    '                <max_speed>'+ content_info.max_speed +'</max_speed>'+
				    '                <delay_webpeer>'+ content_info.delay_webpeer +'</delay_webpeer>'+
				    '                <qos_mode>'+content_info.qos_mode+'</qos_mode>'+
				    '                <no_p2p>'+((content_info.no_p2p)?1:0)+'</no_p2p>'+

			//			'                <playback_speed>'+content_info.playback_speed+'</playback_speed>'+	
			//			'                <delivery_time>'+content_info.delivery_time+'</delivery_time>'+	
			//			'                <webpeer_bw>'+content_info.webpeer_bw+'</webpeer_bw>'+	
				    '            </dl>'+
				    '        </file>'+
				    '    </files>'+
				    '</content_info>';

			} else {
				//????????????????
				//????????????????
			}

			this._connectIfNeedBe();
			var dl_rslt=this.pluginObject.AddContent(this.serviceId, contentInfoXml);

			if ( !dl_rslt ) {
				this.Log( "!!! Error: no Id returned by AddDownload");
			} else {
				return dl_rslt;
			}
		}
		catch (e) {
			this.Log( "!!! Error: cannot download content: "+e.message );
			this.pluginStatus = 'error';
		}
		return false;		
	};
	
	// ---- addContent ---------------------------------------------------
	// -> launch content download using Json dl info (do not need a Djingle service)
	//	--> this function requires contents with files binded as 'main'
	// -------------------------------------------------------------------
	this.addContent = function( content_info ) {
		this.Log("PLUGIN :: addContent( content_info="+content_info+" )");
		
		var content_info_obj = new Object;
		content_info_obj.title=content_info.url;

		if (content_info.id)
			content_info_obj.id=content_info.id;

		content_info_obj.description=content_info.description;
		//content_info_obj.begin
		//content_info_obj.end
		content_info_obj.preview=content_info.preview;
		
		content_info_obj.files = new Object;
		content_info_obj.files.main = new Object;
		content_info_obj.files.main.src=content_info.url;
		content_info_obj.files.main.path=content_info.path;
		content_info_obj.files.main.djqos=true;//!!!!!!!!!!!!!!! dynamique
		content_info_obj.files.main.dl = new Object;
		content_info_obj.files.main.dl.min_speed = content_info.min_speed;
		content_info_obj.files.main.dl.max_speed = content_info.max_speed;
		content_info_obj.files.main.dl.delay_webpeer = content_info.delay_webpeer;
		content_info_obj.files.main.dl.qos_mode = content_info.qos_mode;
		content_info_obj.files.main.dl.no_p2p = ((content_info.no_p2p)?1:0);
		content_info_obj.files.main.dl.hashfile = content_info.hashfile;
		//content_info_obj.files.main.dl.playback_speed = content_info.playback_speed;
		//content_info_obj.files.main.dl.delivery_time = content_info.delivery_time;
		//content_info_obj.files.main.dl.webpeer_bw = content_info.webpeer_bw;
		
		var my_JSON_content_info = JSON.stringify(content_info_obj);
		//alert(my_JSON_content_info);
			
		try {
			this._connectIfNeedBe();
			var dl_rslt=this.pluginObject.AddContent(this.serviceId, my_JSON_content_info);
			
			if ( !dl_rslt ) {
				this.Log( "!!! Error: cannot add content: "+e.message );
			} else {
				return dl_rslt;
			}
		}
		catch (e) {
			this.Log( "!!! Error: cannot add content: "+e.message );
			this.pluginStatus = 'error';
		}
		return false;
	};
	
	// ---- downloadContent ----------------------------------------------
	// -> launch content download (needs Djingle service)
	// -------------------------------------------------------------------
	this.downloadContent = function( content_id ) {

		this.Log("PLUGIN :: downloadContent( content_id="+content_id+" / Instance="+this.instanceId+"/ Service = "+this.serviceId+")");
		try {
			this._connectIfNeedBe();
			
			var dl_rslt=this.pluginObject.DownloadContent(this.serviceId, content_id, false);
			//alert("ici avec xxxx"+dl_rslt+"yyy");

			if ( !dl_rslt ) {
				this.Log( "!!! Error: no Id returned by DownloadContent");
				//alert("Error: no Id returned by DownloadContent");
			} else {
				return dl_rslt;
			}
		}
		catch (e) {
			
			this.Log( "!!! Error: cannot download content" + content_id + ": "+e.message );
			this.pluginStatus = 'error';
		}
		return false;
	};

	// ---- downloadContentFromExternId ----------------------------------
	// -> launch content download using extern_id (needs Djingle service)
	// -------------------------------------------------------------------
	this.downloadContentFromExternId = function( extern_id ) {
	
		try {
			this._connectIfNeedBe();
			var dl_rslt=this.pluginObject.DownloadContent(this.serviceId, extern_id, true);

			if ( !dl_rslt ) {
				this.Log( "!!! Error: no Id returned by DownloadContent");
			} else {
				return dl_rslt;
			}
		}
		catch (e) {
			
			this.Log( "!!! Error: cannot download content " + extern_id + ": "+e.message );
			this.pluginStatus = 'error';
		}
		return false;

	};
	
	// ---- getDownloadInfo ----------------------------------------------
	// -> gets content download info (file by file)
	// -------------------------------------------------------------------
	this.getDownloadInfo = function( content_id ) {

		this.Log("PLUGIN :: getDownloadInfo( content_id="+content_id+" )");

		var dl_info = false;
		try {
			this._connectIfNeedBe();
			var my_JSON_text = false;
			my_JSON_text = this.pluginObject.GetDlParams(this.serviceId, content_id, 'json');
	
			if ( my_JSON_text ) {
				eval( "dl_info="+my_JSON_text );
			} else {
				//content dl not found
				return false;
			}
		}
		catch(e) {
			this.Log("!!! Error reading content dl infos :\n"+my_JSON_text+"\n"+e.message);
			this.pluginStatus = 'error';
			// TODO : re-check plugin ?
		}
		return dl_info;		
	};

	// ---- updateDownload -----------------------------------------------
	// -> updates all QoS-managed files with the same dl parameters 
	// -------------------------------------------------------------------
	this.updateDownload = function( content_id, content_dl_info ) {

		this.Log("PLUGIN :: updateDownload( content_id="+content_id+" )");

		var dl_info = false;
		//get download infos
		dl_info = this.getDownloadInfo(content_id);
		
		if (dl_info) {
		
			//update infos
			var files_info_obj=new Object;

			for (var file in dl_info) {
			
			   	if ( files_info_obj[file].djqos ) {
					files_info_obj[file] = new Object;
					files_info_obj[file].dl = new Object;
					files_info_obj[file].dl = content_dl_info;
				}
			}
			var my_JSON_text = JSON.stringify(files_info_obj);
			
			try {
				this._connectIfNeedBe();
				return this.pluginObject.UpdateDlParams(this.serviceId, content_id, my_JSON_text);
			}
			catch(e) {
				this.Log("!!! Error updating download:\n"+my_JSON_text+"\n"+e.message);
				this.pluginStatus = 'error';
				// TODO : re-check plugin ?
			}
		}
		return false;
	};

	// ---- updateFilesDownload -------------------------------------------
	// -> allows to apply new dl settings to some of the files of the content
	//	--> files_ids must be an array (index => file_id)
	//	--> files_dl_info must be an array (index => file_dl_info)
	// -------------------------------------------------------------------
	this.updateFilesDownload = function (content_id, files_ids, files_dl_info) {
	
		this.Log("PLUGIN :: updateFilesDownload( content_id="+content_id+" )");
		//get download infos
		var dl_info = this.getDownloadInfo(content_id);
		
		if (dl_info) {
		
			//update infos
			var files_info_obj=new Object;

			for (var file in files_ids) {
				files_info_obj[files_ids[file]] = new Object;
				files_info_obj[files_ids[file]].dl = new Object;
				files_info_obj[files_ids[file]].dl = files_dl_info[file];
			}
			var my_JSON_text = JSON.stringify(files_info_obj);

			try {
				this._connectIfNeedBe();
				return this.pluginObject.UpdateDlParams(this.serviceId, content_id, my_JSON_text);
			}
			catch(e) {
				this.Log("!!! Error updating download of certain files:\n"+my_JSON_text+"\n"+e.message);
				this.pluginStatus = 'error';
				// TODO : re-check plugin ?
			}
		}
		return false;
	};


	//##########################################################################
	//### Advanced Download management #########################################
	//##########################################################################
	// ---- _pauseResumeDownload -----------------------------------------
	// -> utility toggle method to manage pause/resume dl 
	// -------------------------------------------------------------------
	this._pauseResumeDownload = function( content_id, pause ) {
		this.Log("PLUGIN :: pauseDownload( content_id="+content_id+", pause="+pause+" )");
    		try {
       			this._connectIfNeedBe();
       			return this.pluginObject.PauseDownload( this.serviceId, content_id, (pause)?1:0 );
    		} 
		catch (e) {
			this.Log( "!!! Error : cannot _pauseResumeDownload: "+e.message );
			this.pluginStatus = 'error';
		}
		return false;		
	};

	this.pauseDownload = function( content_id ) {
		return this._pauseResumeDownload( content_id, true ); 
	};
	
	this.resumeDownload = function( content_id ) {
		return this._pauseResumeDownload( content_id, false ); 
	};
	
	this.togglePauseDownload = function( content_id ) {
		if ( this.getContent( content_id ).status=="download_paused" )
			return this._pauseResumeDownload( content_id, false );
		else
			return this._pauseResumeDownload( content_id, true );
	};
	
	// ---- _disableEnablePending ----------------------------------------
	// -> utility method to manage pendings 
	// -------------------------------------------------------------------
	this._disableEnablePending = function( content_id, disable ) {
		this.Log("PLUGIN :: disablePending( content_id="+content_id+", disable="+disable+" )");
		try {
			this._connectIfNeedBe();
			return this.pluginObject.DisablePending( this.serviceId, content_id, (disable)?1:0 );
		}
		catch (e) {
			this.Log( "!!! Error : cannot _disableEnablePending: "+e.message );
			this.pluginStatus = 'error';
		}
		return false;		
	};
	
	this.enablePending = function( content_id ) {
		return this._disableEnablePending( content_id, false );
	};
	
	this.disablePending = function( content_id ) {
		return this._disableEnablePending( content_id, true );
	};
	
	this.toggleDisablePending = function( content_id ) {
		if ( this.getContent( content_id ).disabled )
			return this._disableEnablePending( content_id, false );
		else
			return this._disableEnablePending( content_id, true );
	};

	//##########################################################################
	//### Content management ###################################################
	//##########################################################################
	// ---- deleteContent ------------------------------------------------
	// -> removes a content from the hard drive
	// -------------------------------------------------------------------
	this.deleteContent = function( content_id ) {
		this.Log("PLUGIN :: deleteContent( content_id="+content_id+" )");
		try {
			this._connectIfNeedBe();
			return this.pluginObject.DeleteContent( this.serviceId, content_id );
		} 
		catch (e) {
			this.Log( "!!! Error : cannot DeleteContent"+e.message );
			this.pluginStatus = 'error';
		}
		return false;		
	};

	// ---- getContent ---------------------------------------------------
	// -> gets content info
	// -------------------------------------------------------------------
	this.getContent = function( content_id ) {

		this.Log('DjPlugin :: getContent --> pluginStatus = '+this.pluginStatus);
		var the_content = false;
		
		try {
			this._connectIfNeedBe();
			var my_JSON_text = false;
			
			//this.pluginObject.Connect('client1');
			my_JSON_text = this.pluginObject.GetContent(this.serviceId, content_id, 'json');
	
			if ( my_JSON_text ) {
				//alert("ds getContent --> my_JSON_text = "+my_JSON_text);
			
				eval( "the_content="+my_JSON_text );
			} else {
				//content does not exist
				return false;
			}
		}
		catch(e) {
			this.Log("!!! Error getting content :\n"+my_JSON_text+"\n"+e.message);
			this.pluginStatus = 'error';
		}
		return the_content;
	};
	
	// ---- getLocalUrl --------------------------------------------------
	// -> utility method to get local URL of the video file to play in the player
	// -------------------------------------------------------------------
	this.getLocalUrl = function( content_id ) {
		this.Log("PLUGIN :: getLocalUrl( content_id="+content_id+" )");
		return this.getContent( content_id ).local_url;
	};

	
	//##########################################################################
	//## Initialize object #####################################################
	//##########################################################################
	this._Initialize( djPlugin_element_id, instance_id, service_id, service_type);
};