// Javascript marquee object by Julian Grinblat
// Converts any object into a marquee

var MarqueeDirection = {

    Top: 1,
    Bottom: 2,
    Left: 3,
    Right: 4

}

var Marquee = function(el, configuration)
{
    this.el = document.createElement("div");
    this.timeout = null;
    this.scrollEl = el;
    this.currentValue = 0;

    var autoStart = true;

    if(configuration != null)
    {
        if(configuration.speed != null)
        {
            this.speed = configuration.speed;
        }
        else
        {
            this.speed = 1;
        }

        if(configuration.direction != null)
        {
            this.direction = configuration.direction;
        }
        else
        {
            this.direction = MarqueeDirection.Top;
        }

        if(configuration.interval != null)
        {
            this.interval = configuration.interval;
        }
        else
        {
            this.interval = 30;
        }

        if(configuration.autoStart != null)
        {
            autoStart = configuration.autoStart;
        }
    }

    if(this.IsVertical()) {
        this.el.style.height = "auto";
    }
    else {
        this.scrollEl.style.whiteSpace = 'nowrap';
        this.el.style.whiteSpace = "nowrap";
        this.el.style.width = "auto";
    }

    this.scrollEl.style.overflow = "hidden";
    this.scrollEl.style.position = "relative";
    
    this.el.style.position = "absolute";

    this.el.innerHTML = this.scrollEl.innerHTML;
    this.scrollEl.innerHTML = "";
    this.scrollEl.appendChild(this.el);

    if(this.IsVertical()) {
        this.el.style.width = this.scrollEl.offsetWidth + "px";
    }
    else {
        if(this.scrollEl.style.height == "") {
            // Make the scroll div keep its dimensions even after messing with its contents
            this.scrollEl.style.height = this.el.offsetHeight + "px";
        }
    }

    if(configuration.startPosition != null)
    {
        this.SetMarqueePosition(configuration.startPosition);
    }
    else
    {
        this.ResetPosition();
    }

    addEvent(
			 this.scrollEl,
			 "mouseover",
			 createObjectCallback(this, this.OnMouseOver));

    addEvent(
			 this.scrollEl,
			 "mouseout",
			 createObjectCallback(this, this.OnMouseOut));

    if(autoStart)
    {
        this.StartScrolling();
    }
}

// Accessors
	
Marquee.prototype.SetSpeed = function(speed)
{
	this.speed = speed;
}

Marquee.prototype.SetDirection = function(direction)
{
	this.direction = direction;
}

Marquee.prototype.SetInterval = function(interval)
{
	this.interval = interval;
}

// Methods

Marquee.prototype.IsScrolling = function()
{
	return this.timeout != null;
}

Marquee.prototype.StartScrolling = function()
{
	// Activate the timeout
    this.MarqueeCallback();
}

Marquee.prototype.StopScrolling = function()
{
	// Deactivate the timeout
    clearTimeout(this.timeout);
}

Marquee.prototype.ResetPosition = function()
{
    if(this.IsVertical())
    {
        this.SetMarqueePosition(this.el.offsetHeight * -1);
    }
    else
    {
        this.SetMarqueePosition(this.el.offsetWidth * -1);
    }
}

Marquee.prototype.IsVertical = function()
{
    return (this.direction == MarqueeDirection.Bottom || this.direction == MarqueeDirection.Top);
}

Marquee.prototype.IsHorizontal = function()
{
    return !this.IsVertical();
}

Marquee.prototype.MarqueeCallback = function()
{
    this.currentValue++;
    if(this.IsVertical())
    {
        if(this.currentValue > this.scrollEl.offsetHeight)
        {
            this.ResetPosition();
        }
        else
        {
            this.SetMarqueePosition(this.currentValue);
        }
    }
    else
    {
        if(this.currentValue > this.scrollEl.offsetWidth)
        {
            this.ResetPosition();
        }
        else
        {
            this.SetMarqueePosition(this.currentValue);
        }
    }

    this.timeout = setTimeout(createObjectCallback(this, this.MarqueeCallback), this.interval);
}

Marquee.prototype.SetMarqueePosition = function(value)
{
    this.currentValue = value;
    
    if(this.direction == MarqueeDirection.Top)
    {
        this.el.style.bottom = value + "px";
    }
    else if(this.direction == MarqueeDirection.Bottom)
    {
        this.el.style.top = value + "px";
    }
    else if(this.direction == MarqueeDirection.Left)
    {
        this.el.style.right = value + "px";
    }
    else if(this.direction == MarqueeDirection.Right)
    {
        this.el.style.left = value + "px";
    }
}

Marquee.prototype.OnMouseOver = function()
{
    this.StopScrolling();
}

Marquee.prototype.OnMouseOut = function(e)
{
    // Execute the mouse out ONLY if we're mousing out of the scrolEl
    // The way to check it is to read the toElement of the event, and check if it's a
    // child of scrollEl, by looping all the way up to the body
    // If it's not a child, great, if it is, then do not execute this event
	var reltg = (e.relatedTarget) ? e.relatedTarget : e.toElement;
	while (reltg != this.scrollEl && reltg.nodeName != 'BODY')
		reltg = reltg.parentNode
	if (reltg == this.scrollEl) return;

	this.StartScrolling();
}