// /* dnd v0.1 2007 08 20 1030 asf*/
// /* dnd v0.9 2007 08 26 2300 asf*/

document.onmousemove = mouseMove ;
document.onmouseup   = mouseUp ;
document.onkeydown   = keyDown ;

var g_mouseOffset    = '' ;
    g_mouseOffset.x = 0 ;
    g_mouseOffset.y = 0 ;
var g_dragObject     = null ;
var g_dragClone      = null ;
var g_oldClass       = null ;   // orignal class of highlighted droptarget
var g_curDropTarget  = null ;   // object the mouse is currently hovering over, if droppable
var g_dropTargets    = new Array() ;    // all elements on the page that are drag targets
var g_startX         = null ;
var g_startY         = null ;

var opa=0 ; var timero;
var fade_target = "" ;
function doFade( f_target_id, f_src )
{
    opa = 0 ;
    fade_target = document.getElementById( f_target_id ) ;
    fade_target.src = f_src ;
/*    if ( fade_target.style.filter ) // will trip if we set it below! // NONE of these are tripping
        alert( 'hi') ;
    if ( fade_target.filter )
        alert( 'hi2') ;
    if ( fade_target.filters ) // triggered on phil IE
        alert( 'hi3') ;
    if ( fade_target.style.filters )
        alert( 'hi4') ;*/
    fade_target.style.filter="alpha(opacity='0')";
    fade_target.style.MozOpacity = 0.0 ;

    timero = setTimeout( 'doFade2()', 50 ) ;
}

function doFade2()
{ // ie hasLayout property
    opa += 5 ;
//    if ( fade_target.style.filter )
        fade_target.style.filter='alpha(opacity='+opa+')';      
    //if ( target.style.MozOpacity )
        fade_target.style.MozOpacity = opa / 100 ;     //NS6
   if ( opa >= 100 )
        clearTimeout( timero ) ;
   else // is this needed? // yes unless we switch to interval
        setTimeout( 'doFade2()', 50 ) ;
}
function keyDown( f_event )
{
    f_event = f_event || window.event ;
    // safari 2 / mac is 27-27; ff2 / wXP is 27-0
//    alert( f_event.keyCode + '-' + f_event.charCode );
    if ( f_event.keyCode == 27 )
    {
        doDropNoTarget( f_event ) ;
        undoHighlight( g_curDropTarget ) ; // we might have a valid drop target, so we have to reset it ourselvs
        g_curDropTarget = null ;
    }
}

function mouseUp( f_event )
{
    f_event = f_event || window.event ;

    if ( g_curDropTarget ) // dropped on valid target
        doDropOnTarget() ;
    else // dropped, not onto a valid target
        doDropNoTarget( f_event ) ;
}

// DOCUMENT BODY:   REMOVE the ORIGNIAL drag node; make the CLONE a DROP TARGET and DRAGGABLE     (so the dragged obj appears to return to its start position)
// DROPTARGET LIST: REMOVE the ORIGINAL drag node, ADD the CLONE node
function doDropNoTarget( f_event )
{
    if ( ! g_dragObject )
           return ;
    var pos = mouseCoords( f_event ) ;// if the mouse hasn't moved, lots of mousemove fcn stuff is needed or we delete the cklciked item
    if ( ( pos.x == g_startX ) && ( g_startY == pos.y )) 
        document.getElementById('cont').removeChild( g_dragClone ) ;
    else
    {
        document.getElementById('cont').removeChild( g_dragObject ) ;
        removeFromDropTargetList( g_dragObject ) ;
        g_dropTargets.push( g_dragClone ) ;
        makeDraggable( g_dragClone ) ;
        makeDropTarget( g_dragClone ) ;
    }

    g_dragClone = null ;
    g_dragObject = null ;
}

// DOCUMENT BODY: REMOVE the ORIGINAL drag node, APPEND the CLONED drag object before the drag target.
// DROPTARGET LIST: REMOVE the ORIGINAL drag node, APPEND the ORIGINAL node, REMOVE the CLONE node
//  
// remove the cloned drag node and append it before the target
function doDropOnTarget()
{
    // append the current node before the droptarget
    if ( g_curDropTarget == null )
        alert( 'doDrop() - Error: No drag target' ) ;

    // remove the original node and the clone node
    var theDragObject = document.getElementById('cont').removeChild( g_dragObject ) ;
    document.getElementById('cont').removeChild( g_dragClone ) ;

    // fix the original node's position
    g_dragObject.style.position = 'relative' ;
    g_dragObject.style.top      = 0 ;
    g_dragObject.style.left     = 0 ;
    g_dragObject.style.zIndex   = 'auto' ; // attempt to fix the slide-under bug (does not work unless pos=absolute?)

    // if not dropped in the trash, insert the original node in front of the drop target.  Otherwise, remove it from the DT list
    if ( g_curDropTarget.id == "trash" )
        removeFromDropTargetList( theDragObject ) ;
    else
        document.getElementById('cont').insertBefore( theDragObject, g_curDropTarget ) ;

    // clear the drop target's highlight and reset targeting
    undoHighlight( g_curDropTarget ) ;
    g_curDropTarget = null ;

    // since nodes have moved, recalculate drag target positions
    recalcDropTargets() ;

    g_dragClone = null ;
    g_dragObject = null ;
}

function recalcDropTargets()
{
    for ( var i = 0 ; i < g_dropTargets.length ; i ++ )
        calcDropTargetPosition( g_dropTargets[ i ] ) ;
}

function calcDropTargetPosition( f_item )
{
    pos = getPosition( f_item ) ;

    f_item.setAttribute( 'startLeft',   pos.x ) ;
    f_item.setAttribute( 'startTop',    pos.y ) ;
    f_item.setAttribute( 'startWidth',  parseInt( f_item.offsetWidth ) ) ;
    f_item.setAttribute( 'startHeight', parseInt( f_item.offsetHeight ) ) ;
}

function isInDropTarget( f_x, f_y, f_item )
{
    var left = f_item.getAttribute( 'startLeft' ) ;
    var right = parseInt( f_item.getAttribute( 'startLeft' ) ) + parseInt( f_item.offsetWidth ) ;
    var top = f_item.getAttribute( 'startTop' ) ;
    var bottom = parseInt( f_item.getAttribute( 'startTop' ) ) + parseInt( f_item.offsetHeight ) ; 

    if ( ( f_x > left ) && ( f_x < right ) && ( f_y < bottom ) && ( f_y > top ) )
        return true ;

    return false ;
}

function handleDropTargets( g_x, g_y )
{
    // cases: none, no old.  none, had old.  same.  new, no old.  new, had old.
    var found = false ;  // needed for the case of 'no target found, had a previous one'

    if ( ! g_dropTargets )
        return ;

    for ( var i = 0 ; i < g_dropTargets.length ; i ++ )
    {
        if ( isInDropTarget( g_x, g_y, g_dropTargets[ i ] ) )
        {
            if ( g_dragObject == g_dropTargets[ i ] ) // ignore the object being dragged
                continue ;

            found = true ;

            if ( g_curDropTarget == g_dropTargets[ i ] ) // if this is already our drop target, do nothing and we're done
                break ;

            if ( g_curDropTarget ) // if we had another target before this, unmark it
                undoHighlight( g_curDropTarget ) ;

            // mark and set our new target, and we're done
            g_curDropTarget = g_dropTargets[ i ] ;
            doHighlight( g_curDropTarget ) ;
            break ;
        }
        else // nope, this is not our target
        {
            if ( g_curDropTarget == g_dropTargets[ i ] ) // it used to be the target, so unmark it
                undoHighlight( g_curDropTarget ) ;
        }
    }

    if ( ( ! found ) && ( g_curDropTarget ) ) // nothing found but had one previously
    {
        undoHighlight( g_curDropTarget ) ;
        g_curDropTarget = null ;
    }
}

function doHighlight( f_item )
{
    g_oldClass = f_item.className ;
    f_item.className = 'drop_hl ' + g_oldClass ;
}

function undoHighlight( f_item )
{
    if ( f_item )
        f_item.className = g_oldClass ;
}

function mouseMove( f_event )
{
    f_event       = f_event || window.event ;
    var mousePos  = mouseCoords( f_event ) ;

    window.status = 'x: ' + mousePos.x + ' y: ' + mousePos.y ;

    if ( g_dragObject )
    {
        g_dragObject.style.position = 'absolute' ;
        g_dragObject.style.top      = mousePos.y - g_mouseOffset.y ;
        g_dragObject.style.left     = mousePos.x - g_mouseOffset.x ;

        if ( g_dragClone )
            g_dragClone.style.display = 'block' ; // unhide the clone once no longer next to it (prevents seeing 2 of us next to each other)

        handleDropTargets( mousePos.x, mousePos.y ) ;

        return false ;
    }
}

function mouseCoords( f_event )
{
    if ( f_event.pageX || f_event.pageY )
        return { x:f_event.pageX, y:f_event.pageY } ;
    else
    {
        var root = document.documentElement || document.body;
        return { x:f_event.clientX + root.scrollLeft - document.documentElement.clientLeft,
                 y:f_event.clientY + root.scrollTop  - document.documentElement.clientTop   } ;
    }
}

function getMouseOffset( f_target, f_event )
{
    f_event = f_event || window.event ;

    var docPos    = getPosition( f_target ) ;
    var mousePos  = mouseCoords( f_event ) ;

    return { x:mousePos.x - docPos.x, y:mousePos.y - docPos.y } ;
}

function getPosition( f_event )
{
    var left = 0 ;
    var top  = 0 ;

    while ( f_event.offsetParent )
    {
        left    += f_event.offsetLeft ;
        top     += f_event.offsetTop ;
        f_event  = f_event.offsetParent ;
    }

    left += f_event.offsetLeft ;
    top  += f_event.offsetTop ;

    window.status = 'gpos: x: ' + parseInt( left ) + ' y: ' + parseInt( top ) ;
    return { x:left, y:top } ;
}

function removeFromDropTargetList( f_item )
{
    var newList = new Array() ;
    for ( var i = 0 ; i < g_dropTargets.length ; i ++ )
        if ( g_dropTargets[ i ] != f_item )
            newList.push( g_dropTargets[ i ] ) ;

//     g_dropTargets.empty() //todo
     g_dropTargets = newList ;
}

function makeClickable( f_object )
{
    f_object.onmousedown =  function()
                            {
                                g_dragObject = this ;
                            }
}

function makeDraggable( f_item )
{
    if ( ! f_item ) 
        return ;

    f_item.onmousedown = function( f_event )
                         {
                            f_event = f_event || window.event ;
                            g_click = true ;
                            g_dragObject  = this ;
                            var pos = mouseCoords( f_event ) ;
                            g_startX = pos.x ;
                            g_startY = pos.y ;
                            g_mouseOffset = getMouseOffset( this, f_event ) ;
                            makeShadowClone( f_item ) ;  // reset ALL sizes - clienthieght, oiffsets etc
                            return false ;
                         }
}

function makeDropTarget( f_item )
{
    calcDropTargetPosition( f_item ) ;
    g_dropTargets.push( f_item ) ;
}

function makeShadowClone( f_item )
{
    if ( g_dragClone )
        alert( 'makeShadowClone() error: clone already exists' ) ;
    g_dragClone = f_item.cloneNode( true ) ;
    g_dragClone.style.display = 'none' ;
    document.getElementById('cont').insertBefore( g_dragClone, f_item ) ;
}

function makeDraggableByTagAndClass( f_tag, f_class )
{
    var tags = document.getElementsByTagName( f_tag ) ;

    for ( var i = 0 ; i < tags.length ; i ++ )
        if ( tags[ i ].className == f_class )
            makeDraggable( tags[ i ] ) ;
}

function makeDropTargetByTagAndClass( f_tag, f_class )
{
    var tags = document.getElementsByTagName( f_tag ) ;

    for ( var i = 0 ; i < tags.length ; i ++ )
        if ( tags[ i ].className == f_class )
            makeDropTarget( tags[ i ] ) ;
}


function getOrderList()
{
    var order = new Array() ;
    tag = document.getElementsByName('order') ;
    for ( var i = 0 ; i < tag.length ; i ++ )
        order.push( tag[ i ].id ) ;

    var str = "" ;
    for ( i = 0 ; i < order.length ; i ++ )
        str += order[ i ] + "," ;

    var reo =  document.getElementById('reorder') // on form
    reo.innerHTML = str ; 
}

