﻿var Widgets = new Array();
var WidgetsSpaces = new Array();

function GetMouseOffset(target, ev)
{
    ev = ev || window.event;

    var docPos    = GetPosition(target);
    var mousePos  = GetMouseCoords(ev);
    return {x:mousePos.x - docPos.x, y:mousePos.y - docPos.y};
}

function GetPosition(e)
{
    var left = 0;
    var top  = 0;

    if (!e.offsetParent)
        left = 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 GetMouseCoords(ev)
{
    if (ev.pageX || ev.pageY) return {x:ev.pageX, y:ev.pageY};
    return {
        x:ev.clientX + document.body.scrollLeft - document.body.clientLeft,
        y:ev.clientY + document.body.scrollTop  - document.body.clientTop
    };
}



var WidgetsSpace = function(id, zoneID)
{
    this.ID = id;
    this.zoneID = zoneID;
    this.widgets = new Array();
    this.widgetsMinY = new Array();
    this.minX = 0;
    this.maxX = 0;
    this.GetIndexByY = function(y)
    {
        var ret = 0;
        while (ret < this.widgetsMinY.length && y > this.widgetsMinY[ret]) ret++;
        return ret;
    }
    this.UpdateSpaceBoundaries = function()
    {
        this.widgetsMinY.length = 0;
        for (var i=0; i<this.widgets.length; i++) this.widgetsMinY[i] = GetPosition(this.widgets[i].GetContainer()).y;
        var zo = $(this.zoneID);
        var ll = GetPosition(zo);
        this.minX = ll.x;
        this.maxX = ll.x + zo.offsetWidth;
    }
    this.RemoveWidget = function(widget)
    {
        for (var i=0; i<this.widgets.length; i++)
        {
            if (this.widgets[i] == widget)
            {
                this.widgets.remove(i);
                this.widgetsMinY.remove(i);
                this.UpdateSpaceBoundaries();
                return;
            }
        }
    }
    this.AddExistingWidget = function(widget,mouse)
    {
        var index = this.GetIndexByY(mouse.y);
        widget.index = index;
        if (index < this.widgets.length)
        {
            var old_c = this.widgets[index].GetContainer();
            var new_c = widget.GetContainer();
            this.widgets.insert(widget, index);
            new_c.parentNode.removeChild(new_c);
            old_c.parentNode.insertBefore(new_c, old_c);
        }
        else
        {
            var new_c = widget.GetContainer();
            this.widgets.insert(widget, index);
            new_c.parentNode.removeChild(new_c);
            $(zoneID).appendChild(new_c);
        }
        widget.widgetZone = this;
        this.UpdateSpaceBoundaries();
    }
    this.AddNewWidget = function(widget)
    {
        widget.widgetZone = this;
        this.widgets.push(widget);
        widget.index = this.widgets.length-1;
    }
    WidgetsSpaces.push(this);
}



var Widget = function(id, idContainer, idBox, idBtnControle, widgetID, minimizeButtonID, minimized)
{
    this.GetBox = function()
    {
        return $(this.idBox);
    }
    this.GetContainer = function()
    {
        return $(this.idContainer);
    }
    this.GetMinimizeButton = function()
    {
        return this.minimizeButton;
    }
    this.GetBtnControle = function()
    {
        return $(this.idBtnControle);
    }
    Widgets.push(this);
    this.id = id;
    this.idContainer = idContainer;
    this.idBox = idBox;
    this.idBtnControle = idBtnControle;
    this.widgetID = widgetID;
    this.paddingTop = 3;
    this.paddingLeft = 3;
    this.widgetZone = null;
    this.index = 0;
    this.minimized = minimized;
    this.minimizeButton = $(minimizeButtonID);
    var container;
    var box;
    var btnControle;
    (container = this.GetContainer()).widget = this;
    (box = this.GetBox()).widget = this;
    (btnControle = this.GetBtnControle()).widget = this;
    this.minimizeButton.widget = this;
    this.minimizeButton.onclick = function(){Widget.Minimize(this.widget);return false;};
    btnControle.onmousedown = Widget.onMouseDown;
    btnControle.onclick = function(){return false; }
}
Widget.onMouseDown = function(ev)
{
    ev = ev || window.event;
    var box = this.widget.GetBox();
    var container = this.widget.GetContainer();
    AddClassName(box.id,'box_transp');
    AddClassName(container.id, 'box_container_dragging');
    Widget.dragObject  = box;
    Widget.mouseOffset = GetMouseOffset(box, ev);
    Widget.onMouseMove(ev);
    return false;
}
Widget.RaiseMM = true;
Widget.onMouseMove = function(ev)
{
    if (!Widget.RaiseMM) return;
    ev = ev || window.event;
    var mousePos = GetMouseCoords(ev);
    if (Widget.dragObject)
    {
        Widget.dragObject.style.position = 'absolute';
        Widget.dragObject.style.top      = (mousePos.y - Widget.mouseOffset.y) + 'px';
        Widget.dragObject.style.left     = (mousePos.x - Widget.mouseOffset.x) + 'px';
        Widget.lastMousePos = mousePos;
        if (!Widget.AMP)
        {
            Widget.AMP = setInterval('Widget.AnalyzeMousePosition();',100);
        }
        return false;
    }
}
Widget.AMP = null;
Widget.onMouseUp = function(ev)
{
    if (Widget.dragObject && Widget.dragObject.widget)
    {
        Widget.droppingObject = Widget.dragObject;
        Widget.droppingOriginalPosition = null;
        Widget.droppingAction = setInterval('Widget.DropBox();',20);
    }
    Widget.dragObject = null;
}
Widget.AnalyzeMousePosition = function()
{
    if (Widget.dragObject && Widget.dragObject.widget)
    {
        var w = Widget.dragObject.widget;
        var m = Widget.lastMousePos;
        var z = w.widgetZone;
        
        for (var i=0; i<WidgetsSpaces.length; i++)
        {
            if (m.x >= WidgetsSpaces[i].minX && m.x <= WidgetsSpaces[i].maxX)
            {
                if (WidgetsSpaces[i] == w.widgetZone)
                {
                    z.RemoveWidget(w);
                    WidgetsSpaces[i].AddExistingWidget(w,m);
                }
                else
                {
                    WidgetsSpaces[i].AddExistingWidget(w,m);
                    z.RemoveWidget(w);
                }
                break;
            }
        }
        clearInterval(Widget.AMP);
        Widget.AMP = null;
    }
}
Widget.DropBox = function()
{
    if (!Widget.droppingObject) return;
    
    var box = Widget.droppingObject;
    var w = box.widget;
    var container = w.GetContainer();
    var pb = {x:parseInt(box.style.left), y:parseInt(box.style.top)};
    var pc = GetPosition(container);
    var dx = pb.x - pc.x;
    var dy = pb.y - pc.y;
    if (!Widget.droppingOriginalPosition) Widget.droppingOriginalPosition = pb;
    var po = Widget.droppingOriginalPosition;
    
    if (Math.abs(dx * 0.16) < w.paddingLeft && Math.abs(dy * 0.16) < w.paddingTop)
    {
        box.style.position = '';
        box.style.top = '';
        box.style.left = '';
        Widget.droppingObject = null;
        RemoveClassName(box.id,'box_transp');
        RemoveClassName(container.id,'box_container_dragging');
        clearInterval(Widget.droppingAction);
        Widget.UpdatePositionInfo();
    }
    else
    {
        if (Math.abs(dx * 0.16) > 1)
        {
            dx -= (dx * 0.16);
            box.style.left = (pc.x + dx) + 'px';
        }
        if (Math.abs(dy * 0.16) > 1)
        {
            dy -= (dy * 0.16);
            box.style.top = (pc.y + dy) + 'px';
        }
    }
}
Widget.UpdateAllSpaces = function()
{
    for (var i=0; i<WidgetsSpaces.length; i++) WidgetsSpaces[i].UpdateSpaceBoundaries();
}

Widget.UpdatePositionInfo = function()
{
    if (Widget.PersistsPositionInfoCTRL) clearTimeout(Widget.PersistsPositionInfoCTRL);
    Widget.PersistsPositionInfoCTRL = setTimeout('Widget.PersistsPositionInfo();',Widget.PersistenceTimeout);
}
Widget.Minimize = function(w)
{
    var container = w.GetContainer();
    var bt_min = w.GetMinimizeButton();
    if (w.minimized)
    {
        AddClassName(container.id, 'box_container');
        RemoveClassName(container.id, 'box_container_minimizado');
        w.minimized = false;
        //alert(bt_min.id);
        if (bt_min) AddClassName(bt_min.id, 'bt_up');
        if (bt_min) RemoveClassName(bt_min.id, 'bt_down');
    }
    else
    {
        AddClassName(container.id, 'box_container_minimizado');
        RemoveClassName(container.id, 'box_container');
        w.minimized = true;
        //alert(bt_min.id);
        if (bt_min) AddClassName(bt_min.id, 'bt_down');
        if (bt_min) RemoveClassName(bt_min.id, 'bt_up');
    }
    Widget.UpdatePositionInfo();
}


Widget.PersistPositionUpdateCTRL = null;
Widget.PersistenceTimeout = 3000;
Widget.PersistsPositionInfo = function()
{
    if (Widget.PersistsPositionInfoCTRL) clearTimeout(Widget.PersistsPositionInfoCTRL);
    if (Widget.onPositionUpdate)
    {
        var objInfo = {};
        objInfo.Zones = [];
        for (var i=0; i<WidgetsSpaces.length; i++)
        {
            var zone = [];
            for (var j=0; j<WidgetsSpaces[i].widgets.length; j++)
            {
                var winfo = {};
                winfo.WidgetID = WidgetsSpaces[i].widgets[j].widgetID;
                winfo.Minimized = WidgetsSpaces[i].widgets[j].minimized;
                zone.push(winfo);
            }
            objInfo.Zones.push(zone);
        }
        Widget.onPositionUpdate(objInfo);
    }
}
window.onresize2 = window.onresize;
window.onresize = function()
{
    if (window.onresize2) window.onresize2();
    Widget.UpdateAllSpaces();
}


document.onmousemove = Widget.onMouseMove;
document.onmouseup   = Widget.onMouseUp;
Widget.dragObject = null;
Widget.mouseOffset = null;
Widget.onPositionUpdate = null;