var draggingOver;
var draggingOverId;
var draggingOverTimer = null;

function clearDraggingOver()
{
    if ( draggingOverTimer )
    {
        clearInterval( draggingOverTimer );
        draggingOverTimer = null
    }

    if ( draggingOver.parentNode )
    {
         draggingOver.parentNode.className = draggingOver.parentNode.className.replace( ' draggingoverchild', '' );
    }

    draggingOver.className = draggingOver.className.replace( ' draggingover', '' );

    draggingOver = null
    dragginOverId = null

    return;
}

//
// Some of the below code is too specific for the item tree.
// This should be made more generic if dragging is used elsewhere.
//
function setDraggingOver( over )
{
    if ( over.parentNode )
    {
         over.parentNode.className = over.parentNode.className + ' draggingoverchild';
    }

    over.className = over.className + ' draggingover';

    draggingOver = over;
    draggingOverId = over.parentNode.id;

    node = document.getElementById( 'node' + over.parentNode.id.substr( 4 ) );
    if ( node.className.match( new RegExp( '(^|\\s)closed(\\s|$)' ) ) )
    {
        draggingOverTimer = setInterval( function()
                                         {
                                             var id = draggingOverId;
                                             clearDraggingOver();
                                             openitemtreenode( id );
                                         }, 500 );
     }
}

function makeDraggable( element )
{
    element.onmousedown = function( event )
    {
        document.onmousemove = function( event )
        {
            event = event || window.event;

            var x = event.clientX + 1;
            var y = event.clientY + 1;

            if ( element.className.match( new RegExp( '(^|\\s)dragparent(\\s|$)' ) ) )
            {
                element = element.parentNode;
            }

            element.style.visibility = 'hidden';
            var over = document.elementFromPoint( x, y );
            element.style.visibility = 'visible';

            if ( over
                && over !== draggingOver )
            {
                if ( draggingOver )
                {
                    clearDraggingOver();
                }

                if ( over.className.match( new RegExp( '(^|\\s)dragdestination(\\s|$)' ) ) )
                {
                    setDraggingOver( over );
                }
            }

            var scrollX = window.pageXoffset || ( document.documentElement && document.documentElement.scrollLeft ) || ( document.body && document.body.scrollLeft );
            var scrollY = window.pageYoffset || ( document.documentElement && document.documentElement.scrollTop ) || ( document.body && document.body.scrollTop );
            x = x + scrollX;
            y = y + scrollY;

            element.style.left = x + 'px';
            element.style.top = y + 'px';
        };

        document.onmouseup = function()
        {
            document.onmousemove = null;

            if ( element.className.match( new RegExp( '(^|\\s)dragparent(\\s|$)' ) ) )
            {
                element = element.parentNode;
            }

            if ( element.releaseCapture )
            {
                element.releaseCapture();
            }

            if ( draggingOver )
            {
                var over = draggingOver;

                clearDraggingOver();

                if ( over.className.match( new RegExp( '(^|\\s)beforechild(\\s|$)' ) ) )
                {
                    doSubmit( 'moveitembeforeitem' + element.id.substring( 4 ) + '_' + over.id.substring( 11 ) );
                    over.className = over.className.replace( ' draggingover', '' );
                    element.style.display = 'none';
                }
                else
                {
                    doSubmit( 'moveitemtoparent' + element.id.substring( 4 ) + '_' + over.parentNode.id.substring( 4 ) );
                    over.parentNode.className = over.parentNode.className.replace( ' draggingover', '' );
                    over.className = over.className.replace( ' draggingover', '' );
                    element.style.display = 'none';
                }
            }

            element.style.cursor = "";
            element.style.position = "static";
            element.style.left = 0;
            element.style.top = 0;
            element.style.width = "auto";

            document.onmouseup = null;
        }

        event = event || window.event;

        var scrollX = window.pageXoffset || ( document.documentElement && document.documentElement.scrollLeft ) || ( document.body && document.body.scrollLeft );
        var scrollY = window.pageYoffset || ( document.documentElement && document.documentElement.scrollTop ) || ( document.body && document.body.scrollTop );
        var x = event.clientX + scrollX + 1;
        var y = event.clientY + scrollY + 1;

        if ( element.className.match( new RegExp( '(^|\\s)dragparent(\\s|$)' ) ) )
        {
            draggingParent = true;
            element = element.parentNode;
        }

        element.style.width = element.clientWidth + 1 + 'px'
        element.style.left = x + 'px';
        element.style.top = y + 'px';
        element.style.position = "absolute";
        element.style.cursor = "default";

        if ( element.setCapture )
        {
            element.setCapture();
        }
    };

    element.unselectable = "on";
    element.onselectstart = function() { return false };
    element.style.userSelect = element.style.MozUserSelect = "none";
}

function setDraggables()
{
    var elements = document.getElementsByTagName( 'div' );

    for ( var i = 0, len = elements.length; i < len; i++ )
    {
        if ( elements[i].className.match( new RegExp( '(^|\\s)draggable(\\s|$)' ) ) )
        {
            makeDraggable( elements[i] );
        }
    }
}

