///<reference path="global.js" />
///<reference path="uielements.js" />

Scroll =
{
    Hort: function (movable, scroll, dx) {
        var mx = $G.Mouse.X;
        var delta = mx - Scroll.StartMX;
        var x = Scroll.StartX + delta;
        var abs = Scroll.BorderH / x;
        if (Scroll.MBorderH >= 0)
            Scroll.CurrentMovable = null;
        if (x > 0) {
            if (x < Scroll.BorderH) {
                scroll.style.marginLeft = x + "px";
                if (movable)
                    movable.style.marginLeft = Math.floor(Scroll.MBorderH / abs) + "px";
            }
            else {
                scroll.style.marginLeft = Scroll.BorderH + "px";
                movable.style.marginLeft = Scroll.MBorderH + "px";
            }
        }
        else {
            scroll.style.marginLeft = "0px";
            movable.style.marginLeft = "0px";
        }
        mx = delta = x = abs = null;
    },
    Vert: function (movable, scroll, dx) {
        if (movable) {
            var borderV = dx ? (scroll.parentNode.offsetHeight - scroll.offsetHeight) : Scroll.BorderV;
            var borderMV = dx ? -(movable.offsetHeight - movable.parentNode.offsetHeight) : Scroll.MBorderV;
            var sx = dx ? $G.GetStyle(scroll, "margin-top", true) : Scroll.StartY;
            var x = sx + (dx || $G.Mouse.Y - Scroll.StartMY);
            var abs = borderV / x;
            if (borderMV >= 0 && !dx)
                Scroll.CurrentMovable = null;
            if (x > 0) {
                if (x < borderV) {
                    scroll.style.marginTop = x + "px";
                    if (movable)
                        movable.style.marginTop = Math.floor(borderMV / abs) + "px";
                }
                else {
                    scroll.style.marginTop = borderV + "px";
                    movable.style.marginTop = borderMV + "px";
                }
            }
            else {
                scroll.style.marginTop = "0px";
                movable.style.marginTop = "0px";
            }
            x = abs = null;
        }
    },
    Elements: [],
    Add: function (obj, formal) {
        Scroll.Elements.push({ key: formal, obj: obj });
    },
    Init: function () {
        for (var i = 0; i < Scroll.Elements.length; i++) {
            if ($G.IsString(Scroll.Elements[i].obj)) {
                Scroll.Elements[i].obj = $G.GET(Scroll.Elements[i].obj);
                if (Scroll.Elements[i].obj)
                    $G.Extend(Scroll.Elements[i], { scroll: $G.GET(Scroll.Elements[i].obj, (Scroll.Elements[i].obj.scroll || Scroll.Elements[i].obj.getAttribute("scroll"))) }, "")
            }
            if (Scroll.Elements[i].obj)
                $UI.Wheel.Register(Scroll.Elements[i].obj, Scroll.Elements[i].key, function (delta) {
                    Scroll.Vert(this.obj, this.scroll, -delta * ($G.Browser.Detect.safari ? 5 : 10) * ($G.Browser.Detect.opera ? -1 : 1));
                } .bind(Scroll.Elements[i]), true);
        }
        Scroll._oldMouseUp = document.body.onmouseup;
        document.body.onmouseup = function (e) {
            if (Scroll._oldMouseUp)
                try { Scroll._oldMouseUp(e); } catch (e) { }
            if (Scroll.CurrentMovable)
                try { $G.Selection.Enable(Scroll.CurrentMovable); } catch (e) { }
            Scroll.CurrentScroll = Scroll.CurrentMovable = null;
            if ($G.Browser.Detect.webkit) {
                $G.Selection.Enable(document.body);
            }
        }
        Scroll._oldMouseDown = document.body.onmousedown;
        document.body.onmousedown = function (e) {
            if (Scroll._oldMouseDown)
                try { Scroll._oldMouseDown(e); } catch (e) { }
            if ($G.Browser.Detect.webkit) {
                $G.Selection.Disable(document.body);
            }
            var target = $G.Event.Target(e);
            if (target && target.className && ($G.ClassName.Has(target, "scroll") || target.scroll)) {
                //Scroll
                Scroll.CurrentScroll = target;
                Scroll.StartX = $G.GetStyle(target, "margin-left", true);
                Scroll.StartY = $G.GetStyle(target, "margin-top", true);
                Scroll.Width = target.offsetWidth || 0;
                Scroll.Height = target.offsetHeight || 0;
                Scroll.BorderV = target.parentNode.offsetHeight - Scroll.Height;
                Scroll.BorderH = target.parentNode.offsetWidth - Scroll.Width;
                Scroll.Ver = $G.ClassName.Has(target, "type-vert");
                Scroll.Hor = $G.ClassName.Has(target, "type-hor");
                //Movable

                Scroll.CurrentMovable = $G.GET(target, (target.getAttribute("toscroll") || target.toscroll ));                
                if (Scroll.CurrentMovable) {
                    Scroll.MStartX = $G.GetStyle(Scroll.CurrentMovable, "margin-left", true);
                    Scroll.MStartY = $G.GetStyle(Scroll.CurrentMovable, "margin-top", true);
                    Scroll.MWidth = Scroll.CurrentMovable.offsetWidth || 0;
                    Scroll.MHeight = Scroll.CurrentMovable.offsetHeight || 0;
                    Scroll.MBorderV = -(Scroll.MHeight - Scroll.CurrentMovable.parentNode.offsetHeight);
                    Scroll.MBorderH = -(Scroll.MWidth - Scroll.CurrentMovable.parentNode.offsetWidth);
                    $G.Selection.Disable(Scroll.CurrentMovable);
                }
                Scroll.StartMX = $G.Mouse.X;
                Scroll.StartMY = $G.Mouse.Y;

            }
            target = null;
        }
        Scroll._oldMousemove = document.body.onmousemove;
        document.body.onmousemove = function (e) {
            if (Scroll._oldMousemove)
                try { Scroll._oldMousemove(e); } catch (e) { }
            if (Scroll.CurrentScroll) {
                if (Scroll.Hor) {
                    try { Scroll.Hort(Scroll.CurrentMovable, Scroll.CurrentScroll); } catch (e) { }
                }
                if (Scroll.Ver) {
                    try { Scroll.Vert(Scroll.CurrentMovable, Scroll.CurrentScroll); } catch (e) { }
                }
                return false;
            }
        }
    }
}
Scroll._scrollingLoad = window.onload;
window.onload = function(e) {
    if (Scroll._scrollingLoad)
        Scroll._scrollingLoad(e);
    Scroll.Init();
}
