/**************************************************************************
*
*  @@@BUILDINFO@@@ 80document-2.jsx 2.0.1.70  05-June-2007
*  Copyright 2006-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.
**************************************************************************/

Document.__sourceID__ = 0;		// next source ID appended to title
Document.__scriptID__ = 0;		// next script ID attached to name
Document.__windowID__ = 0;		// next document ID for the window
Document.autoCompletion = null;	// holds autocompletion data if there is a timer pending

document = null;
documents = [];

Document.FIND_WRAPAROUND    = 1;
Document.FIND_IGNORECASE    = 4;
Document.FIND_WORDS         = 8;
Document.FIND_REGEXP        = 16;
Document.FIND_REPLACEALL	= 32;
Document.FIND_SELECTION     = 64;

// Each Document instance has the following extra properties.
// These properties are not present for instances that are not documents.
// paneTitle - the original title to display
// fileName	 - the file name part of the title
// roState   - true if the document is logically read only (it can be modified, though)
// scriptID  - the script ID; either a full pathname, (ScriptN) for new scripts, or a target ID
// langID	 - the lexer language (default: js)
// lf		 - the line endings for Save
// encoding	 - the file encoding for Save
// badLine	 - temporary: If a syntax error was detected, this is the line (need to remove color on edits)
// lastAutoComplete - holds the last autocomplete string to inhibit double calls

// Create a new document, but do not show the window yet. Return the window.
// Supply an optional title and an optional language and script ID.

Document.newDoc = function( title, langID, scriptID )
{
    // reset remote flag
    remoteLaunched = false;
    
    //
    // set default language
    //
	if( !langID || langID.toString().length <= 0 )
		langID = "js";
		
    //
    // set default title
    //		
	if( !title )
		title = localize( "$$$/ESToolkit/DefaultSourceName=Source%1", ++this.__sourceID__ );
	
	//
	// set default script ID
	//
	if( !scriptID )
		scriptID = "(Script" + ++this.__scriptID__ + ")";	
		
	var windowID =  "doc" + ++this.__windowID__;
	var properties = "name: '" + windowID + "'";

    var maximize = ( document ? document.window.maximized : false );
    	
	//
	// create window
	//
   var w = new Window (
        "documentwindow {                                                                                                                                                                             \
            orientation     : 'column',                                                                                                                                                         \
            margins         : 2,                                                                                                                                                                \
            spacing         : 2,                                                                                                                                                                \
            properties      :                                                                                                                                                                   \
            {                                                                                                                                                                                   \
                minimumSize     : [370, 180],                                                                                                                                                   \
            },                                                                                                                                                                                  \
            toolbarGroup    : Group                                                                                                                                                             \
            {                                                                                                                                                                                   \
                alignment       : ['fill', 'top' ],                                                                                                                                             \
                orientation     : 'row',                                                                                                                                                        \
                margins         : 0,                                                                                                                                                            \
                spacing         : 0,                                                                                                                                                            \
                targetGroup     : Group                                                                                                                                                         \
                {                                                                                                                                                                               \
                    alignment       : ['fill','fill'],                                                                                                                                          \
                    alignChildren   : ['fill','fill'],                                                                                                                                          \
                    orientation     : 'row',                                                                                                                                                    \
                    margins         : 0,                                                                                                                                                        \
                    spacing         : 2,                                                                                                                                                        \
                    btnCon          : IconButton                                                                                                                                                \
                    {                                                                                                                                                                           \
                        preferredSize    : [24, 24],                                                                                                                                            \
                        properties       : { style : 'toolbutton' },                                                                                                                            \
                        alignment        : [ 'left', 'top' ],                                                                                                                                   \
                        helpTip          : '$$$/ESToolkit/Document/htCon=Click to connect to target application.'                                         \
                    },                                                                                                                                                                          \
                    targetDDL         : DropDownList                                                                                                                                            \
                    {                                                                                                                                                                           \
                        helpTip          : '$$$/ESToolkit/Document/htTargets=Select the target application.'    \
                    },                                                                                                                                                                          \
                    imgstate         : Image                                                                                                                                                    \
                    {                                                                                                                                                                           \
                        preferredSize   : [18, 18],                                                                                                                                             \
                        maximumSize     : [18, 18],                                                                                                                                             \
                        minimumSize     : [18, 18],                                                                                                                                             \
                        helpTip          : '$$$/ESToolkit/Document/htState=Current state of selected engine.'                                                                                   \
                    },                                                                                                                                                                          \
                    engineDDL         : DropDownList                                                                                                                                            \
                    {                                                                                                                                                                           \
                        helpTip          : '$$$/ESToolkit/Document/htEngine=Select the engine of the target application.'                                   \
                    }                                                                                                                                                                           \
                },                                                                                                                                                                              \
                dummy01         : Group                                                                                                                                                         \
                {                                                                                                                                                                               \
                    preferredSize   : [15,22],                                                                                                                                                  \
                    alignment       : ['right','fill']                                                                                                                                          \
                },                                                                                                                                                                              \
                debugGroup      : Group                                                                                                                                                         \
                {                                                                                                                                                                               \
                    alignment       : ['right','fill'],                                                                                                                                         \
                    orientation     : 'row',                                                                                                                                                    \
                    margins         : 0,                                                                                                                                                        \
                    spacing         : 2,                                                                                                                                                        \
                    btnRun          : IconButton                                                                                                                                                \
                    {                                                                                                                                                                           \
                        preferredSize    : [24, 24],                                                                                                                                            \
                        properties       : { style : 'toolbutton' },                                                                                                                            \
                        helpTip          : '$$$/ESToolkit/Document/htRun=Start running script.'                                          \
                    },                                                                                                                                                                          \
                    btnPause        : IconButton                                                                                                                                                \
                    {                                                                                                                                                                           \
                        preferredSize   : [24, 24],                                                                                                                                             \
                        properties       : { style : 'toolbutton' },                                                                                                                            \
                        helpTip          : '$$$/ESToolkit/Document/htHalt=Halt execution of the script.'                                                                                        \
                    },                                                                                                                                                                          \
                    btnStop         : IconButton                                                                                                                                                \
                    {                                                                                                                                                                           \
                        preferredSize   : [24, 24],                                                                                                                                             \
                        properties       : { style : 'toolbutton' },                                                                                                                            \
                        helpTip          : '$$$/ESToolkit/Document/htStop=Stop execution of the script.'                                                                                        \
                    },                                                                                                                                                                          \
                    btnStepover     : IconButton                                                                                                                                                \
                    {                                                                                                                                                                           \
                        preferredSize   : [24, 24],                                                                                                                                             \
                        properties       : { style : 'toolbutton' },                                                                                                                            \
                        helpTip          : '$$$/ESToolkit/Document/htStepover=Step over current script line.'                                                                                   \
                    },                                                                                                                                                                          \
                    btnStepinto     : IconButton                                                                                                                                                \
                    {                                                                                                                                                                           \
                        preferredSize   : [24, 24],                                                                                                                                             \
                        properties       : { style : 'toolbutton' },                                                                                                                            \
                        helpTip          : '$$$/ESToolkit/Document/htStepinto=Step into function call in the current line.'                                                                     \
                    },                                                                                                                                                                          \
                    btnStepout      : IconButton                                                                                                                                                \
                    {                                                                                                                                                                           \
                        preferredSize   : [24, 24],                                                                                                                                             \
                        properties       : { style : 'toolbutton' },                                                                                                                            \
                        helpTip          : '$$$/ESToolkit/Document/htStepout=Step out of current executed function.'                                                                            \
                    }                                                                                                                                                                           \
                }                                                                                                                                                                               \
            },                                                                                                                                                                                  \
            document        : Document                                                                                                                                                          \
            {                                                                                                                                                                                   \
                maximumSize     : [10000,10000],                                                                                                                                                    \
                preferredSize   : [390, 460],                                                                                                                                                   \
                alignment       : ['fill', 'fill' ],                                                                                                                                            \
            },                                                                                                                                                                                  \
            statusGroup          : Group                                                                                                                                                        \
            {                                                                                                                                                                                   \
                alignment       : ['fill', 'bottom' ],                                                                                                                                          \
                orientation     : 'row',                                                                                                                                                        \
                margins         : 0,                                                                                                                                                            \
                spacing         : 0,                                                                                                                                                            \
                maximumSize     : [1000,22],                                                                                                                                                    \
                infoStatus     : Panel                                                                                                                                                          \
                {                                                                                                                                                                               \
                    alignment       : ['fill','center'],                                                                                                                                        \
                    margins         : 0,                                                                                                                                                        \
                    spacing         : 0,                                                                                                                                                        \
                    properties      : { borderStyle : 'sunken' },                                                                                                                               \
                    statustext      : StaticText                                                                                                                                                \
                    {                                                                                                                                                                           \
                        properties  : { truncate : 'middle' },                                                                                                                                  \
                        alignment   : ['fill','center'],                                                                                                                                        \
                        characters  : 40                                                                                                                                                        \
                    }                                                                                                                                                                           \
                },                                                                                                                                                                              \
                posStatus        : Panel                                                                                                                                                        \
                {                                                                                                                                                                               \
                    alignment       : ['right','center'],                                                                                                                                       \
                    margins         : 0,                                                                                                                                                        \
                    spacing         : 0,                                                                                                                                                        \
                    properties      : { borderStyle : 'sunken' },                                                                                                                               \
                    statustext      : StaticText                                                                                                                                                \
                    {                                                                                                                                                                           \
                        properties  : { truncate : 'middle' },                                                                                                                                  \
                        alignment   : ['center','center'],                                                                                                                                      \
                        characters  : 20                                                                                                                                                        \
                    }                                                                                                                                                                           \
                },                                                                                                                                                                              \
                busyStatus       : Group                                                                                                                                                        \
                {                                                                                                                                                                               \
                    alignment       : ['right','center'],                                                                                                                                       \
                    orientation     : 'row',                                                                                                                                                    \
                    margins         : [7,0,0,0],                                                                                                                                                \
                    spacing         : 0,                                                                                                                                                        \
                    imgbusy         : Image                                                                                                                                                     \
                    {                                                                                                                                                                           \
                        alignment    : ['left', 'center'],                                                                                                                                      \
                        preferredSize   : [18, 18]                                                                                                                                              \
                    },                                                                                                                                                                          \
                    sizeBoxSpacer    : Group {                                                                                                                                                  \
                        size        : [20,1]                                                                                                                                                    \
                    }                                                                                                                                                                          \
                }                                                                                                                                                                               \
            }                                                                                                                                                                                  \
        }");
        
    w.maximized = maximize;

    ///////////////////////////////////////////////////////////////////////////////
    //
    // create shortcuts
    //
    w.targetDDL     = w.toolbarGroup.targetGroup.targetDDL;
    w.engineDDL     = w.toolbarGroup.targetGroup.engineDDL;
    w.btnCon        = w.toolbarGroup.targetGroup.btnCon;
    w.btnRun        = w.toolbarGroup.debugGroup.btnRun;
    w.btnStepover   = w.toolbarGroup.debugGroup.btnStepover;
    w.btnStepinto   = w.toolbarGroup.debugGroup.btnStepinto;
    w.btnStepout    = w.toolbarGroup.debugGroup.btnStepout;
    w.btnStop       = w.toolbarGroup.debugGroup.btnStop;
    w.btnPause      = w.toolbarGroup.debugGroup.btnPause;
    w.imgstate      = w.toolbarGroup.targetGroup.imgstate;

    ///////////////////////////////////////////////////////////////////////////////
    //
    // set widths
    //
	w.targetDDL.preferredSize.width = 150;
	w.engineDDL.preferredSize.width = 100;

    ///////////////////////////////////////////////////////////////////////////////
    //
    // debugging buttons
    //
    w.btnRun.icon         = ScriptUI.newImage( '#Run_R', '#Run_N' );
    w.btnPause.icon       = ScriptUI.newImage( '#Pause_R', '#Pause_N' );
    w.btnStop.icon        = ScriptUI.newImage( '#Stop_R', '#Stop_N' );
    w.btnStepover.icon    = ScriptUI.newImage( '#StepOver_R', '#StepOver_N' );
    w.btnStepinto.icon    = ScriptUI.newImage( '#StepInto_R', '#StepInto_N' );
    w.btnStepout.icon     = ScriptUI.newImage( '#StepOut_R', '#StepOut_N' );

    w.btnRun.onClick      = menus.debug.run.onSelect;
    w.btnPause.onClick    = menus.debug.pause.onSelect;
    w.btnStop.onClick     = menus.debug.stop.onSelect;
    w.btnStepover.onClick = menus.debug.over.onSelect;
    w.btnStepinto.onClick = menus.debug.into.onSelect;
    w.btnStepout.onClick  = menus.debug.out.onSelect;
    
    ///////////////////////////////////////////////////////////////////////////////
    //
    // connect button
    //
    w.btnCon.iconConnected      = ScriptUI.newImage( '#Connected_R', '#Connected_N' );
    w.btnCon.iconDisconnected   = ScriptUI.newImage( '#Disconnected_R', '#Disconnected_N' );
    w.btnCon.iconConnecting     = ScriptUI.newImage( '#Connecting_R', '#Connecting_N' );
    
    w.btnCon.icon           = w.btnCon.iconConnected;
    
    w.btnCon.onClick = function()
    {    
        var targetName = this.window.document.getCurrentTargetName();
        
        if( targetMgr.getConnected( targetName ) )
			Debugger.disconnect( targetName, true );
		else
            targetMgr.select( targetName, '', this.window.document );        
    }
    
    ///////////////////////////////////////////////////////////////////////////////
    //
    // engine state icon
    //
    w.imgstate.iconInactive = ScriptUI.newImage( '#InactiveEngine', '#InactiveEngine' );
    w.imgstate.iconWait     = ScriptUI.newImage( '#WaitingEngine', '#InactiveEngine' );
    w.imgstate.iconRun      = ScriptUI.newImage( '#RunningEngine', '#InactiveEngine' );
    w.imgstate.iconStop     = ScriptUI.newImage( '#StoppedEngine', '#InactiveEngine' );
    
    w.imgstate.icon = w.imgstate.iconInactive;

    ///////////////////////////////////////////////////////////////////////////////
	//
	// targets & engines dropdown lists
	//
	
	//-----------------------------------------------------------------------------
	// 
	// w.getChangingTargetEngine(...)
	// 
	// Purpose:get/set change status of targets & engines - DropDownLists
	// 
	//-----------------------------------------------------------------------------
	
	w.getChangingTargetEngine = function()
	{
	    return ( targetMgr.isChanging() || this.userChangeTargetEngine );
	}
	
	w.setChangingTargetEngine = function( change )
	{
	    this.userChangeTargetEngine = change;
	    targetMgr.setIsChanging( change );
	}
	
	//-----------------------------------------------------------------------------
	// 
	// w.targetDDL.onChange(...)
	// 
	// Purpose:selection of targets list changed
	// 
	//-----------------------------------------------------------------------------

	w.targetDDL.onChange = function()
	{	
	    if( !appInShutDown )
	    {
	        //
	        // we process only change events if the user selects a new target
	        //
	        if( !this.window.getChangingTargetEngine() )
	        {
		        var targetItem = this.selection;

		        if( targetItem )
		        {		    
	                this.window.setChangingTargetEngine( true );
        	        
	                //
	                // set active target at target manager
	                // (cause notify 'changeActiveEngine')
	                //
	                targetMgr.setActive( targetItem.target, null, this.document );

	                this.window.setChangingTargetEngine( false );
	            }
           
				if( targetItem && !targetMgr.getConnected( targetItem.target ) )
				{
					if( PrefUtils.getValue( 'prefs.autolaunch', 'Boolean' ) || 
						( targetItem && BridgeTalk.isRunning( targetItem.target ) ) )
						this.window.btnCon.notify();
				}
	        }
	    }
	}
	
    //-----------------------------------------------------------------------------
    // 
    // w.engineDDL.onChange(...)
    // 
    // Purpose: selection of engines list changed
    // 
    //-----------------------------------------------------------------------------

	w.engineDDL.onChange = function()
	{	
	    if( !appInShutDown )
	    {
	        //
	        // we process only change events if the user selects a new target
	        //
	        if( !this.window.getChangingTargetEngine() )
	        {
	            var activeTarget = targetMgr.getActiveTarget();
	            var engineItem   = this.selection;
    	        
	            if( activeTarget && engineItem )
	            {
	                this.window.setChangingTargetEngine( true );
    	            
	                //
	                // set active engine at current active target
	                // (cause notify 'changeActiveEngine')
	                //
	                activeTarget.setActive( engineItem.engine );
    	            
	                this.window.setChangingTargetEngine( false );
	            }
	        }
	    }
	}

    ///////////////////////////////////////////////////////////////////////////////
    //
    // document
    //
    
    //-----------------------------------------------------------------------------
    // 
    // w.document.addTarget(...)
    // 
    // Purpose: add new target to list
    // 
    //-----------------------------------------------------------------------------
    
    w.document.addTarget = function( target )
    {
        var oldSelection = 0;
        
        if( this.window.targetDDL.selection )
            oldSelection = this.window.targetDDL.selection;
            
        this.window.setChangingTargetEngine( true );
        
        var item                        = this.window.targetDDL.add( 'item', target.title );                
        item.target                     = target.targetName;
        this.window.targetDDL.selection = oldSelection;

        this.window.setChangingTargetEngine( false );
    }

    //-----------------------------------------------------------------------------
    // 
    // w.document.setupTargets(...)
    // 
    // Purpose: setup targets list
    // 
    //-----------------------------------------------------------------------------
    
    w.document.setupTargets = function()
    {
        this.window.setChangingTargetEngine( true );
        
        this.window.targetDDL.removeAll();
        this.window.engineDDL.removeAll();

        var alltargets = targetMgr.getTargets();
        
        if( alltargets )
        {
            for( var i=0; i<alltargets.length; i++ )
                this.addTarget( alltargets[i] );
                
            this.selectActiveTarget( targetMgr.getActiveTarget() );
        }

        this.window.setChangingTargetEngine( false );
    }
    
    //-----------------------------------------------------------------------------
    // 
    // w.document.setupEngines(...)
    // 
    // Purpose: setup engines list
    // 
    //-----------------------------------------------------------------------------

    w.document.setupEngines = function( targetObj )
    {
        if( !targetObj )
            targetObj = targetMgr.getActiveTarget();
            
        this.populateEngineDDL( targetObj );
        
        this.window.setChangingTargetEngine( true );
        this.window.engineDDL.selection = 0;                            
        this.selectActiveTarget( targetMgr.getActiveTarget() );
        this.window.setChangingTargetEngine( false );
    }
    
    //-----------------------------------------------------------------------------
    // 
    // w.document.populateEngineDDL(...)
    // 
    // Purpose: Add engine names to dropdown list
    // 
    //-----------------------------------------------------------------------------
    
    w.document.populateEngineDDL = function( targetObj )
    {
        if( targetObj)
        {
            this.window.setChangingTargetEngine( true );
            this.window.engineDDL.removeAll();        

            var engineNames = targetObj.getEngines();
            
            if( engineNames )
            {
                for( var i=0; i<engineNames.length; i++ )
                {
                    var item = this.window.engineDDL.add( 'item', engineNames[i] );
                    item.engine = engineNames[i];
                }
            }

            this.window.setChangingTargetEngine( false );
        }
    }
    
    //-----------------------------------------------------------------------------
    // 
    // w.document.selectActiveTarget(...)
    // 
    // Purpose: select active target
    // 
    //-----------------------------------------------------------------------------
    
    w.document.selectActiveTarget = function( activeTargetObj )
    {
		function selectEngine (window, activeTargetObj)
		{
			if( !window.engineDDL.selection || 
				( window.engineDDL.selection && 
				  window.engineDDL.selection.engine != activeTargetObj.getActive() ) )
			{
				window.setChangingTargetEngine( true );
	            
				for( var i=0; i<window.engineDDL.items.length; i++ )
					if( window.engineDDL.items[i].engine == activeTargetObj.getActive() )
						window.engineDDL.selection = window.engineDDL.items[i];
	                    
				window.setChangingTargetEngine( false );
			}
		}

        if( activeTargetObj )
        {
            if( this == document )
            {
                //
                // handle active (top-most) document
                //
            
                if( !this.window.targetDDL.selection || 
                    ( this.window.targetDDL.selection && 
                      this.window.targetDDL.selection.target != activeTargetObj.targetName ) )
                {
                    //
                    // set target at DropDownList
                    //
                    this.window.setChangingTargetEngine( true );
                    
                    for( var i=0; i<this.window.targetDDL.items.length; i++ )
                        if( this.window.targetDDL.items[i].target == activeTargetObj.targetName )
                            this.window.targetDDL.selection = this.window.targetDDL.items[i];
                            
                    this.window.setChangingTargetEngine( false );
                }
                
                if( activeTargetObj.getConnected() || activeTargetObj.isDefault())
                {                
                    this.populateEngineDDL( activeTargetObj );
                    
                    //
                    // target is connected, select active engine in DropDownList
                    // if not selected, yet
                    //
					selectEngine (this.window, activeTargetObj);
                }
                else
                {
                    //
                    // target not yet connected
                    //
                    this.window.engineDDL.removeAll();
                }
            }
            else
            {
                //
                // handle not-active document
                //
            
                if( this.window.targetDDL.selection && this.window.targetDDL.selection.target == activeTargetObj.targetName )
                {
                    if( !activeTargetObj.getConnected() && !activeTargetObj.isDefault() )
                    {
                        //
                        // target not yet connected
                        //
                        this.window.engineDDL.removeAll();
                    }
                }
            }
        }
    }
    
    //-----------------------------------------------------------------------------
    // 
    // w.document.getCurrentTargetName(...)
    // 
    // Purpose: Get current target or engine name
    // 
    //-----------------------------------------------------------------------------
    
    w.document.getCurrentTargetName = function()
    {
        var targetName = '';
        
        if( this.window.targetDDL.selection )
            targetName = this.window.targetDDL.selection.target;

        return targetName;
    }
    
    w.document.getCurrentEngineName = function()
    {
        var engineName = '';
        
        if( this.window.engineDDL.selection )
            engineName = this.window.engineDDL.selection.engine;
            
        return engineName;
    }
    
    //-----------------------------------------------------------------------------
    // 
    // w.document.isDebugging(...)
    // 
    // Purpose: Is there a debugger running for current target & engine
    // 
    //-----------------------------------------------------------------------------
    
    w.document.isDebugging = function()
    {
        var targetName = this.getCurrentTargetName();
        var engineName = this.getCurrentEngineName();
        
        var dbg         = Debugger.find( targetName, engineName );
        var docInDebug  = false;
        
        if( dbg )
            docInDebug = ( dbg.documents[this.scriptID] && dbg.state != Debugger.INACTIVE && dbg.state != Debugger.WAITING );
                         
        return docInDebug;
    }
    
    //-----------------------------------------------------------------------------
    // 
    // w.document.canDebug(...)
    // 
    // Purpose: Can the document be debugged at the moment 
    //          (or is there already another engine of the target is in debugging, 
    //           so we can't start another session)
    // 
    //-----------------------------------------------------------------------------
    
    w.document.canDebug = function()
    {
        var canDebug    = false;
        var targetName  = this.getCurrentTargetName();
        var engineName  = this.getCurrentEngineName();
        
        if( targetMgr.getConnected( targetName ) || targetMgr.defaultTarget.targetName == targetName )
        {
            canDebug = true;
            var dbgs = Debugger.getAll( targetName );
               
            if( dbgs && dbgs.length > 0 )
            {
                for( var i=0; i<dbgs.length; i++ )
                {
                    if( dbgs[i].state != Debugger.INACTIVE && dbgs[i].state != Debugger.WAITING ) // TODO: debugging over multiple document: && dbgs[i].state != Debugger.STOPPED )
                    {
                        if( dbgs[i].document != this )
                        {
                            canDebug = false;
                            break;
                        }
                    }
                }
            }
        }
        
        return canDebug;
    }
	
	//-----------------------------------------------------------------------------
	// 
	// w.document.setEngineState(...)
	// 
	// Purpose: Reflect state of current engine
	// 
	//-----------------------------------------------------------------------------
	
    w.document.setEngineState = function( forTarget, forEngine )
    {
        var targetName = this.getCurrentTargetName();
        
        if( targetName == forTarget )
        {
            var item = null;
            
            for( var i=0; i<this.window.engineDDL.items.length; i++ )
                if( this.window.engineDDL.items[i].text == forEngine )
                    item = this.window.engineDDL.items[i];
                    
            if( item )
            {
                var icon = w.imgstate.iconInactive;

                var debuggerObj = Debugger.find( forTarget, forEngine );
                
                if( debuggerObj )
                {                
                    switch( debuggerObj.state )
                    {
                        case Debugger.RUNNING:	icon = w.imgstate.iconRun;  break;
                        case Debugger.STOPPED:	icon = w.imgstate.iconStop; break;
                        case Debugger.WAITING:	icon = w.imgstate.iconWait; break;
                    }
                }
                
                if( 0 )
                    item.icon = icon;
                
                if( this.window.engineDDL.selection && this.window.engineDDL.selection == item )
                    w.imgstate.icon = icon;     
                else               
                    w.imgstate.icon = w.imgstate.iconInactive;
            }
        }
    }
    
    ///////////////////////////////////////////////////////////////////////////////
    //
    // Cursor position
    //
    
    w.document.setCursorPos = function( x, y )
    {
        this.parent.statusGroup.posStatus.statustext.text = localize( '$$$/ESToolkit/Panes/Statusbar/Line=Line' ) + ' ' + (x+1) + '    ' + localize( '$$$/ESToolkit/Panes/Statusbar/Column=Column' ) + ' ' + (y+1);
    }
    
    w.document.clearCursorPos = function()
    {
        this.parent.statusGroup.posStatus.statustext.text = '';
    }

    ///////////////////////////////////////////////////////////////////////////////
    //
    // status line
    //

    w.document.setStatusLine = function( text )
    {
        if( !text )
            text == '';
            
        if( text.indexOf( '$$$' ) == 0 )
            text = localize( text );            
            
        this.parent.statusGroup.infoStatus.statustext.text = text;
    }
    
    ///////////////////////////////////////////////////////////////////////////////
    //
    // profiling
    //

    w.document.eraseProfileData = function()
    {
        this.profiling = 0;
        this.profileData = [];
        this.clearProfileData();
    }
    
    w.document.updateProfData = function()    
    {
        for( var i=0; i<this.profileData.length; i++ )
            this.setProfileData( this.profileData[i].line, this.profileData[i].hit, this.profileData[i].time );

        this.profiling = 0;     // switch to 0 before to force a redraw
        
        var display = PrefUtils.getValue( 'prefs.profiling.profDisplayMode', 'Number' );
        
        if( this.profileData.length > 0 && display > 0 )
        {
            var level       = PrefUtils.getValue( 'prefs.profiling.profileLevel', 'Number' );
            this.profiling  = display == 1 ? level-1 : level;
        }
    }

    //-----------------------------------------------------------------------------
    // 
    // w.document.onNotify(...)
    // 
    // Purpose: notify handler
    // 
    //-----------------------------------------------------------------------------
    
    w.document.onNotify = function( reason )
    {    
        this.window.updateToolbarState();
        
        var targetName = this.getCurrentTargetName();
        var engineName = this.getCurrentEngineName();
        
        switch( reason )
        {
			case 'filechanged' :
			{
			    var newFile = arguments[1];
			    if( newFile.absoluteURI == File( this.scriptID ).absoluteURI )
			    {
					var reload = true;
					if (this.isModified())
						// Always ask if the file has been modified
						reload = queryBox ("$$$/ESToolkit/Alerts/AutoreloadChanged=File %1^nhas been changed.^nDo you want to reload it and lose your changes?",
										   decodeURIComponent( newFile.fsName ) );
					else if (!PrefUtils.getValue( 'prefs.document.autoReload', 'Boolean' ))
						// Autoreload off: ask if not modified
						reload = queryBox ("$$$/ESToolkit/Alerts/AutoreloadUnchanged=File %1^nhas been changed.^nDo you want to reload it?",
										   decodeURIComponent( newFile.fsName ) );
					if (reload)
					{
						newFile.encoding = this.encoding;
						var text = Document.safeRead (newFile);
						if (null != text)
						{
							this.encoding = newFile.encoding;
						    this.setText( text, false );
						    this.setSavePoint();
						    this.setTitle();
					    }
				    }
				}
			}
			break;
			
            case 'startConnect':
            {
                if( targetName == arguments[1] )
                {
                    this.window.connecting = true;
                    this.window.updateToolbarState();
                }
            }
            break;
            
            case 'endConnect':
            {
                if( targetName == arguments[1] )
                {
                    this.window.connecting = false;
                    this.window.updateToolbarState();
                }
            }
            break;
            
            case 'state':
            {
                if( targetName == arguments[1].target )
                    this.setEngineState( arguments[1].target, arguments[1].engine );
            }
            break;
            
            case 'changeActiveTarget':
            case 'changeActiveEngine':
            {
                //
                // active engine (and probably the target) changed at target manager
                //
                this.selectActiveTarget( arguments[1] )
                this.window.updateToolbarState();
            }
            break;
            
            case 'targetDied':
                // nothing to do
                break;
				
            case 'addTarget':               // new target added
                this.addTarget( arguments[1] );
                this.window.updateToolbarState();
                break;

            case 'changeTargets':           // new targets list
                this.setupTargets();
                break;

			case 'removeEngines':
            case 'changeEngines':           // new engines list
			{
				if( targetName == arguments[1].targetName )
					this.setupEngines( arguments[1] );
			}
			break;

			case 'autoCompletionPrefsChanged':
				if (Document.autoCompletion)
				{
					// cancel any pending timer
					app.cancelTask (Document.autoCompletion.autoID);
					Document.autoCompletion = null;
				}
				break;
				
			case 'shutdown':
			    globalBroadcaster.unregisterClient( this );
			    this.window.setChangingTargetEngine( true );
			    this.window.targetDDL.removeAll();
			    this.window.engineDDL.removeAll();
			    break;
        }
    }

    w.document.canAutoComplete = function( style )
    {
        //
        // TODO: this information should come from syntaxdefs.xml
        //
        var ret = true;
        
        switch( style )
        {
            case 1:
            case 2:
            case 3:
            case 6:
            case 7:
            case 12:
            case 13:
            case 15:
                ret = false;
        }
        
        return ret;
    }
    
    w.document.startAutoCompletion = function()
    {
        if( this.textselection.length == 0 && this.wordRight.length == 0 )
        {
            var pos = this.getLogicalPos();
            
            var line = this.lines[pos[0]];
            var searchStr = this.wordLeft;

            //
            // include classname
            //
            if( line.charAt( line.length - searchStr.length - 1 ) == '.' )
            {
                var prevWord = this.getWordAt( pos[2] - searchStr.length - 1 );
                
                if( prevWord.length > 0 && prevWord.charCodeAt(0) > 64 && prevWord.charCodeAt(0) < 91 )
                    searchStr = prevWord + '.' + searchStr;
            }
            
            if( searchStr.length > 0 && searchStr != this.lastAutoComplete )
            {
                //
                // since this document is actually active
                // the current debugger has the same target
                // as this document
                //
                if( currentDebugger )
                {
                    //
                    // ask for code hints (an array is returned)
			        // every line has the format [Classname.]Elementname[ - helptext]
                    //               

                    var strs = currentDebugger.getCodeHints( searchStr );

                    //
                    // show auto completion listbox
                    //
                    if( strs && strs.length > 0 )
						this.showAutoCompletion( strs );
                }
            }
        }
    }

	///////////////////////////////////////////////////////////////////////////////
	//
	// Document UI handler
	//
	
	w.document.onLineClick = function (line)
	{
		this.toggleBreakpoint (line);
	}

    w.document.onUpdateUI = function()
    {
        var pos = this.getLogicalPos();
        
        this.setCursorPos( pos[0], pos[1] );
  
        if( PrefUtils.getValue( 'prefs.autocompletion', 'Boolean' ) &&
            pos[1] == this.currentPos[1]+1 && pos[0] == this.currentPos[0] )
        {
            if( Document.autoCompletion )
                app.cancelTask( Document.autoCompletion.autoID );
            
            if( this.canAutoComplete( this.currentStyle ) )
            {
			    var time = PrefUtils.getValue( 'prefs.autotime', 'Number' );
                var id = app.scheduleTask( "Document.startAutoCompletion();", time * 1000, false );      
			    Document.autoCompletion = { autoDoc : this , autoID : id };   
			}
        }
        
        this.currentPos = pos;
    }        

    w.document.onAutocomplete = function( text )
    {
        if( this.textselection.length == 0 && this.wordRight.length == 0 )
        {
            //
	        // The text format is [Classname.]Elementname[: help text]
	        //
			var fullText	= text.split(": ")[0];
            var classText   = fullText.split('.');
            var elementText = classText.length > 0 ? classText[classText.length-1] : '';
            
            var searchText  = this.wordLeft;

            if( elementText.length > 0 && elementText.indexOf( searchText ) == 0 )
            {
				this.lastAutoComplete = elementText;
				
				//
				// Update the OMV UI
				//
				currentDebugger.displaySelectedCodeHint (text);
				
                //
                // insert the completion
                //
				elementText = elementText.substr( searchText.length );
                this.insert( elementText, this.getLogicalPos()[2] );
                var curSel  = this.getSelection();
                this.setSelection( curSel[0], curSel[1]+elementText.length, curSel[0], curSel[1]+elementText.length );
            }
        }
    }
     
    w.document.onMouseOver = function( line, text )
	{
	    if( currentDebugger && prefs.dynamicHelp.valueOf() )
		    currentDebugger.getHelpTip( this, line, text );
	    else
		    this.helpTip = '';
	}

    ///////////////////////////////////////////////////////////////////////////////
    //
    // Window
    //
    
    //-----------------------------------------------------------------------------
    // 
    // w.updateToolbarState(...)
    // 
    // Purpose: Update UI states of toolbar area
    // 
    //-----------------------------------------------------------------------------
    
    w.updateToolbarState = function()
    {
        var targetName = '';
        var engineName = '';
        
        if( this.targetDDL.selection )
            targetName = this.targetDDL.selection.target;
        if( this.engineDDL.selection )
            engineName = this.engineDDL.selection.engine;
            
        //
        // disable engine DDL if target isn't connected
        //
        if( targetMgr.getConnected( targetName ) || targetMgr.defaultTarget.targetName == targetName )
        {
            this.engineDDL.enabled = true;
            this.btnCon.icon = this.btnCon.iconConnected;
        }
        else
        {
            this.engineDDL.enabled = false;
            this.btnCon.icon = this.btnCon.iconDisconnected;
        }
        
        //
        // set connect button icon if we just about to connect
        //
        if( this.connecting )
            this.btnCon.icon = this.btnCon.iconConnecting;
            
        //
        // debugging state
        //
        
        //
        // Is there a debugger for the current target & engine ?
        // If there is one and if it's running then don't let
        // the user change target or engine!
        //
        if( this.document.isDebugging() )             
        {
            //
            // debugger of document is actually running, so disable target&engine DropDownList
            //
            this.targetDDL.enabled = false;
            this.engineDDL.enabled = false;
        }
        else
        {
            this.targetDDL.enabled = true;
            
            if( this.engineDDL.enabled )
                // don't enable if it was disabled before
                this.engineDDL.enabled = true;
        }
        
        //
        // Is there any other debugger for the current target?
        // If there is one (but not using the current engine) and
        // it's running then don't let the user start another
        // session at the same target but different engine!
        //
        var canDebug = this.document.canDebug();

        if( this.document == document )
        {
            // update menu items, too
            menus.debug.reflectState();
        }
        else
            this.updateDebugButtonStates( !canDebug && targetMgr.getConnected( targetName ) );
            
        // update current engine state icon
        this.document.setEngineState( targetName, engineName );
    }
    
    //-----------------------------------------------------------------------------
    // 
    // w.updateDebugButtonStates(...)
    // 
    // Purpose: Update UI states of debugging buttons
    // 
    //-----------------------------------------------------------------------------
    
    w.updateDebugButtonStates = function( disable )
    {        
        var forceDisable = false;
        
        if( disable )
            forceDisable = true;

        var targetName = '';
        var engineName = '';
        
        if( this.targetDDL.selection )
            targetName = this.targetDDL.selection.target;
        if( this.engineDDL.selection )
            engineName = this.engineDDL.selection.engine;

		var running = false;
		var stopped = false;
		
		var dbg = Debugger.find( targetName, engineName );
		
		if( dbg )
		{
		    running = ( dbg.state == Debugger.RUNNING );
		    stopped = ( dbg.state == Debugger.STOPPED );
		}
		
		switch( this.document.status )
		{
			case "noexec":
				// not executable
                this.btnRun.setEnabled( false );
                this.btnStepover.setEnabled( false );
                this.btnStepinto.setEnabled( false );
                this.btnStepout.setEnabled( false );
                this.btnStop.setEnabled( false );
                this.btnPause.setEnabled( false );
				break;
				
			case "exec":
				// standard executable
                this.btnRun.setEnabled( !forceDisable && ( !running || stopped ) );
                this.btnStepover.setEnabled( !forceDisable && ( !running || stopped ) );
                this.btnStepinto.setEnabled( !forceDisable && ( !running || stopped ) );
                this.btnStepout.setEnabled( !forceDisable && stopped );
                this.btnStop.setEnabled( !forceDisable && ( running || stopped ) );
                this.btnPause.setEnabled( !forceDisable && running );
				break;

			case "dynamic":
				// dynamic script, not saveable
                this.btnRun.setEnabled( !forceDisable && stopped );
                this.btnStepover.setEnabled( !forceDisable && stopped );
                this.btnStepinto.setEnabled( !forceDisable && stopped );
                this.btnStepout.setEnabled( !forceDisable && stopped );
                this.btnStop.setEnabled( !forceDisable && stopped );
                this.btnPause.setEnabled( false );
				break;
		}
    }
            
    ///////////////////////////////////////////////////////////////////////////////
    //
    // busy animation
    //
    w.document.busyID = app.initBusyPlaceholderImage( w.statusGroup.busyStatus.imgbusy );

	w.id = windowID;

	///////////////////////////////////////////////////////////////////////////////
	//
	// Window UI handler
	//
	w.onResize		= function() { this.layout.resize(); }; 
	
	w.onActivate	= function() 
	{
		if( !this.userChangeTargetEngine )
		{
			this.document.activate(); 
			
		    if( this.targetDDL.selection && this.engineDDL.selection )
		    {
			    var target = this.targetDDL.selection.target;
			    var engine = this.engineDDL.selection.engine;
				
			    if( target.length && engine.length )
				{
					//
					// if target&engine is not active at the moment
					// set them active
					//
					var activeTarget = targetMgr.getActiveTarget();
					var activeEngine = '';
					
					if( activeTarget )
					{
						activeEngine = activeTarget.getActive();
						activeTarget = activeTarget.targetName;
					}
					
					if( activeTarget != target || activeEngine != engine )
					{
						targetMgr.setActive( target, engine, this.document );
					}
				}
		    }
		    else
		    {
                this.document.selectActiveTarget( targetMgr.getActiveTarget() )
                this.updateToolbarState();
		    }
            
			menus.debug.reflectState();
			
			var pos = this.document.getLogicalPos();
			
			this.document.setCursorPos( pos[0], pos[1] );
		}
		
		this.document.activeStyle = true;
		
		if( this.minimized )
		    this.minimized = false;
    }
    
    w.onDeactivate  = function()
    {
        this.document.clearCursorPos();
        this.document.activeStyle = false;
        
        if( document == this.document )
        {
            document = null;
            
            if( !appInShutDown )
                globalBroadcaster.notifyClients( 'activeDocChanged' );
        }
    }
    
    w.onShow = function()
    {    
        this.document.readPrefs();
    }
    
    w.onClose = function() 
    {     
        if( this.document.isDebugging() )
        {
            this.document.setStatusLine( '$$$/ESToolkit/Status/StopDebugForClose=Stop debugging before closing document' );                
            return false;
        }
        
        if( this.document.isModified() && !this.document.save( false, app.enableStandardUI ) )
            return false;
      
        this.document.writePrefs();
              
        targetMgr.unregisterClient( this.document );            
        Debugger.unregisterClient( this.document );            
            
        //
        // remove from documents list
        //
		for (var i = 0; i < documents.length; i++)
		{
            if( documents[i] == this.document )
			{
				documents.splice (i, 1);
				break;
			}
		}
		
		//
		// switch to last opened document
		//
		if( !appInShutDown )
		{
		    globalBroadcaster.notifyClients( 'activeDocChanged' );
		    globalBroadcaster.notifyClients( 'numDocsChanged' );
		}

		if (document == this.document)
		{
			document = null;
			
			if (documents.length)
				documents [documents.length-1].active = true;
		}
		
		addDelayedTask (menus.updateWindowMenu);

		this.document.setScriptID();
    }

    w.document.currentPos	    = [0,0];
	w.document.lastAutoComplete	= "";
	w.document.roState			= false;
	w.document.lf				= PrefUtils.getValue( 'prefs.document.lineend', 'String' ).toLowerCase();
	w.document.encoding			= "UTF-8";
	w.document.profileData		= [];
	w.document.includePath      = '';
	w.document.autoIndent       = PrefUtils.getValue( 'prefs.document.autoIndent', 'Number' );
	
	w.document.setScriptID( scriptID );

	if (w.document.isFile())
	{
		var f = File (w.document.scriptID);
		w.document.paneTitle = f.fsName;
		w.document.fileName  = f.name;
		w.document.roState	 = f.readonly;
	}
	else
	{
		w.document.paneTitle =
		w.document.fileName  = decodeURIComponent (title);
	}
	
	if( langID == 'js' )
	    w.document.status = 'exec';
    else
        w.document.status = 'noexec';
	
	w.document.clearUndo();

	w.origTitle = w.paneTitle;
	w.document.setTitle();

	// update the global document variables
	document = w.document;
	
	documents.push (w.document);

	w.document.setLanguage (langID);
	
	if( w.document.status == 'noexec' )
	    w.toolbarGroup.enabled = false;

    globalBroadcaster.registerClient( w.document );
    targetMgr.registerClient( w.document );
    Debugger.registerClient( w.document );

    targetMgr.setIsChanging( true );    
    w.document.setupTargets();
    w.document.setupEngines();
    targetMgr.setIsChanging( false );    
    					
	if( !appInShutDown )
	{
	    globalBroadcaster.notifyClients( 'activeDocChanged' );
	    globalBroadcaster.notifyClients( 'numDocsChanged' );
	}

	addDelayedTask (menus.updateWindowMenu);
	
	return w;
}

///////////////////////////////////////////////////////////////////////////////
//
// Document UI handler
//

Document.prototype.onCreate =	function() {}
Document.prototype.onLoad =		function() {}
Document.prototype.onKey  =		function (key) 
{ 
//    print (key); 
}

Document.prototype.onActivate = function()
{
	if( this.paneTitle )
	{	
		if (this != document)
		{
			document = this;
			if( !appInShutDown )
			    globalBroadcaster.notifyClients( 'activeDocChanged' );
		}
        this.window.updateToolbarState();
    }
}

Document.prototype.onDeactivate = function()
{
	if( this.window.updateToolbarState )
		this.window.updateToolbarState();
}

Document.prototype.onChange = function()
{
    if( !this.ignoreChange )
    {
	    // If we are debugging, we need to stop
	    if( currentDebugger && currentDebugger.isActive() && this.isDebugging() )
	    {
	        if( queryBox( "$$$/ESToolkit/Alerts/DebuggingUnchanged=The script of the document %1 is in debug mode.^nDo you want to stop debugging to enter your changes?", decodeURIComponent(this.fileName) ) )
			{
    		    currentDebugger.stop();
			}
    		else
    		{
				var oldindent	= this.autoIndent;
				this.autoIndent = 0;
				
				var src =  "var oldind="+oldindent+";									\
							var __doc__=Document.find('" + this.scriptID + "');         \
							if(__doc__){                                                \
								var old=__doc__.ignoreChange;                           \
								__doc__.ignoreChange=true;                              \
								__doc__.undo();											\
								__doc__.autoIndent=oldind;                              \
								__doc__.ignoreChange=old;                               \
								__doc__.setTitle();}";
								
				app.scheduleTask( src, 10 );
            }
		}
		    
	    if( this.badLine )
	    {
		    this.setCurrentLine( this.badLine, colors.White );
		    delete this.badLine;
	    }
	    
	    if( this.paneTitle )
		    this.setTitle();
	}
}

Document.prototype.onLineNumbersChanged = function()
{
	breakpoints.updateFromDoc (this);
}

//-----------------------------------------------------------------------------
// 
// Document.prototype.isFile(...)
// 
// Purpose: Is this document a disk file?
// 
//-----------------------------------------------------------------------------

Document.prototype.isFile = function()
{
	// true if the scriptID contains an absolute URI.
	// Do not use File.exists - it may be slow on networked files
	return( this.scriptID && ( this.scriptID[0] == '/' || this.scriptID[0] == '~' ) );
}

//-----------------------------------------------------------------------------
// 
// Document.prototype.activate(...)
// 
// Purpose: De/activate the document.
// 
//-----------------------------------------------------------------------------

Document.prototype.activate = function()
{
	this.parent.active = true;
	this.active = true;

	// TODO: do we need this?
	if (this.paneTitle && (this != document))
	{
		document = this;
		
		if( !appInShutDown )
		    globalBroadcaster.notifyClients( 'activeDocChanged' );
	}
}

Document.prototype.deactivate = function()
{
	this.active = false;
}

//-----------------------------------------------------------------------------
// 
// Document.prototype.setText(...)
// 
// Purpose: set documents content
// 
//-----------------------------------------------------------------------------

Document.prototype.setText = function( text, silent )
{
    if( typeof silent == 'undefined' )
        silent = true;
    
    var oldState        = this.ignoreChange;
    this.ignoreChange   = silent;
    this.text           = text;
    
    if( silent )
        this.setSavePoint();
        
    this.ignoreChange   = oldState;
}

//-----------------------------------------------------------------------------
// 
// Document.prototype.setTitle(...)
// 
// Purpose: Set the title with readonly and modified indicators
// 
//-----------------------------------------------------------------------------

Document.prototype.setTitle = function()
{
	var title = this.paneTitle;
	if (title.length)
	{
		if (this.roState)
			title = localize ("$$$/ESToolkit/Status/ReadOnlyIndicator=[R/O]") + " " + title;
		if (this.isModified())
			title = "* " + title;
		
		if (this.parent.text != title)
			this.parent.text = title;
	}
}

//-----------------------------------------------------------------------------
// 
// Document.prototype.insertVersionTag(...)
// 
// Purpose: Insert a Version tag
// 
//-----------------------------------------------------------------------------

Document.prototype.insertVersionTag = function()
{
	if (this.isFile())
	{
		var name = decodeURIComponent( File (this.scriptID).name );
		var text = "@@@" + "BUILDINFO" + "@@@ " + name + " !Version! " + new Date().toString();
		if (this.find ("@@@" + "BUILDINFO" + "@@@", 2))
		{
			// replace current string
			var sel = this.getSelection();
			this.setSelection (sel[0], sel [1], sel[0]+1, 0);
			this.textselection = text + "\n";
		}
		else
		{
			var sel = this.getSelection();
			this.setSelection (sel[0], 0);
			this.textselection = "/**\n* " + text + "\n*/\n";
		}
	}
}

//-----------------------------------------------------------------------------
// 
// Document.prototype.reload(...)
// 
// Purpose: Reload document contents (if not modified)
// 
//-----------------------------------------------------------------------------

Document.prototype.reload = function()
{
    if( this.isFile() && !this.isModified() )
    {
        var myFile = new File( this.scriptID );
        
		myFile.encoding = this.encoding;
		var text = Document.safeRead (myFile);
		if (null != text)
		{
			this.encoding = myFile.encoding;
		    this.setText( text, false );
			this.setSavePoint();
			this.setTitle();
	    }

    }
}

//-----------------------------------------------------------------------------
// 
// Document.prototype.setSaved(...)
// 
// Purpose: Set the saved state
// 
//-----------------------------------------------------------------------------

Document.prototype.setSaved = function( uri )
{
    if( uri )
		this.setScriptID( uri );

	if (this.isFile())
	{
		var f = File (this.scriptID);
		this.paneTitle = f.fsName;
		this.fileName  = f.name;
		this.roState = f.readonly;

		var langID = this.langID;
		
		if( !langID || ( langID && langID == '' ) )
		    langID = lang.getLanguageForFile (File (this.scriptID));
		if (langID)
			this.setLanguage (langID);

		if( menus.file.recent )
		    menus.file.recent.add (this.scriptID, this.langID);
	}
	this.setSavePoint();
	this.setTitle();
}

//-----------------------------------------------------------------------------
// 
// Document.prototype.save(...)
// 
// Purpose: Save the document:
//              saveAs  - invoke Save As
//              ask     - ask before saving
//          retuns true if saved, false on errors or if the result of asking 
//          was Cancel
// 
//-----------------------------------------------------------------------------

Document.prototype.save = function (saveAs, ask)
{
	// do not save non-documents
	if (!this.paneTitle)
		return true;

	// TODO: save to target
	if (ask)
	{
		switch (app.saveAlert ( decodeURIComponent(this.fileName)))
		{
			case -1:	return false;
			case 0:		return true;
		}
	}

	var f = null;

	if (saveAs)
	{	
	    if( !this.currentFolder )
	        this.currentFolder = app.currentFolder;
	        
        var obj = lang.getLexerAndStyles (this.langID);	        
        
        var proposedName = this.fileName;
        var fileExt      = '.' + obj.defFileExt;
        
        if( proposedName.indexOf( fileExt ) < 0 )
            proposedName += fileExt;
        	        
		var f = File( this.currentFolder + '/' + proposedName );
		f = f.saveDlg( localize( "$$$/ESToolkit/FileDlg/SaveAs=Save As" ), lang.buildFileTypes (this.langID) );
		
		if(f)
		    // remember the folder
		    this.currentFolder = app.currentFolder = 
			f.parent ? f.parent.absoluteURI : "/";
		
	}
	else
	{
		// normal save
		// do nothing if doc is not modified
		if (!this.isModified())
			return true;
			
		if (this.scriptID[0] == '(')
			// no file name yet
			return this.save (true);

// TODO: save to target
		f = new File (this.scriptID);
	}

	if (f)
	{
		// if the selected file already is open, do not save
		var doc = Document.find (f.absoluteURI);
		if (doc && doc != this)
		{
			errorBox ("$$$/ESToolkit/FileDlg/InUse=File %1 is currently opened and cannot be overwritten.", decodeURIComponent(f.name) );
			return false;
		}
		// If the file is read-only, abort
		if (f.readonly)
		{
			var msg = _win
					? "$$$/ESToolkit/FileDlg/ProtectedWin=Could not save as %1 because the file is locked.^nUse the 'Properties' command in the Windows Explorer to unlock the file."
					: "$$$/ESToolkit/FileDlg/ProtectedMac=Could not save as %1 because the file is locked.^nUse the 'Get Info' command in the Finder to unlock the file.";
			errorBox( msg, decodeURIComponent(f.name) );
			
			return false;
		}
		
		var error = "";
		
		if( f.open("w") )
		{
			// Remove from Folder Watch to inhibit own notification
			app.removeFileWatch( this, f );
			f.encoding = this.encoding;
			f.lineFeed = this.lf;
			f.write (this.text);
			error = f.error;
			f.close();
			if (error == "")
				error = f.error;
			
			// we are good citizen
			app.notifyFileChanged (f);
			// and re-enable file watch
			app.addFileWatch( this, f );
		}
		else
			error = f.error;
		if (error != "")
			errorBox ("$$$/ESToolkit/FileDlg/CannotWrite=Cannot write to file %1!\n" + error, decodeURIComponent( f.name ) );
		else
		{
			this.setSaved (f.absoluteURI);

	        if( saveAs )
	        {
	            scripts.fillScripts();
	            menus.updateWindowMenu();
            }
                    	    
			return true;
		}
	}
	
	return false;
}

//-----------------------------------------------------------------------------
// 
// Document.prototype.exportAsBinary(...)
// 
// Purpose: Export script as jsxbin
// 
//-----------------------------------------------------------------------------

Document.prototype.exportAsBinary = function()
{
	var s;

	// do not save non-documents or docs that are not JS
	if (!this.paneTitle || (this.langID != "js"))
		return true;

	if( !this.checkSyntax( this.includePath ) )
		return false;
	try
	{
		s = app.compile (this.text);
	}
	catch (e)
	{
		return false;
	}

    if( !this.currentFolder )
        this.currentFolder = app.currentFolder;

	var pos = this.fileName.lastIndexOf ('.');
	
	if( pos < 0 )
		pos = this.fileName.length;
		
	var proposedName = this.fileName.substr( 0, pos ) + ".jsxbin";
	var f = File( this.currentFolder );
	f.changePath( proposedName );
	f = f.saveDlg( localize( "$$$/ESToolkit/FileDlg/ExportAsBinary=Export To Binary JavaScript" ),
				   localize( "$$$/ESToolkit/FileDlg/JSXBIN=Binary JavaScript files:*.jsxbin" ));
	if(f)
	{
	    // remember the folder
	    this.currentFolder = app.currentFolder = 
			f.parent ? f.parent.absoluteURI : "/";

		// If the file is read-only, abort
		if (f.readonly)
		{
			var msg = _win
					? "$$$/ESToolkit/FileDlg/ProtectedWin=Could not save as %1 because the file is locked.^nUse the 'Properties' command in the Windows explorer to unlock the file."
					: "$$$/ESToolkit/FileDlg/ProtectedMac=Could not save as %1 because the file is locked.^nUse the 'Get Info' command in the Finder to unlock the file.";
			errorBox (msg, decodeURIComponent( f.name ) );
			return false;
		}
		if (f.open ("w"))
		{
			f.lineFeed = this.lf;
			f.encoding = this.encoding;
			f.write (s);
			f.close();
			
			// we are good citizen
			app.notifyFileChanged (f);
		}
		if (f.error != "")
			errorBox ("$$$/ESToolkit/FileDlg/CannotWrite=Cannot write to file %1!", decodeURIComponent( f.name ) );
		else
			return true;
	}
	return false;
}

//-----------------------------------------------------------------------------
// 
// Document.prototype.close(...)
// 
// Purpose: Close the document (return false on error or abort)
// 
//-----------------------------------------------------------------------------

Document.prototype.close = function()
{
	// do not close non-documents
	if (this.paneTitle)
		return this.parent.close();
	return true;
}

//-----------------------------------------------------------------------------
// 
// Document.prototype.setStyles(...)
// 
// Purpose: Set an XML list of styles
// 
//-----------------------------------------------------------------------------

Document.prototype.setStyles = function (styles)
{
	if (styles)
	{
		for (var i = 0; i < styles.length(); i++)
		{
			var style = styles [i];
			// Never set the default style
			if (style.@index == 32)
				continue;
			// <style title fore back color name size bold italics />
			var obj = lang.getStyleValues (style);
			this.setStyle (obj.index, obj.fore, obj.back, obj.name, obj.size, obj.bold, obj.italics);
		}
	}
}

//-----------------------------------------------------------------------------
// 
// Document.prototype.setLanguage(...)
// 
// Purpose: Set the lexer language
// 
//-----------------------------------------------------------------------------

Document.prototype.setLanguage = function (langID)
{
	if (langID != this.langID)
	{
		var xml = lang.getLexerAndStyles (langID);
		// get the default style (which is #32)
		var style = xml.xpath ('style[@index=32]');
		var obj = lang.getStyleValues (style);
		this.clearStyles (obj.fore, obj.back, obj.name, obj.size, obj.bold, obj.italics);
		this.setStyles (xml.style);
		// Convert the keywords to a simple array
		var kwds = [];
		for (var i = 0; i < xml.keywords.length(); i++)
			kwds [Number (xml.keywords [i].@index)] = xml.keywords [i].toString();

		this.setLexer (xml.lexer.toString(), kwds, xml.wordChars.toString());
		this.langID = langID;
	}
}

//-----------------------------------------------------------------------------
// 
// Document.prototype.checkSyntax(...)
// 
// Purpose: Do a syntax check and display the result. Return false on errors.
// 
//-----------------------------------------------------------------------------

Document.prototype.checkSyntax = function (includes)
{
	if( !includes )
		includes = this.isFile() ? File (this.scriptID).parent : "";
		
    var result = app.checkSyntax (this.text, includes);
    
    if( result.error )
    {
		app.beep();
		
		var doc = this;
		
		if( this.scriptID != result.file && result.file.length > 0 )
		{
		    var f = new File( result.file );
		    var tmp = Document.load( f );
		    
		    if( tmp && tmp.document )
		        doc = tmp.document;
		}

		if( result.line1 == result.line2 )
		{
			// Set this.badLine, which is removed on the next edit
			doc.badLine = result.line1;
			doc.setCurrentLine (result.line1, colors.Coral);
		}

		doc.setSelection (result.line1, result.col1, result.line2, result.col2, true);
        Document.setStatusLine( result.error, doc );
    }
    else
        Document.setStatusLine( '$$$/ESToolkit/Status/NoErrors=No Errors', this );
    
    return ( result.error ? false : true );
}

//-----------------------------------------------------------------------------
// 
// Document.prototype.writePrefs(...)
// 
// Purpose: Write document preferences
// 
//-----------------------------------------------------------------------------

Document.prototype.writePrefs = function()
{
    // do not save empty files, only disk files
    if( this.isFile() )
    {
        var index = PrefUtils.getValue( 'prefs.documents.length', 'Number' );
        
        for( var i=0; i<index; i++ )
        {
            if( this.scriptID == prefs.documents[i].scriptID )
            {
                index = i;
                break;
            }
        }
    
        //
        // lexer
        //
		prefs.documents[index].langID   = this.langID;

        //
        // target & engine
        //
        var targetName = '';
        var engineName = '';

        if( this.parent.toolbarGroup.targetGroup.targetDDL.selection )
            targetName = this.parent.toolbarGroup.targetGroup.targetDDL.selection.target;
        if( this.parent.toolbarGroup.targetGroup.engineDDL.selection )
            engineName = this.parent.toolbarGroup.targetGroup.engineDDL.selection.text;
            
        prefs.documents[index].target    = targetName;
        prefs.documents[index].engine    = engineName;
        
        //
        // view prefs
        //
        prefs.documents[index].wrap      = this.wrap.toString();
		prefs.documents[index].folding   = ( this.folding == 3 ? 'true' : 'false' );
        prefs.documents[index].lineNum   = this.lineNumbers.toString();
        
        //
        // line endings
        //
        prefs.documents[index].lineend   = this.lf;
        
        //
        // bookmarks
        //
        prefs.documents[index].bookmarks = this.bookmarks.toString();

        //
        // documents scriptID
        //
        prefs.documents[index].scriptID = this.scriptID;    // this need to be the last entry!!
        
        var length = PrefUtils.getValue( 'prefs.documents.length', 'Number' );
        
        if( index >= length )
            prefs.documents.length = length + 1;
    }    
}

//-----------------------------------------------------------------------------
// 
// Document.prototype.readPrefs(...)
// 
// Purpose: Read document preferences
// 
//-----------------------------------------------------------------------------

Document.prototype.readPrefs = function()
{
	this.lineNumbers	= PrefUtils.getValue( 'prefs.document.lineNumbers', 'Boolean' );
	this.wrap			= PrefUtils.getValue( 'prefs.document.wrap', 'Boolean' );
	this.folding		= PrefUtils.getValue( 'prefs.document.folding', 'Boolean' ) ? 3 : 0;
	this.tabs           = PrefUtils.getValue( 'prefs.document.tabs', 'Number' );
	
	var docs = PrefUtils.getValue( 'prefs.documents.length', 'Number' );

    for( var i=0; i<docs; i++ )
    {
        if( prefs.documents[i].scriptID == this.scriptID )
        {
            //
            // target & engine
            //
            var targetName = prefs.documents[i].target.toString();
            var engineName = prefs.documents[i].engine.toString();

            if( targetName.length > 0 )
                targetMgr.setActive( targetName, engineName, this );
                
            //
            // view prefs
            //                                
            this.wrap           = prefs.documents[i].wrap == 'true';
			this.folding        = ( prefs.documents[i].folding == 'true' ? 3 : 0 );
            this.lineNumbers    = prefs.documents[i].lineNum == 'true';
                
            //
            // line endings
            //
	        this.lf             = prefs.documents[i].lineend;
        	
	        if( this.lf.toString().length == 0 )
	            this.lf = Folder.fs.toLowerCase();
	            
            //
            // bookmarks
            //
            var bmstr = prefs.documents[i].bookmarks.toString();
            
            if( bmstr.length > 0 )
            {
                var bms = bmstr.split(',');
                
                for( var b=0; b<bms.length; b++ )
                    this.addBookmark( parseInt( bms[b] ) );
            }
            
            break;
        }
    }
}

//-----------------------------------------------------------------------------
// 
// Document.prototype.setScriptID(...)
// 
// Purpose: Set documents scriptID
// 
//-----------------------------------------------------------------------------

Document.prototype.setScriptID = function( scriptID )
{
	if (this.scriptID != scriptID)
	{
		if( this.isFile() )
			app.removeFileWatch( this, File( this.scriptID ) );

		this.scriptID = scriptID;
		
		if( this.isFile() )
			app.addFileWatch( this, File( this.scriptID ) );
	}
}

//-----------------------------------------------------------------------------
// 
// Document.prototype.getAllBreakpoints(...)
// 
// Purpose: Get a list of all breakpoints. This call returns an array if 
//          breakpoints containing objects. Each objects contains a line property 
//          (number, zero-based), a enabled property (true/false), and a condition 
//          property (string) if there is a condition attached.
// 
//-----------------------------------------------------------------------------

Document.prototype.getAllBreakpoints = function( enabled )
{
	var bps     = new XML( '<breakpoints engine="" flags=""></breakpoints>' );
	var lines   = this.getBreakpoints();

	for( var i=0; i<lines.length; i++ )
	{
        var line    = lines[i];
		var bp      = this.getBreakpoint( line );
		
		if( bp[0] != -1 )
		{
			var bpxml		= new XML ('<breakpoint/>');
			bpxml.@file		= this.scriptID;
			bpxml.@line		= line + 1;
			bpxml.@enabled	= (bp[0] != 0);
			bpxml.@hits		= bp[1];
			bpxml.@count	= bp[3];
			if (bp[2].length)
				bpxml.appendChild (bp[2]);
			if( !enabled || ( enabled && bp[0] == 1 ) )
			    bps.appendChild( bpxml );
		}
	}
	return bps;
}

//-----------------------------------------------------------------------------
// 
// Document.prototype.toggleBreakpoint(...)
// 
// Purpose: Toggle a breakpoint from off to enabled to disabled.
// 
//-----------------------------------------------------------------------------

Document.prototype.toggleBreakpoint = function( line )
{
    //
    // breakpoint array:
    // element 0 : state
    //         1 : hitcount
    //         2 : condition
    //         3 : current hits
    //
	var bp = this.getBreakpoint( line );

	if( !bp )
		bp = [ -1, 1, '', 0 ];
		
	switch( bp[0] )
	{
		case -1:	bp[0] = 1; break;	// hidden -> enabled
		case 0:		bp[0] = -1; break;	// disabled -> hidden
		default:	bp[0] = 0;			// enabled -> disabled
	}
	
	//
	// update document window
	//
	this.setBreakpoint( line, bp[0], bp[1], bp[2], bp[3] );
	
	//
	// send if connected
	//
	targetMgr.sendBreakpoints();

    //	
	// Update the Breakpoints pane
	//
	breakpoints.update();
}

//-----------------------------------------------------------------------------
// 
// Document.prototype.removeAllBreakpoints(...)
// 
// Purpose: Remove all breakpoints and conditions.
// 
//-----------------------------------------------------------------------------

Document.prototype.removeAllBreakpoints = function()
{
	var lines = this.getBreakpoints();
	
	for( var i=0; i<lines.length; i++ )
		this.removeBreakpoint( lines[i] );
		
	if( lines.length )
	{
        //	
	    // Update the Breakpoints pane
	    //
	    breakpoints.update();
	}
}

//-----------------------------------------------------------------------------
// 
// Document.prototype.updateBreakpoints(...)
// 
// Purpose: Evaluate the body of a Breakpoints message sent by the target.
//          This message contains a list of altered breakpoints, two numbers
//          on each line. If the breakpoint could not be set at all, the second
//          number is < 0.
// 
//-----------------------------------------------------------------------------

Document.prototype.updateBreakpoints = function (bt)
{
	var reply = bt.splitBody();
	
	for( var i=0; i<reply.length; i++ )
	{
		var oldLine = +reply [i][0];
		var newLine = +reply [i][1];
		var oldBP	= this.getBreakpoint (oldLine);
		this.removeBreakpoint (oldLine);

		if (!oldBP)
			oldBP = [1, 1, ""];

		if (newLine >= 0)
			this.setBreakpoint( newLine, oldBP[0], oldBP[1], oldBP[2], oldBP[3] );
    }
    
	// If any BP locations were changed, update the Breakpoints pane
	if (reply.length)
		breakpoints.update();
}

///////////////////////////////////////////////////////////////////////////////
//
// Class methods
//

//-----------------------------------------------------------------------------
// 
// Document.load(...)
// 
// Purpose: [static] load document
// 
//-----------------------------------------------------------------------------

Document.load = function (file, langID)
{
	if (!(file instanceof File))
		return null;
	var doc = Document.find (file.absoluteURI);
	if (doc)
	{
		// already loaded
		doc.activate();
		return doc.parent;
	}

	if (!langID)
		langID = lang.getLanguageForFile (file);
	if (!langID)
		return null;
	var text = Document.safeRead (file);
	if (null == text)
		return null;

	var w = this.newDoc (file.name, langID, file.absoluteURI);
	
	w.document.roState  = file.readonly;
	w.document.encoding = file.encoding;
	w.document.setText( text, false );
	w.document.clearUndo();
	w.document.setSaved();

	w.show();
	
	return w;
}

//-----------------------------------------------------------------------------
// 
// Document.create(...)
// 
// Purpose: [static] create document
// 
//-----------------------------------------------------------------------------

Document.create = function (title, text, scriptID )
{
	if (text == undefined)
		text = "";

	var w = this.newDoc( title, PrefUtils.getValue( 'prefs.document.language', 'String' ), scriptID );

	w.document.setText( text, false );
	w.document.clearUndo();
	w.document.setSaved();
	w.skipRectPrefs = true;

	w.show();
	
	return w;
}

//-----------------------------------------------------------------------------
// 
// Document.find(...)
// 
// Purpose: [static] find opened document with given scriptID
// 
//-----------------------------------------------------------------------------

Document.find = function (scriptID)
{
    for (var i = 0; i < documents.length; i++)
	{
		if (documents [i].scriptID == scriptID)
			return documents [i];
	}
	return null;
}

//-----------------------------------------------------------------------------
// 
// Document.loadPrefs(...)
// 
// Purpose: [static] load all documents from preferences
// 
//-----------------------------------------------------------------------------

Document.loadPrefs = function()
{
	var docs = PrefUtils.getValue( 'prefs.opendocs.length', 'Number' );

    for( var i=0; i<docs; i++ )
    {
        var scriptID = prefs.opendocs[i].scriptID.toString();
        
        if( scriptID && ( scriptID[0] == '/' || scriptID[0] == '~' ) )
        {
            if( !this.load( new File( scriptID ), prefs.opendocs[i].langID ) )
                break;
        }
    }

    return ( docs > 0 );
}

//-----------------------------------------------------------------------------
// 
// Document.readPrefs(...)
// 
// Purpose: [static] read/write preferences for all opened documents
// 
//-----------------------------------------------------------------------------

Document.readPrefs = function()
{
    for (var i = 0; i < documents.length; i++)
		documents [i].readPrefs();
}

Document.writePrefs = function()
{
    prefs.opendocs.length = documents.length;
    
    for( var i=0; i<documents.length; i++ )
    {
        prefs.opendocs[i].scriptID = documents[i].scriptID;
        prefs.opendocs[i].langID   = documents[i].langID;
        
        if( documents[i].isFile() )
            documents[i].writePrefs();
    }
}

//-----------------------------------------------------------------------------
// 
// Document.saveAll(...)
// 
// Purpose: [static] save all opened files
//                   return false on error or abort
// 
//-----------------------------------------------------------------------------

Document.saveAll = function (ask)
{
	var ok = true;
	var oldDoc = document;
	try
	{
		for (var i = 0; ok && i < documents.length; i++)
		{
			if (documents[i].isModified())
			{
				documents[i].activate();
				// do not Save As, ask before saving
				ok = document.save (false, true);
			}
		}
	}
	catch (e) 
	{
		ok = false;
	}
	if (oldDoc)
		oldDoc.activate();
	return ok;
}

//-----------------------------------------------------------------------------
// 
// Document.previousDoc(...)
// 
// Purpose: [static] Switch to the previous/next doc
// 
//-----------------------------------------------------------------------------

Document.previousDoc = function()
{
	for( var i=0; i<documents.length; i++ )
	{
		if( documents[i] == document )
		{
		    i--;
		    
			if( i < 0 )
				i = documents.length-1;

			documents[i].activate();
			break;
		}
	}
}

// Switch to the next doc

Document.nextDoc = function()
{
	for( var i=0; i<documents.length; i++ )
	{
		if( documents[i] == document )
		{
		    i++;
		    
			if( i >= documents.length )
				i = 0;
				
			documents[i].activate();
			break;
		}
	}
}

//-----------------------------------------------------------------------------
// 
// Document.cascade(...)
// 
// Purpose: [static] cascade document windows
// 
//-----------------------------------------------------------------------------

Document.cascade = function()
{
    workspace.cascadeDocuments();
}

//-----------------------------------------------------------------------------
// 
// Document.tile(...)
// 
// Purpose: [static] tile document windows
//                   orientation - 'horizontal' or 'vertical'
// 
//-----------------------------------------------------------------------------

Document.tile = function(orientation)
{
    workspace.tileDocuments(orientation);
}

//-----------------------------------------------------------------------------
// 
// Document.setStatusLine(...)
// 
// Purpose: [static] set status text at given document (use topmost document
//                   if no valid document passed)
// 
//-----------------------------------------------------------------------------

Document.setStatusLine = function( text, doc )
{
    var currentDoc = document;
    
    if( doc )
        currentDoc = doc;
    
    if( currentDoc )
        currentDoc.setStatusLine( text );
}


///////////////////////////////////////////////////////////////////////////////
//
// profiling
//

Document.clearProfData = function()
{
    for( var i=0; i<documents.length; i++ )
        documents[i].clearProfileData();
}

Document.setProfiling = function( profType )
{
    for( var i=0; i<documents.length; i++ )
    {
        if( documents[i].profiling != profType )
            documents[i].profiling = 0;
    }
}

Document.clearProfileData = function()
{
    for( var i=0; i<documents.length; i++ )
        documents[i].eraseProfileData();
}

Document.updateProfData = function()
{
    for( var i=0; i<documents.length; i++ )
    {
        if( PrefUtils.getValue( 'prefs.profiling.profDisplayMode', 'Number' ) == 0 )
        {
            documents[i].profiling = 0;
            documents[i].clearProfileData();
        }
        else
            documents[i].updateProfData();
    }
}

// Dump the profiler data into a file.

Document.saveProfData = function()
{
	var f = new File (app.currentFolder + "/profileData.csv");
	f = f.saveDlg (
			localize ("$$$/ESToolkit/ProfSaveDlg/Title=Save Profiler Data"),
			localize ("$$$/ESToolkit/ProfSaveDlg/Types=CSV (Comma Delimited):*.csv"));

	if (f)
	{
		if (f.open ("w"))
		{
			f.encoding = "UTF-8";
			for (var i = 0; i < documents.length; i++)
			{
				var scriptID = documents [i].scriptID;
				if (scriptID[0] == '/' || scriptID [0] == '~')
				{
					var tmp = new File (scriptID);
					scriptID = tmp.fsName;
				}
				var data = documents [i].profileData;
				if (!data)
					continue;
				for (var j = 0; j < data.length; j++)
				{
					var line = data [j];
					f.write (scriptID + ',' + (line.line+1) + ',' + line.time + ',' + line.hit + '\n');
				}
			}
		}
		if (f.error.length || !f.close())
		{
			errorBox ("$$$/ESToolkit/FileDlg/CannotWrite=Cannot write to file %1!", decodeURIComponent( f.fsName ) );
			f.remove();
		}
			
		// we are good citizen
		app.notifyFileChanged (f);
	}
}

///////////////////////////////////////////////////////////////////////////////
//
// safe read
//

//-----------------------------------------------------------------------------
// 
// Document.safeRead (file)
// 
// Purpose: [static] Do a safe read. Open the file, read it, and close it.
//			On errors, display an error message (if quiet is undefined/false) 
//			and return null; otherwise,	return the text read.
// 
//-----------------------------------------------------------------------------

Document.safeRead = function (file, quiet)
{
	var text = null;
	var error = "";
	if (file.open())
	{
		switch (file.encoding)
		{
			case "UCS-2BE":
			case "UCS-2LE":
			case "UCS-4BE":
			case "UCS-4LE":
			case "UTF-8":
			case "UTF8":
				// Auto-detected encoding
				text = file.read();
				error = file.error;
				break;
			default:
				// no autodetection: force UTF-8 as 1st attempt
				file.encoding = "UTF-8";
				text = file.read();
				error = file.error;
				if (error != "" && file.encoding != app.systemEncoding)
				{
					// retry with the system encoding
					file.encoding = app.systemEncoding;
					file.seek (0);
					text = file.read();
					error = file.error;
				}
		}
		file.close();
	}
	else
		error = file.error;

	if (error.length)
	{
		if (!quiet)
		{
			text = localize ("$$$/ESToolkit/FileDlg/CannotOpen=Cannot open file %1!", decodeURIComponent( file.name ) );
			text += "\n" + file.error;
			errorBox (text);
		}
		text = null;
	}
	return text;
}

///////////////////////////////////////////////////////////////////////////////
//
// auto completion
//

//-----------------------------------------------------------------------------
// 
// Document.startAutoCompletion(...)
// 
// Purpose: [static] Start auto completion. Therefore get code hints from omv 
//                   for the search string (from cursor position back to previous 
//                   whitespace) and fill listbox with code hints
// 
//-----------------------------------------------------------------------------

Document.startAutoCompletion = function()
{       
    if( Document.autoCompletion && Document.autoCompletion.autoDoc == document )
        document.startAutoCompletion();
}
