var dragObject = null;
var mouseOffset = null;

function mouseCoords(ev){
    var tmp = new Object();

    if(ev.pageX || ev.pageY){
        return {x:ev.pageX, y:ev.pageY};
    }else{
        return {x:(ev.clientX + document.body.scrollLeft - document.body.clientLeft),
        y:(ev.clientY + document.body.scrollTop - document.body.clientTop)};
    }
}

function getMouseOffset(target, ev){
    ev = ev || window.event;

    var docPos = getPosition(target);
    var mousePos = mouseCoords(ev);
    return {x:mousePos.x - docPos.x, y:mousePos.y - docPos.y};
}

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

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

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

    return {x:left, y:top};
}

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

    if(dragObject){
        var y = mousePos.y - mouseOffset.y;
        var x = mousePos.x - mouseOffset.x;

        if(!dragObject.noConstrain){
            if(y < dragObject.offset.y){
                y = dragObject.offset.y;
            }
            if(x < dragObject.offset.x){
                x = dragObject.offset.x;
            }
            if(y + dragObject.offsetHeight + dragObject.offset.y >= winView.height){
                y = winView.height - dragObject.offsetHeight - dragObject.offset.y;
            }
            if(x + dragObject.offsetWidth + dragObject.offset.x >= winView.width){
                x = winView.width - dragObject.offsetWidth - dragObject.offset.x;
            }
        }

        dragObject.style.position = 'absolute';
        dragObject.style.top = y + 'px';
        dragObject.style.left = x + 'px';

        if(typeof(dragObject.moveFunction) == 'function'){
            dragObject.moveFunction();
        }

        return false;
    }
}

function mouseUp(){
    if(!dragObject){
        return false;
    }

    if(typeof(dragObject.endFunction) == 'function'){
        dragObject.endFunction();
    }

    dragObject = null;
}

function makeDraggable(item, target, offset, onmousedown, onmousemove, onmouseup, noConstrain, staticMouseOffset){
    if(!item){
        return;
    }

    item.style.cursor = 'move';

    item.onmousedown = function(ev){
        if(!ev){
            var ev = window.event;
        }
        if(!target){
            dragObject = this;
        }else{
            dragObject = target;
        }

        if(offset){
            dragObject.offset = offset;
        }else{
            dragObject.offset = {x:0, y:0};
        }

        mouseOffset = staticMouseOffset || getMouseOffset(dragObject, ev);
        if(noConstrain){
            dragObject.noConstrain = true;
        }
        if(typeof(onmousedown) == 'function'){
            onmousedown(item, ev);
        }
        if(typeof(onmousemove) == 'function'){
            dragObject.moveFunction = onmousemove;
        }
        if(typeof(onmouseup) == 'function'){
            dragObject.endFunction = onmouseup;
        }
        return false;
    }
}
