/**************************************************************************
*
*  @@@BUILDINFO@@@ 22breakpoints-2.jsx 2.0.1.65   24-April-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.
**************************************************************************/

breakpoints = null;

/*
Breakpoints are kept as XML. This XML has the same format as the XML understood
by the ESTK debugging backend in the target:

<breakpoints engine="..." flags="n">
    <breakpoint file="..." line="..." [enabled="..."] [hits="..."] [count="..."]>[cond]</breakpoint>
	...
</breakpoints>
 
- engine is the target engine.
- flags are the debug flags (especially 1024 - don't stop on guarded exceptions).
- enabled is true or false, and optional (default: true).
- hits is the hit count.
- count is the real hit count. If not supplied when setting (or < 0), keep the real hit count.
- cond is the optional condition.

Just send this table over to the target to set breakpoints. No response is expected.
When getting breakpoints, use a body of <get-breakpoints engine="..."/>. The returned
data is again the same list as above. There is no way to detect invalid breakpoints.
*/

//-----------------------------------------------------------------------------
// 
// app.createBreakpoints(...)
// 
// Purpose: Create and setup breakpoints palette
// 
//-----------------------------------------------------------------------------

app.createBreakpoints = function (where)
{
    //
    // create breakpoints palette window
    //
	breakpoints = new Window( 
		"dockpalette {													\
			text:'$$$/ESToolkit/Panes/Breakpoints/Title=Breakpoints',   \
			properties: { 											    \
				name:'breakpoints',                                     \
			    defaultVisibility : true,								\
				flyoutmenu: true,										\
				icon : '#PBreakpoints_N',	\
				rollover : '#PBreakpoints_R',"
			 +  where
			 +  "},													    \
			preferredSize: [100, 100],									\
			margins      : 2,                                           \
			spacing      : 2,                                           \
			list: ListBox {											    \
				preferredSize: [10, 20],								\
				alignment: ['fill', 'fill' ]	}					    \
            infogrp : Group                                         \
            {                                                       \
                orientation : 'row',                                \
                margins      : 0,                                   \
                spacing      : 0,                                   \
                alignment	: ['fill','bottom'],					\
                targetField: EditText                               \
                {								                    \
                    properties	: { readonly: true },	            \
                    alignment	: ['fill','bottom'],				\
                    characters : 40                                 \
                },													\
                sizeBoxSpacer    : Group                            \
                {                                                   \
                    alignment	: ['right','bottom'],				\
                    preferredSize        : [14,1]                   \
                }                                                   \
            }                                                       \
		}");
	
	breakpoints.id = "breakpoints";
	
	breakpoints.menuText = localize ("$$$/ESToolkit/Menu/Window/Breakpoints/Title=&Breakpoints");

	breakpoints.onNotify = function( reason )
	{
	    switch( reason )
	    {
	        case 'shutdown':
	            this.list.removeAll();
	            globalBroadcaster.unregisterClient( this );
	            break;
	            
	        case 'activeDocChanged':
	        {
	            this.update();
	            
	            if( document )
                    this.infogrp.targetField.textselection = document.paneTitle;
	            else
	                this.infogrp.targetField.text = '';
            }
            break;
	    }
	}
	
	globalBroadcaster.registerClient( breakpoints );
    targetMgr.registerClient( breakpoints );

	// Double click handler

	breakpoints.list.onDoubleClick = function()
	{
		if (this.selection)
			breakpoints.breakpointDialog (this.selection.breakpoint, false);
	}

	//
	// add flyout menu
	//
    var itemAdd = new MenuElement( 'command', '$$$/ESToolkit/Panes/Breakpoints/Flyout/Add=Add', "at the end of breakpoints/flyout", "breakpoints/flyout/add" );
    var itemMod = new MenuElement( 'command', '$$$/ESToolkit/Panes/Breakpoints/Flyout/Modify=Modify', "at the end of breakpoints/flyout", "breakpoints/flyout/modify" );
    var itemRem = new MenuElement( 'command', '$$$/ESToolkit/Panes/Breakpoints/Flyout/Remove=Remove', "at the end of breakpoints/flyout", "breakpoints/flyout/remove" );
	
	//
	// show palette
	//
	breakpoints.show();
	panes.push (breakpoints);
	
    ///////////////////////////////////////////////////////////////////////////////
    //
    // methods
    //
    
    //-----------------------------------------------------------------------------
    // 
    // itemMod.onDisplay(...)
    // itemRem.onDisplay(...)
    // 
    // Purpose: Enabled state of flyout menu items
    // 
    //-----------------------------------------------------------------------------
    
    itemMod.onDisplay = itemRem.onDisplay = function()
    {
        this.enabled = ( breakpoints.list.selection != null && breakpoints.enabled );
    }
    
    itemAdd.onDisplay = function()
    {
        this.enabled = breakpoints.enabled;
    }
    
    //-----------------------------------------------------------------------------
    // 
    // itemAdd.onSelect(...)
    // itemMod.onSelect(...)
    // 
    // Purpose: Flyout menu item add/modify clicked
    // 
    //-----------------------------------------------------------------------------
    
    itemAdd.onSelect = itemMod.onSelect = function()
    {
        if( document )
        {
            var bp = null;
			var add = false;
            if( this == itemMod && breakpoints.list.selection != null )
                bp = breakpoints.list.selection.breakpoint;
            else
                add = true, bp = new XML( '<breakpoint file="" line="1" enabled="true" hits="1" count="0"></breakpoint>' );

			breakpoints.breakpointDialog (bp, add);
        }
    }

    //-----------------------------------------------------------------------------
    // 
    // itemRem.onSelect(...)
    // 
    // Purpose: Flyout menu item remove clicked.
    // 
    //-----------------------------------------------------------------------------

    itemRem.onSelect = function()
    {
        if( breakpoints.list.selection != null && document )
        {
            var selIndex = breakpoints.list.selection.index;

            var line     = parseInt( breakpoints.list.selection.breakpoint.@line ) - 1;
        
            if( isNaN( line ) )     line = 0;
            
            document.removeBreakpoint( line );
            
            targetMgr.sendBreakpoints();
            breakpoints.update();
            
            if( breakpoints.list.items.length > selIndex )
                breakpoints.list.selection = selIndex;
            else
                breakpoints.list.selection = null;
        }
    }

	//-----------------------------------------------------------------------------
	// 
	// breakpoints.onResize(...)
	// breakpoints.onResizing(...)
	// 
	// Purpose: Palette resizing/resized
	// 
	//-----------------------------------------------------------------------------
	
	breakpoints.onResize = 
	breakpoints.onResizing = function ()
	{
		this.layout.resize();
	}
	
	//-----------------------------------------------------------------------------
	// 
	// breakpoints.breakpointDialog(...)
	// 
	// Purpose: Create and execute breakpoint dialog
	// 
	//-----------------------------------------------------------------------------
	
	breakpoints.breakpointDialog = function( bp, add )
	{
		if (!document)
			return;
		
	    var title = '$$$/ESToolkit/Dialogs/Breakpoint/Title=Add Breakpoint';
//	    var title = add ? '$$$/ESToolkit/Dialogs/Breakpoint/Title=Add Breakpoint'
//						: '$$$/ESToolkit/Dialogs/Breakpoint/TitleModify=Modify Breakpoint';
	    
	    var dlg = new Window( 
	           "prefdialog {                                                                            \
	                text : '" + title + "',                                                         \
	                properties :                                                                    \
	                {                                                                               \
	                    name : 'breakpoint'                                                         \
	                },                                                                              \
	                                                                                                \
	                groupAll : Group                                                                \
	                {                                                                               \
	                    orientation : 'column',                                                     \
	                    alignChildren : 'right',                                                    \
                                                                                                    \
                        groupLine : Group                                                           \
                        {                                                                           \
                            orientation : 'row',                                                    \
                                                                                                    \
	                        staticLine : StaticText                                                 \
	                        {                                                                       \
	                            text : '$$$/ESToolkit/Dialogs/Breakpoint/Line=Line:'                \
	                        },                                                                      \
	                                                                                                \
	                        editLine : EditText                                                     \
	                        {                                                                       \
	                            preferredSize : [60, 20],                                           \
	                            helpTip : '$$$/ESToolkit/Dialogs/Breakpoint/htLine=The line number in the source code for the breakpoint.'                \
	                        },                                                                      \
	                                                                                                \
	                        checkActive : Checkbox                                                  \
	                        {                                                                       \
	                            text : '$$$/ESToolkit/Dialogs/Breakpoint/Checkbox=Active',          \
	                            preferredSize : [230, 20],                                          \
	                            helpTip : '$$$/ESToolkit/Dialogs/Breakpoint/htActive=Check this box to activate the breakpoint.'                \
	                        }                                                                       \
                        },                                                                          \
                                                                                                    \
                        groupCond : Group                                                           \
                        {                                                                           \
                            orientation : 'row',                                                    \
                                                                                                    \
	                        staticCond : StaticText                                                 \
	                        {                                                                       \
	                            text : '$$$/ESToolkit/Dialogs/Breakpoint/Condition=Condition:'      \
	                        },                                                                      \
                                                                                                    \
	                        editCond : EditText                                                     \
	                        {                                                                       \
	                            preferredSize : [300, 40],                                          \
	                            multiline: true,                                                     \
	                            helpTip : '$$$/ESToolkit/Dialogs/Breakpoint/htCondition=Condition when the breakpoint should be hit.'                \
	                        }                                                                       \
                        },                                                                          \
                                                                                                    \
                        groupHit : Group                                                           \
                        {                                                                           \
                            orientation : 'row',                                                    \
                                                                                                    \
	                        staticCond : StaticText                                                 \
	                        {                                                                       \
	                            text : '$$$/ESToolkit/Dialogs/Breakpoint/HitCount=Hit count:'       \
	                        },                                                                      \
                                                                                                    \
	                        editHit : EditText                                                     \
	                        {                                                                       \
	                            text : '1',      \
	                            preferredSize : [50, 20]                                          \
	                        }                                                                       \
                        },                                                                          \
                                                                                                    \
                        groupButtons : Group                                                        \
                        {                                                                           \
                            orientation : 'row',                                                    \
                                                                                                    \
	                        buttonRemove : Button                                                   \
	                        {                                                                       \
	                            text : '$$$/ESToolkit/Dialogs/Breakpoint/buttonRemove=Remove',      \
	                            visible : " + ( bp.line > -1 ? "true" : "false" ) + "               \
	                        },                                                                      \	                                                                                                \
							okBtn			: Button			\
							{									\
								text			: '$$$/CT/ExtendScript/UI/OK=&OK', \
								properties		: {				\
									name			:'ok'		\
								}								\
							},						        	\
							cancelBtn		: Button			\
							{									\
								text			 : '$$$/CT/ExtendScript/UI/Cancel=&Cancel', \
								properties		: {				\
									name			: 'cancel'	\
								}								\
							}						        	\
                        }                                                                           \
                    }                                                                               \
	            } " );
	     
		dlg.buttonOK		= dlg.groupAll.groupButtons.okBtn;
		dlg.buttonRemove	= dlg.groupAll.groupButtons.buttonRemove;
		dlg.editCond		= dlg.groupAll.groupCond.editCond;
		dlg.editLine		= dlg.groupAll.groupLine.editLine;
		dlg.checkActive		= dlg.groupAll.groupLine.checkActive;
		dlg.editHit			= dlg.groupAll.groupHit.editHit;

		// save the document (Mac loses the document during a modal dialog)
		dlg.document = document;
		
        //
        // handle buttons
        //	            
        dlg.buttonOK.onClick = function()
        {
			var result = app.checkSyntax( dlg.editCond.text );
			if (result.error)
			{
				errorBox (result.error);
				dlg.editCond.active = true;
				return;
			}

			result = Number (dlg.editLine.text);
			if (isNaN (result) || result < 1 || result > dlg.document.lines.length)
			{
				app.beep();
				dlg.editLine.active = true;
				return;
			}
            dlg.close(1);
        }

		dlg.buttonRemove.onClick = function()
        {
			var line = Number (dlg.editLine.text);
			if (isNaN (line) || line < 1 || line > dlg.document.lines.length)
			{
				app.beep();
				dlg.editLine.active = true;
				return;
			}
				
			dlg.document.removeBreakpoint( line-1 );
			
			targetMgr.sendBreakpoints();
			breakpoints.update();

            dlg.close(0);
        }

        //
        // fill controls with existing values
        //	            
        var line    = parseInt( bp.@line );
        var hits    = parseInt( bp.@hits );
        var enabled = ( bp.@enabled == 'true' ? true : false );
        
        if( isNaN( line ) )     line = 1;
        if( isNaN( hits ) )     hits = 0;

        dlg.editLine.text       = line;
        dlg.editCond.text       = bp.toString();
        dlg.checkActive.value   = enabled;
        dlg.editHit.text        = hits;
        
        //
        // display dialog
        //
	    dlg.center();
	    
	    var ret = ( dlg.show() == 1 && dlg.editLine.text.length > 0 );

		//
		// switch focus back to the document
		//
		dlg.document.active = true;
		
        //
        // get values from dialog if closed with ok
        //
        if( ret )
        {
            bp.@line      = parseInt( dlg.editLine.text );
            bp.setChildren( dlg.editCond.text );
            bp.@enabled   = dlg.checkActive.value;
            bp.@hits      = parseInt( dlg.editHit.text );

			var newLine    = parseInt( bp.@line ) - 1;
			var newHits    = parseInt( bp.@hits );
			var newEnabled = ( bp.@enabled == 'true' ? 1 : 0 );
            
			if( isNaN( newLine ) || newLine < 0 )   newLine = 0, bp.@line = 1;
			if( isNaN( newHits ) )                  newHits = 0, bp.@hits = 0;

            if( !add && line-1 != newLine )
                document.removeBreakpoint( line-1 );
                
			document.setBreakpoint( newLine, newEnabled, newHits, bp.toString(), 0 );
			targetMgr.sendBreakpoints();
			breakpoints.update();
		}

        return ret;
    }

    //-----------------------------------------------------------------------------
    //
    // breakpoints.update(...)
    //
    // Purpose: Update breakpoints list in palette
    //
    //-----------------------------------------------------------------------------

    breakpoints.update = function()
    {
        if( document )
        {
            /* pwollek 02/04/2007
               We wanna show the breakpoints of the current document,
               not of the related target/engine!
            var targetName = document.getCurrentTargetName();
            var engineName = document.getCurrentEngineName();
            
            if( targetMgr.getConnected( targetName, true ) )
                this.updateFromTarget( targetName, engineName );
            else 
            */
                this.updateFromDoc( document );
        }
        else
            this.list.removeAll();
    }
    
    breakpoints.updateFromTarget = function( targetName, engineName )
    {
        var bt = BridgeTalk.create( targetName );
        bt.body = '<get-breakpoints engine="' + engineName + '"/>';
        bt.pane = this;
        
        bt.onOwnError = function (bt)
        {
            if( document )
                this.pane.updateFromDoc( document );
        }
        
        bt.onOwnResult = function (bt)
        {
            var bps = new XML( bt.body );
            
            if( bps.child(0).toXMLString().length > 0 )
                this.pane.doUpdate( bps );
            else if( document )
                this.pane.updateFromDoc( document );
        }
        
        bt.safeSend();
    }
    
    breakpoints.updateFromDoc = function( doc )
    {
		if( doc )
			this.doUpdate( doc.getAllBreakpoints() );
    }
            
    breakpoints.doUpdate = function( breakpoints )
    {    
        this.list.removeAll();
        
        if( breakpoints )
        {
            var bp          = null;
            var i           = 0;
            
            do
            {
                bp = breakpoints.child(i);
                i++;
                
                if( bp.toXMLString().length > 0 )
                {
                    var cond        = bp.toString();
                    var hitcount    = parseInt( bp.@hits );

                    var text        = localize( '$$$/ESToolkit/Panes/Breakpoints/Line=Line' ) + ' ' 
							        + ( parseInt( bp.@line ) );
    							    
				    if( cond.length > 0 )
				        text += ' ' + localize( '$$$/ESToolkit/Panes/Breakpoints/Cond=when' ) + ' ' + cond;
    				    
				    if( !isNaN( hitcount ) && hitcount > 1 )
				    {
				        if( cond.length > 0 )
				            text += ' ,';
    				        
				        text += ' ';
				        text += localize( '$$$/ESToolkit/Panes/Breakpoints/hitcount=Hitcount' ) + ' == ' + hitcount;
				        text += ' (' + localize( '$$$/ESToolkit/Panes/Breakpoints/cHitcount=Current' ) + ' == ' + bp.@count + ' )';
				    }
    								
                    var item        = this.list.add( 'item', text );
                    item.breakpoint = bp;
                    
                    var enabled     = ( item.breakpoint.@enabled == 'true' ? true : false );

                    if( cond.length )
                        item.icon = ( enabled ? '#BreakpointEnabledCond' : '#BreakpointDisabledCond' );
                    else
	                    item.icon = ( enabled ? '#BreakpointEnabled' : '#BreakpointDisabled' );
                }
            
            } while( bp.toXMLString().length > 0 )
        }
    }
}
