<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" xmlns:c="com.*" creationComplete="init()" layout="absolute" viewSourceURL="srcview/index.html">
 
<mx:Script> 
<![CDATA[ 
    import mx.controls.listClasses.ListBase;
    import mx.core.UIComponent;
    import mx.controls.Tree;
    import mx.collections.ArrayCollection;
    import mx.core.DragSource;
    import mx.managers.DragManager;
    import mx.events.DragEvent;
    import mx.events.TreeEvent;
    import flash.events.KeyboardEvent;
    import flash.events.MouseEvent;
    import flash.events.Event;
    import mx.utils.ObjectUtil;



private function init():void{
    /**
    * NOTE: if your using this in seperated out components and you find that your keyboard listener is not working
    * you may instead have to add the event listener to the stage rather than the component...
    /**
    
    * our aim is to be able to start dragging and then hold down the "d" key on our
    * keyboard, and then while i'm holding it, have it hit my debug point...
    * if you look at line: 118 you can put your debug point on that line, and while
    * your holding the letter "d" on you keyboard it will hit that point... (ONLY WHILE
    * HOLDING THE KEY THOUGH) this helps out tremendously with debuging mouse events.
    **/
    //right
    addEventListener(KeyboardEvent.KEY_DOWN,onKeyDown);
    addEventListener(KeyboardEvent.KEY_UP,onKeyUp);
}
[Bindable] private var isDebugMode:Boolean = false;
private static var DEBUG:uint = 68;
/*********************listeners*********************/
private function onKeyDown(event:KeyboardEvent):void{
    switch(event.keyCode){
        case DEBUG:
            isDebugMode = true;
            //trace('keyDown');
            break;
    }
}
private function onKeyUp(event:KeyboardEvent):void{
    switch(event.keyCode){
        case DEBUG:
            isDebugMode = false;
            //trace('keyUp');
            break;
    }
}
[Bindable]
public var selectedNode:Object;

[Bindable]
public var description:String = "Press 'd' on your keyboard while dragging and dropping, it's keyCode 68, and " +
        "you can use it to debug mouse events. \n \n" +
        "Directions:\n\nTo see the effect of the Spring Loaded Folders select " + 
        "an item in the tree and drag the item over the folders wait, hovering over the folder and " + 
        "it'll open.\n\nIf a folder opens and you did not want it to open move the mouse out of " + 
        "the tree, and it'll restore the original state. \n\nPlay around with the delay to get a " + 
        "desired delay.Hitting spacebar while dragging over a closed folder will open it immediately.";


public function treeChanged(event:Event):void {
    selectedNode=event.currentTarget.selectedItem;
}

private function onDragOver(event:DragEvent):void{
    try{
        if( event.dragInitiator is ListBase ){
            var list:ListBase = event.dragInitiator as ListBase;
            if( event.currentTarget != event.dragInitiator){
                //do what?
                //trace(mx.utils.ObjectUtil.toString('[currentTarget]'+event.currentTarget));
            }
            if(list.indexToItemRenderer(list.calculateDropIndex(event)) != null){
                    var currTree:Tree = Tree(event.currentTarget);
                    var currNodeOver:Object;
                    var rowIndex:int = currTree.calculateDropIndex(event);
                    var hoverTarget:Object = currTree.indexToItemRenderer(rowIndex).data;
                    var parent:Object = currTree.getParentItem(hoverTarget);
                    var tattlerStr:String = new String();
                    var halfRow:int = currTree.rowHeight/2;
                    var certerRowY:int = (rowIndex*currTree.rowHeight)+halfRow;
                    var bottomRowY:int = (rowIndex+1)*currTree.rowHeight;
                    
                    currNodeOver = currTree.indexToItemRenderer(rowIndex).data;
                    
                    DragManager.showFeedback(DragManager.MOVE);
                    currTree.showDropFeedback(event);
                    
                   

                    
                    tattlerStr = "Selected Item: " + selectedNode + "\n" + "Over Target: " + hoverTarget.level
                    + "\n" 
                    + "calculateDropIndex " + rowIndex
                    + "\n" 
                    + "halfRow " + halfRow.toString()
                    + "\n"
                    + "certerRowY " + certerRowY.toString()
                    + "\n"
                    + "bottomRowY " + bottomRowY.toString()
                    + "\n" 
                    + "mouseY " + currTree.mouseY.toString()
                    + "\n"
                    + "isItemOpen " + currTree.isItemOpen(currNodeOver).toString()
                    + "\n"
                    + "isDebugMode " + currTree.isItemOpen(currNodeOver).toString()
                    + "\n" + "\n";
                
                    tattler.text = tattlerStr;
                    
                    if (this.isDebugMode){
                        trace('put your debug point on this line')
                        tattler.text += '\n' + 'put your debug on this line';                        
                    }
                }else{
                    tattler.text = "No Drop Buddy";
                }
        }
    }catch(err:Error){
        trace('[error]'+err);
    }
    
}

private function onDragDrop(event:DragEvent):void{
    try{
        var target:Tree = Tree(event.currentTarget);
        var list:ListBase = event.dragInitiator as ListBase;
        var ds:DragSource = event.dragSource;
        var rowIndex:int = target.calculateDropIndex(event);
        var hoverTarget:Object = target.indexToItemRenderer(rowIndex).data;
        var parent:Object = target.getParentItem(hoverTarget);
        var items:Array = ds.dataForFormat("items") as Array;
        var i:int;
    
        //trace(event.dragInitiator);
        if( event.dragInitiator is DataGrid ){
            //do what?
            //trace(mx.utils.ObjectUtil.toString('[currentTarget]'+event.currentTarget));
            for (i=0; i < items.length; i++){
                var tempObj:Object = {};
                tempObj = items[i];
                parent.children.addItem(tempObj);
            }
            
            event.preventDefault();
        }
    }catch(err:Error){
        trace('[onDragDropError]'+err);
    }
    
}


private function onDragEnter(event:DragEvent):void{
    DragManager.acceptDragDrop(UIComponent(event.currentTarget));
}

private function onTreeDoubleClick(event:Event):void{
    var target:Tree = Tree(event.currentTarget);
    
    if( target.dataDescriptor.isBranch(target.selectedItem) ){
        target.selectedItem.children = this.newData;
        target.expandItem(target.selectedItem,true,true);
    }
    
}

private var newData:ArrayCollection = new ArrayCollection(
                         [
                         {label:"c1", level:"Course", type:"prereq"},
                         {label:"c2", level:"Course", type:"prereq"} 
                         ]
                         );
[Bindable]
private var treeData:ArrayCollection = new ArrayCollection(
[ {label:"Curriculum", level:"Curr", children:new ArrayCollection(
        [ {label:"cert1", level:"Cert", children:new ArrayCollection(
                        [{label:"c1", level:"Course", type:"prereq"},
                         {label:"c2", level:"Course", type:"prereq"} 
                         ])}
        ])},{label:"Curriculum", level:"Curr", children:new ArrayCollection(
        [ {label:"cert1", level:"Cert", children:new ArrayCollection()}
        ])}
]);

[Bindable]
private var secondTreeData:ArrayCollection = new ArrayCollection(
[ {label:"Curriculum", level:"Curr", children:new ArrayCollection(
        [ {label:"cert1", level:"Cert", children:new ArrayCollection(
                        [{label:"c1", level:"Course", type:"prereq"},
                         {label:"c2", level:"Course", type:"prereq"} 
                         ])}
        ])},{label:"Curriculum", level:"Curr", children:new ArrayCollection(
        [ {label:"cert1", level:"Cert", children:new ArrayCollection(
                        [{label:"c1", level:"Course", type:"prereq"},
                         {label:"c2", level:"Course", type:"prereq"} 
                         ])}
        ])}
]);


[Bindable]
private var gridDP:ArrayCollection = new ArrayCollection(
                    [{label:"c5", level:"Course", type:"prereq"},
                    {label:"c6", level:"Course", type:"prereq"},
                    {label:"c7", level:"Course", type:"prereq"}]);
]]>
</mx:Script>
<mx:VBox width="100%" height="100%">
    <mx:Canvas backgroundColor="#f3d7ab" borderColor="#000000" borderStyle="outset" width="100%" x="10" height="50%" y="10" horizontalScrollPolicy="off" verticalScrollPolicy="off">
            
            <mx:HBox width="100%" height="100%" >
                <c:SpringLoadedTree id="tree1" width="35%" height="100%"
                        autoCloseOpenNodes="{autoCloseOpenNodes.selected}" 
                        autoCloseOnDrop="{autoCloseOnDrop.selected}" 
                        autoOpenTimerMS="{DelayOpen.value}" 
                        autoCloseTimerMS="{DelayClose.value}" 
                        showOpeningIndication="{showOpenIdication.selected}" 
                        autoCloseOnExit="{autoCloseOnExit.selected}" 
                        backgroundAlpha="0.29"  
                        dataProvider="{treeData}"
                        mouseDown="treeChanged(event)"
                        fontWeight="bold" color="#000000"
                        dragEnabled="true" 
                        dragOver="onDragOver(event)"
                        dragMoveEnabled="true"
                        dropEnabled="true"
                        labelField="label" wordWrap="true"
                        fontSize="8" variableRowHeight="true"
                        x="41" y="20"
                        doubleClick="onTreeDoubleClick(event)"
                        doubleClickEnabled="true"/>
                        
                <c:SpringLoadedTree id="tree2" width="35%" height="100%"
                        autoCloseOpenNodes="{autoCloseOpenNodes.selected}" 
                        autoCloseOnDrop="{autoCloseOnDrop.selected}" 
                        autoOpenTimerMS="{DelayOpen.value}" 
                        autoCloseTimerMS="{DelayClose.value}" 
                        showOpeningIndication="{showOpenIdication.selected}" 
                        autoCloseOnExit="{autoCloseOnExit.selected}" 
                        backgroundAlpha="0.29"
                        dataProvider="{secondTreeData}"
                        mouseDown="treeChanged(event)"
                        fontWeight="bold" color="#000000"
                        dragEnabled="true" 
                        showRoot="false"
                        dragDrop="onDragDrop(event)"
                        dragEnter="onDragEnter(event)"
                        dragOver="onDragOver(event)"
                        dragMoveEnabled="true"
                        dropEnabled="true"
                        labelField="label" wordWrap="true"
                        fontSize="8" variableRowHeight="true"
                        x="41" y="20"/>

                
                <mx:DataGrid dataProvider="{gridDP}" id="grid1" 
                        dragEnabled="true"
                        dragMoveEnabled="true" height="100%">
                </mx:DataGrid>
                        
                <mx:Text text="{description}" id="Directions" enabled="true" height="100%" width="30%"/>
                
                
            </mx:HBox>
    </mx:Canvas>
    <mx:HBox width="100%" height="50%">
        <mx:TextArea x="10" y="368" width="50%" height="100%" id="tattler"/>
        <mx:Canvas width="50%" height="100%" y="446" x="470">
            <mx:CheckBox id="autoCloseOnDrop" selected="true" label="Return to original state on drop" left="10" right="10" bottom="96"/>
            <mx:HSlider value="1000" tickInterval="200" snapInterval="200" maximum="2000" allowTrackClick="true" minimum="200" id="DelayOpen" left="255" bottom="174" width="190"/>
            <mx:Label text="Folder auto open delay ms:{DelayOpen.value}" left="10" bottom="174" textAlign="left" width="248"/>
            <mx:CheckBox id="showOpenIdication" selected="true" label="Show opening indication" left="10" right="10" bottom="122"/>
            
            <mx:HSlider value="200" tickInterval="100" snapInterval="100" maximum="1000" allowTrackClick="true" minimum="100" id="DelayClose" bottom="200" width="190" left="255"/>
            <mx:Label text="Folder auto close delay ms:{DelayClose.value}" left="10" bottom="200" textAlign="left" width="248"/>
            <mx:CheckBox id="autoCloseOpenNodes" selected="true" label="Auto open/close folders on drag over/out" left="10" right="10" bottom="148"/>
            <mx:CheckBox id="autoCloseOnExit" selected="true" label="Auto close folders on tree exit" left="10" right="10" bottom="70"/>
        </mx:Canvas>
    </mx:HBox>
</mx:VBox>
</mx:Application>