/**************************************************************************
*
*  @@@BUILDINFO@@@ 04cdicmanager-2.jsx 3.5.0.7		08-December-2008
*  ADOBE SYSTEMS INCORPORATED
*  Copyright 2010 Adobe Systems Incorporated
*  All Rights Reserved.
* 
* NOTICE:  Adobe permits you to use,  modify, and  distribute this file in
* accordance with the terms of the Adobe license agreement accompanying it.
* If you have received this file from a source other than Adobe, then your
* use, modification, or distribution of it requires the prior written
* permission of Adobe.
*
**************************************************************************/

///////////////////////////////////////////////////////////////////////////////
//
// class CDICManager
//

//-----------------------------------------------------------------------------
// 
// CDICManager(...)
// 
// Purpose: ctor
// 
//-----------------------------------------------------------------------------

Feature.COMPATIBILITY_CS3 = 500;
Feature.COMPATIBILITY_CS4 = 501;
Feature.TO_FRONT		  = 502;

function CDICManager()
{
    this.cdic               = {};           // list of CDIC object,
                                            // index : cdic name
    this.synchronousCalls   = {};           // synchronous calls
    
    cdi.onTask = this.processCDITask;

    var cdics = cdi.getCDIComponents();
    
    if( cdics.length > 0 )
    {
        var names = cdics.split( '\n' );
        
        for( var i=0; i<names.length; i++ )
        {
            var name = names[i];

            this.cdic[name]             = cdi.getCDIComponent(name);
            this.cdic[name].mgr         = this;
            this.cdic[name].onTask      = this.processCDICTask;

			if( name == "BTBackend" )
			{
				this.cdic[name].features[Feature.COMPATIBILITY_CS3].supported = prefs.cmp.CS3.getValue( Preference.BOOLEAN );
				this.cdic[name].features[Feature.COMPATIBILITY_CS4].supported = prefs.cmp.CS4.getValue( Preference.BOOLEAN );
			}

			this.cdic[name].features[Feature.TO_FRONT].supported = prefs.toFront.getValue( Preference.BOOLEAN );
        }
    }
}

CDICManager.prototype.getCDICs = function()
{
    var cdics = [];
    
    for( var i in this.cdic )
        cdics.push( this.cdic[i] );
        
    return cdics;
}

CDICManager.prototype.callSynchronous = function( task, timeout )
{
    this.synchronousCalls[task.id] = [];
    task.cdicMgr = this;
    
    task.onResult = function()
    {
        if( this.cdicMgr.synchronousCalls[this.id] )
            this.cdicMgr.synchronousCalls[this.id] = [ this.result ];
    }
    
    task.onError = function()
    {
        if( this.cdicMgr.synchronousCalls[this.id] )
            this.cdicMgr.synchronousCalls[this.id] = [ null , [this.errorCode, this.errorMessage ] ];
    }
    
    task.onTimeout = function()
    {
        if( this.cdicMgr.synchronousCalls[this.id] )
            this.cdicMgr.synchronousCalls[this.id] = [ null, null, true ];
    }
    
   if( timeout && timeout > 0 )
        task.submit( timeout );
    else
        task.submit();
    
	var id = task.id;
    var abort = false;
    
    while( !abort && this.synchronousCalls[id].length == 0 )
    {
        cdi.pump();
        abort = !app.pumpEventLoop();
        $.sleep (20);
    }
    
    return this.synchronousCalls[id];
}

CDICManager.getSynchronousResult = function( resultVector )
{
	return ( resultVector ? resultVector[0] : undefined );
}

CDICManager.getSynchronousError = function( resultVector )
{
	return ( resultVector ? resultVector[1] : undefined );
}

CDICManager.prototype.processCDITask = function( task )
{
    switch( task.name )
    {
        case Job.ERROR:
        {
            errorBox( task.errorMessage, localize( "$$$/ESToolkit/Alerts/ErrorTitle=%1 Error", "CDIC internal" ) );
            task.quitTask();
        }
        break;
    }
}

CDICManager.prototype.processCDICTask = function( task )
{
    this.setCDICPrefValue = function( key, value )
    {
        if( key )
        {
            key = 'prefs.cdic.' + key.toString();
            
            if( value )
                value = value.toString();
                
            var evalStr = evalStr = key + '=' + value;
        
            if( typeof value == 'string' )
                evalStr = key + '=\"' + value + '\"';

            eval( evalStr );
        }
    }
    
    this.getCDICPrefValue = function( key )
    {
        var value = null;
        
        if( key )
        {
            key = 'prefs.cdic.' + key.toString();

			var exists = eval( key + '.hasValue();' );
            
			if( exists )
				value = eval( key );
        }
        
        return value;
    }

	try
	{
		switch( task.name )
		{
			case Job.PRINT:
			{
				//alert( task.message );
				console.write( task.message );
			}
			break;
	                
			case Job.OPEN_DOC:
			{
				var doc = null;
				var f   = new File( task.scriptID );

				if (f.exists)
					doc = scripts.loadFile (f);
	            
				app.toFront();
				
				if( doc )
					docMgr.activateDocument( doc );

				task.quitTask();
			}
			break;
	        
			case Job.GET_BIN4SRC:
			{
				var ret = '';
				var file = File.openDlg( localize( "$$$/ESToolkit/FileDlg/Bin4Src=Select source file for " ) + task.scriptID, "*.*", true );
	            
				if( file )
					ret = file.absoluteUri;
	                
				task.returnResult( ret );
			}
			break;
	        
			case Job.GET_SRC4BIN:
			{
				var ret = '';
				var file = File.openDlg( localize( "$$$/ESToolkit/FileDlg/Src4Bin=Select binary file for " ) + task.scriptID, "*.*", true );
	            
				if( file )
					ret = file.absoluteUri;
	                
				task.returnResult( ret );
			}
			break;
	        
			case Job.NEW_ADDRESSES:
			{
				for( var i=0; i<task.addresses.length; i++ )
				{
					var addr = new Address( task.addresses[i] );
	                
					// we don't want create new sessions here
					// pwollek 07/28/08: why not? If the cdic send a new address
					//                   including an engine then the ESTK has
					//                   to add a new session!
					// addr.engine = '';

					var target = targetMgr.addTarget( addr, true, !app.remoteLaunched );
	                
					if( target && !target.getConnected() && !target.getChangeConnectState() )
						target.connect( true, undefined, undefined, undefined, true );
				}
	            
				if( task.addresses.length == 1 && app.remoteLaunched )
				{
					//
					// ESTK was launched by a remote connect request
					// open a new document and set the target to the calling
					// application. But not, if a debugging request follows (that
					// would clear the flag 'remoteLaunched')!
					//
					var src = """if( remoteLaunched )
								 {
									 var docwin = docMgr.create();
									 if( docwin && docwin.docObj && ( docwin.docObj instanceof SourceDocument ) )
									 {
										 var addr   = new Address('""" + task.addresses[0].toString() + """');
										 var target = targetMgr.findTarget( addr );

										 if( target )
										 {
											 targetMgr.setActive( target );
											 docwin.docObj.selectActiveTarget( target );
										 }
									 }
								 }""";

					app.scheduleTask( src, 200 );
				}

				task.returnResult( true );
			}
			break;
	        
			case Job.REMOVE_ADDRESS:
			{
				var target = targetMgr.findTarget( task.address );
	            
				if( target )
				{
					var session = target.findSession( task.address );
	                
					if( session )
						target.removeSession( session );
	                    
					if( !session || target.sessions.length == 0 )
						targetMgr.removeTarget( target );
				}
	            
				task.quitTask();
			}
			break;
	        
			case Job.CHANGE_ADDRESS:
			{
				var targetOld = targetMgr.findTarget( task.oldAddress );
				var targetNew = targetMgr.findTarget( task.newAddress );
	            
				if( targetOld == targetNew )
				{
					var sessionOld = targetOld.findSession( task.oldAddress );
					var sessionNew = targetOld.findSession( task.newAddress );
	                
					if( sessionOld && !sessionNew )
						targetOld.changeSession( task.oldAddress, task.newAddress );
				}
	            
				task.quitTask();
			}
			break;
	        
			case Job.NEW_SESSION:
			{
				var ret = false;
				var delayed = false;
	          
				if( task.sessionObject )
				{
					var target = targetMgr.findTarget( task.address );

					if( !target )
					{
						//
						// unknown target, add target&session
						//
						var targetAddr = new Address( task.address );
						targetAddr.engine = '';
						target = targetMgr.addTarget( task.address, true, true );
					}
	                                
					if( target )
					{
						//
						// known target, add new session
						//
						if( target.getChangeConnectState() )
						{
							addDelayedTask( cdicMgr.processCDICTask, task );
							delayed = true;
							break;
						}
						else
						{
							target.addSession( task.address, task.sessionObject );
							ret = true;
						}
					}
				}
	            
				if( !delayed )
					task.returnResult( ret );     
			}
			break;
	        
			case Job.SET_PREF:
			{
				var key   = task.key;
				var value = task.value;
	            
				this.setCDICPrefValue( key, value );
				task.quitTask();
			}
			break;
	        
			case Job.SET_PREFS:
			{
				var keys   = task.keys;
				var values = task.values;
	            
				for( var i=0; i<keys.length; i++ )
				{
					var key   = keys[i];
					var value = values[i];
	                
					this.setCDICPrefValue( key, value );
				}
				task.quitTask();
			}
			break;
	        
			case Job.GET_PREF:
			{
				var key   = task.key;

				var value = this.getCDICPrefValue( key );
	            
				task.returnResult( value );            
			}
			break;
	        
			case Job.GET_PREFS:
			{
				var keys   = task.keys;
				var values = [];
	            
				for( var i=0; i<keys.length; i++ )
				{
					var key   = keys[i];
	                
					values.push( this.getCDICPrefValue( key ) );
				}
				task.returnResult( values );            
			}
			break;
		}
		}
		catch( exc )
		{}
}
