/**************************************************************************
*
*  @@@BUILDINFO@@@ 04cdicmanager-2.jsx 3.0.0.14  27-February-2008
*  Copyright 2007 Adobe Systems Incorporated
*  All Rights Reserved.
*
* NOTICE:  All information contained herein is, and remains the property of
* Adobe Systems Incorporated  and its suppliers,  if any.  The intellectual 
* and technical concepts contained herein are proprietary to  Adobe Systems 
* Incorporated  and its suppliers  and may be  covered by U.S.  and Foreign 
* Patents,patents in process,and are protected by trade secret or copyright 
* law.  Dissemination of this  information or reproduction of this material
* is strictly  forbidden  unless prior written permission is  obtained from 
* Adobe Systems Incorporated.
**************************************************************************/

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

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

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;
        }
    }
}

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

CDICManager.prototype.callSynchronous = function( task )
{
    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 ];
    }
    
    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:
        {
            app.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.' + this.name + '.' + 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 = key.toString();
            
            value = eval( 'prefs.cdic.' + this.name + '.' + key );
        }
        
        return value;
    }

    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 );
            }
            
			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;
    }
}
