
function DivDragger_unlock ( name ) {
    g_divDraggerParents[name].inputIsLocked = false ;  
}

function DivDragger_move ( name ) {
    obj = g_divDraggerParents[name] ; 
    var temp = $(obj.parentID).removeChild( $(obj.dragChildID) ) ; 
    if ( obj.dragTargetAtBottom ) {
        $(obj.parentID).appendChild(temp);
    }
    else {
        $(obj.parentID).insertBefore(temp,$(obj.dragTargetID));
    }
    obj.dragging = false ; 
    obj.dragChildID = null ; 
    obj.dragTargetID = null ; 
    obj.markDiv      = null ; 
    obj.dragTargetAtBottom = false ; 
}

function DivDragger_ajaxResponseFunction ( ok ) {
    eval(ok.responseText); 
}

function DivDragger_ajaxErrorFunction ( nee ) {
    g_divDraggerParents[ok.responseText].inputIsLocked = false ; 
}

function DivDragger_getChildDIVCount ( e ) {
    var child = e.firstChild ; 
    var count = 0 ; 

    while ( child ) {
        if ( child.nodeName == 'DIV' ) {
            count = count + 1 ; 
        }
        child = child.nextSibling ; 
    }

    return count ; 
}

function DivDragger_checkForParentDOMObject ( current, potentialParent ) {
    if ( ! current.parentNode ) 
        return false ; 
    if ( current.parentNode == potentialParent ) 
        return true ; 
    return DivDragger_checkForParentDOMObject ( current.parentNode, potentialParent ) ; 
}

function DivDragger_draggerIsParent ( dragger, thisDragger ) {
    return DivDragger_checkForParentDOMObject( $(thisDragger.getParentID()), $(dragger.getParentID()) );
}

g_divDraggerParents = new Object() ;  

DivDraggerParent = Class.create() ; 

DivDraggerParent.prototype = 
{
	initialize : function( parentID, markerClass, draggerClass, order, ajaxURL )
    // Set ajaxURL to null if you dont need an ajax backend ! 
	{
		g_mouseDevice.registerListener( this );
        this.parentID      = parentID     ; // ID of parent element. All DIV-childs of this element are dragable. 
        this.dragging      = false        ; // Are we currently dragging ?  
        this.floatVisible  = false        ; // Is floating DIV already visible ? 
        this.dragChildID   = null         ; // ID of the DIV-child that is dragged around.   
        this.dragDivID     = null         ; // ID of the floating DIV that is visualizing the drag.   
        this.dragTargetID  = null         ; // ID of the DIV-child next to the mouse pointer while draggin(target position). 
        this.markDiv       = null         ; // Reference to the marker DIV that is added to the parent element. 
        this.mouseX        = 0            ; // Previous mouse position (X). 
        this.mouseY        = 0            ; // Previous mouse position (Y). 
        this.markerClass   = markerClass  ; // CSS class of the marker DIV. 
        this.draggerClass  = draggerClass ; // CSS class of the dragger DIV. 
        this.order         = order        ; // 'horizontal' or 'vertical'. In which way the items are ordered. 
        this.ajaxURL       = ajaxURL      ; // URL of ajax backend script. 
        this.dragTargetAtBottom = false ;   // Special case : drag target position is at very end of DIV-child sequence. 
        this.inputIsLocked      = false ;   // While waiting for an ajax response the input to this element is locked. 
        this.treeChilds = new Array()   ; 
        this.treeParent = null          ;  

        $(parentID).setAttribute('DivDragger',parentID);

        g_divDraggerParents[this.parentID] = this ; 
	},

    getParentID : function () 
    {
        return this.parentID ; 
    },
	
	onMouseDown : function(e)
	{
 
        // martin put this here. ole: schau dir den code hier mal an, was soll das?
        if ( ! this.parentID ) 
            return false ; 

        divs = $(this.parentID).getElementsByTagName("DIV");
        for ( i = 0 ; i < divs.length ; i++ ) {
            if ( divs[i].getAttribute("DivDragger") ) {

                g_divDraggerParents[ divs[i].getAttribute("DivDragger") ].onMouseDown(e); 
                if ( e.divDraggerWasHere ) 
                    return false ; 
            }
        
        }

        if ( this.inputIsLocked ) 
            return false ; 

        var toDelete = $( this.dragDivID ) ;  
        if ( toDelete ) {
            document.getElementsByTagName('BODY')[0].removeChild( toDelete );
        }

        var parentNode = $(this.parentID) ; // Get reference to parent node. 
        if ( ! parentNode ) 
            return false ; 

        childCount = DivDragger_getChildDIVCount(parentNode) ; 

        if ( childCount <= 1 ) 
            return false ; 

        var child = parentNode.firstChild ; 

        while ( child ) {
            if ( child.nodeName == 'DIV' ) {
                if( g_pointWithinElement( g_mouseDevice.getMousePosX(), g_mouseDevice.getMousePosY(), child ) ) {
//                    $('debug_'+this.parentID).innerHTML = 'dragging child' + child.id ; 
                    this.dragging = true ; 
                    this.dragChildID = child.id ; 
                    this.dragDivID = this.parentID + '___dragDiv' ; 
                    
                    var dragDiv = document.createElement("DIV");
                    dragDiv.id = this.dragDivID ; 
                    dragDiv.style.top=(g_getTop(child)-1)+'px';;
                    dragDiv.style.left=(g_getLeft(child)-1)+'px';;
                    dragDiv.style.position='absolute';
                    dragDiv.style.width=(child.offsetWidth)+'px';
                    dragDiv.style.height=(child.offsetHeight)+'px';
                    dragDiv.style.visibility = 'hidden' ;                     
                    dragDiv.style.zIndex=0;
                    dragDiv.className = this.draggerClass ; 
                    document.getElementsByTagName('BODY')[0].appendChild(dragDiv);

                    this.mouseX = g_mouseDevice.getMousePosX() ; 
                    this.mouseY = g_mouseDevice.getMousePosY() ; 

                    e.divDraggerWasHere = true ; 
                    break ; 
                }
            }
            child = child.nextSibling ; 
        }

        return false; // This must be false. Otherwise the signal is not brought to the underlying HTML element (i.e. textedit field) 
	},
	
	onMouseMove : function(e)
	{
        if ( this.inputIsLocked ) 
            return false ; 

        if ( this.dragging ) {
            mX = g_mouseDevice.getMousePosX() ; 
            mY = g_mouseDevice.getMousePosY() ; 

            difX = mX - this.mouseX ; 
            difY = mY - this.mouseY ; 

            var floatDiv = $( this.dragDivID ) ; 

            if ( ! this.floatVisible ) {
                if ( ( abs(difX) < 10 ) && ( abs(difY) < 10 ) ) 
                    return false ; 
            }

            if ( floatDiv ) {
                this.floatVisible = true ; 
                floatDiv.style.visibility = 'visible' ; 
                floatDiv.style.top  = g_getTop ( floatDiv ) + difY + "px" ;
                floatDiv.style.left = g_getLeft( floatDiv ) + difX + "px" ;                
            }

            this.mouseX = mX ; 
            this.mouseY = mY ; 

            var parentNode = $(this.parentID) ; 

            if ( ! parentNode ) 
                return false ; 

            var child = parentNode.firstChild ; 

            while ( child ) {
                if ( child.nodeName == 'DIV' ) {

                    if ( child.id == 'dragMarkDiv' ) {
                        child = child.nextSibling ; 
                        continue ; 
                    }
                        
                    if( g_pointWithinElement( g_mouseDevice.getMousePosX(), g_mouseDevice.getMousePosY(), child ) ) {

                        var oldMarkerRemoved  = false ; 
                        var targetIsLastChild = false ; 
                        
                        if ( this.dragTargetID != child.id ) {
                            if ( this.markDiv ) {
                                parentNode.removeChild(this.markDiv) ; 
                                this.markDiv = null ; 
                                oldMarkerRemoved = true ; 
                            }
                        }
                        else {
                            if ( child != getLastDIVChild(parentNode) ) {
                                // Break the loop. New target is old target. Nothing to be done... 
                                // In case of child == parentNode.lastChild the marker could change position. 
                                break ; 
                            } 
                            targetIsLastChild = true ; 
                        }

                        var oldMarkDiv = this.markDiv ; // For special case... 
                        var oldDragTargetAtBottom = this.dragTargetAtBottom ; // For special case...

                        this.dragTargetAtBottom = false ; 

                        if ( targetIsLastChild ) {
                            if ( this.order == 'vertical' ) {
                                if ( ( g_mouseDevice.getMousePosY() > ( g_getTop(child) + child.offsetHeight/2) ) ) {
                                    this.dragTargetAtBottom = true ; 
                                }
                            }
                            else {
                                if ( ( g_mouseDevice.getMousePosX() > ( g_getLeft(child) + child.offsetWidth/2) ) ) {
                                    this.dragTargetAtBottom = true ; 
                                }
                            }
                            if (  this.dragTargetAtBottom == oldDragTargetAtBottom ) {
                                break ; // Break the loop, nothing to be done here. 
                            }
                        }

                        if ( ( ! oldMarkerRemoved ) && oldMarkDiv ) {
                            parentNode.removeChild( oldMarkDiv );
                        }

                        this.dragTargetID = child.id ; 
                        
                        this.markDiv = document.createElement("DIV");
                        this.markDiv.id = 'dragMarkDiv' ; 
                        this.markDiv.className = this.markerClass ; 

                        if ( this.dragTargetAtBottom ) {
                            parentNode.appendChild(this.markDiv);
                        }
                        else {
                            parentNode.insertBefore(this.markDiv,child);
                        }
                        
                        break ; 
                    }
                }

                child = child.nextSibling ; 

            }
            e.divDraggerWasHere = true ; 
        }
		return false; // This must be false. Otherwise the signal is not brought to the underlying HTML element (i.e. textedit field) 
	},
	
	onMouseUp : function(e)
	{

        ajaxParams = null ; 

        if ( this.inputIsLocked ) 
            return false ; 

        el = $( this.dragDivID ) ; 
        if ( el ) {
            document.getElementsByTagName('BODY')[0].removeChild( el );
        }
        if ( this.dragging) {
            if ( this.dragTargetID ) {
                if ( this.dragTargetID != this.dragChildID ) {

                    this.floatVisible = false ;                     
                    parentNode = $(this.parentID) ; 

                    if ( this.ajaxURL != null ) { // Do the ajax request 
                        if ( this.dragTargetAtBottom ) {
                            ajaxParams = 'ajax_moveMappenDiv=1&draggerObjectName='+this.parentID+'&moveItem='+$(this.dragChildID).getAttribute('key_id')+'&afterItem='+$(this.dragTargetID).getAttribute('key_id'); 
                        }
                        else {
                            ajaxParams = 'ajax_moveMappenDiv=1&draggerObjectName='+this.parentID+'&moveItem='+$(this.dragChildID).getAttribute('key_id')+'&beforeItem='+$(this.dragTargetID).getAttribute('key_id') ; 
                        }

                        new Ajax.Request( this.ajaxURL, 
                        {
                            parameters:ajaxParams, 
                            onSuccess:DivDragger_ajaxResponseFunction,
                            onFailure:DivDragger_ajaxErrorFunction
                          }
                        );
                    
                        this.inputIsLocked = true ; 
                    }
                    else { // Dont do an ajax request but do the job right now 
                        var temp = $(this.parentID).removeChild( $(this.dragChildID) ) ; 
                        if ( this.dragTargetAtBottom ) {
                            $(this.parentID).appendChild(temp);
                        }
                        else {
                            $(this.parentID).insertBefore(temp,$(this.dragTargetID));
                        }
                    }

                }
            }

            if ( this.markDiv ) {
              $(this.parentID).removeChild(this.markDiv) ; 
              this.markDiv = null ; 
            }

            if ( ajaxParams == null ) { // We're not waiting for ajax response so clean up now 
                this.dragging = false ; 
                this.dragChildID = null ; 
                this.dragTargetID = null ; 
                this.markDiv      = null ; 
                this.dragTargetAtBottom = false ; 
            }

            e.divDraggerWasHere = true ; 
        }
		return false; // This must be false. Otherwise the signal is not brought to the underlying HTML element (i.e. textedit field) 
	}
	
};


