/**
 * EverythingScroller
 *
 * @author Jean-Francois M\u00fcller
 *
 * Copyright (c) styled4u.com Jean-Francois Mueller, all rights reserved.
 *
 * Known Bugs:
 * TODO: If the surrounding container has a border defined,
 *       than problems will occure with reaching the far right end.
 *       The better way is to define another div around the container and
 *       give it the necessary border.
 *
 */
function Scroller(node, optional_maxSpeed_in_px, optional_refreshrate_in_ms)
{
    this.maxSpeed    = (typeof optional_maxSpeed_in_px != "undefined")    ? optional_maxSpeed_in_px    : 10;
    this.refreshrate = (typeof optional_refreshrate_in_ms != "undefined") ? optional_refreshrate_in_ms : 50;

    this.ContainerNode = node;
    this.ContentNode = false;
    this.LeftScroller = false;
    this.RightScroller = false;

    this.bInitiated = false;

    this.UpScroller = false;
    this.DownScroller = false;

    this.curSpeedX = 0;
    this.curSpeedY = 0;
    this.bScrollLeft    = false;
    this.bScrollRight   = false;
    this.bScrollUp      = false;
    this.bScrollDown    = false;

    this.maxScrollX = 0;
    this.maxScrollY = 0;

    this.intervallIndicator = 0;

    var self = this;

    this.setLeftScroller = function(node)
    {
        this.LeftScroller = node;
        this.LeftScroller.onmouseover = function(){
            self.scrollLeft();
        };

        this.LeftScroller.onmouseout  = function(){
            self.stopScrollLeft();
        };
    }

    this.setRightScroller = function(node)
    {
        this.RightScroller = node;
        this.RightScroller.onmouseover = function(){
            self.scrollRight();
        };
        this.RightScroller.onmouseout  = function(){
            self.stopScrollRight();
        };
    }

    this.setUpScroller = function(node)
    {
        this.UpScroller = node;
        this.UpScroller.onmouseover = function(){
            self.scrollUp();
        };
        this.UpScroller.onmouseout  = function(){
            self.stopScrollUp();
        };
    }

    this.setDownScroller = function(node)
    {
        this.DownScroller = node;
        this.DownScroller.onmouseover = function(){
            self.scrollDown();
        };
        this.DownScroller.onmouseout  = function(){
            self.stopScrollDown();
        };
    }

    this.init = function(force)
    {
        if(this.bInitiated && !force) // if it is already initiated
            return;

        // TODO: building a container around the given container, may be the better solution instead of using the necessary div
        if(!this.ContainerNode.getElementsByTagName("div")[0])
            throw "no necessary inner div is defined!";
        this.ContentNode = this.ContainerNode.getElementsByTagName("div")[0];

        this.ContainerNode.style.position = "relative";
        this.ContentNode.style.position = "absolute";
        this.ContentNode.style.top = 0+"px";

        //calculating the max scroll positions, notice the MINUS in front of the expressions!
        this.maxScrollX = -(this.ContentNode.offsetWidth  - this.ContainerNode.offsetWidth);
        this.maxScrollY = -(this.ContentNode.offsetHeight - this.ContainerNode.offsetHeight);

        this.maxScrollX = (this.maxScrollX >= 0) ? 0 : this.maxScrollX;
        this.maxScrollY = (this.maxScrollY >= 0) ? 0 : this.maxScrollY;

        // if already an intervall was set, clear it
        if(this.intervallIndicator)
            window.clearInterval(this.intervallIndicator);

        // setting the scroll interval
        this.intervallIndicator = window.setInterval(function(){
            self.scrollIt();
        }, this.refreshrate);

        this.bInitiated = true;
    }

    this.scrollIt = function()
    {
        /**** Acceleration ****/
        // x axis
        if(this.m_bScrollLeft && this.curSpeedX <= this.maxSpeed)
            this.curSpeedX += 1;
        if(this.m_bScrollRight && this.curSpeedX >= (this.maxSpeed*-1))
            this.curSpeedX += -1;
        // y axis
        if(this.m_bScrollUp && this.curSpeedY <= this.maxSpeed)
            this.curSpeedY += 1;
        if(this.bScrollDown && this.curSpeedY >= (this.maxSpeed*-1))
            this.curSpeedY += -1;

        /**** slowing down ****/
        // x axis
        if(this.curSpeedX != 0 && !this.m_bScrollLeft && !this.m_bScrollRight)
            this.curSpeedX += (this.curSpeedX > 0) ? -1 : 1
        // y axis
        if(this.curSpeedY != 0 && !this.m_bScrollUp && !this.bScrollDown)
            this.curSpeedY += (this.curSpeedY > 0) ? -1 : 1

        /**** moving content... ****/
        var newPos;

        // x axis
        if(this.curSpeedX != 0)
        {
            newPos = parseInt(this.ContentNode.style.left);

            if(isNaN(newPos))
                newPos = 0;

            newPos += this.curSpeedX;

            // limit corrections
            if(newPos > 0) newPos = 0;
            if(newPos < this.maxScrollX) newPos = this.maxScrollX;
            if(newPos == 0 || newPos == this.maxScrollX) this.curSpeedX = 0;

            this.ContentNode.style.left = newPos+"px";
        }

        // y axis
        if(this.curSpeedY != 0)
        {
            newPos = parseInt(this.ContentNode.style.top);

            if(isNaN(newPos))
                newPos = 0;

            newPos += this.curSpeedY;

            // boundaries corrections
            if(newPos > 0) newPos = 0;
            if(newPos < this.maxScrollY) newPos = this.maxScrollY;
            if(newPos == 0 || newPos == this.maxScrollY) this.curSpeedY = 0;

            this.ContentNode.style.top = newPos+"px";
        }
    }

    this.scrollLeft = function()
    {
        this.init();
        this.stopScrollRight();
        this.m_bScrollLeft = true;
    }

    this.stopScrollLeft = function()
    {
        this.m_bScrollLeft = false;
    }

    this.scrollRight = function()
    {
        this.init();
        this.stopScrollLeft();
        this.m_bScrollRight = true;
    }

    this.stopScrollRight = function()
    {
        this.m_bScrollRight = false;
    }

    this.scrollUp = function()
    {
        this.init();
        this.stopScrollDown();
        this.m_bScrollUp = true;
    }

    this.stopScrollUp = function()
    {
        this.m_bScrollUp = false;
    }

    this.scrollDown = function()
    {
        this.init();
        this.stopScrollUp();
        this.bScrollDown = true;
    }

    this.stopScrollDown = function()
    {
        this.bScrollDown = false;
    }
}