﻿jQuery.fn.marquee = function(options) {

    var direction_downup = 'down-up';
    var direction_updown = 'up-down';
    var direction_leftright = 'left-right';
    var direction_rightleft = 'right-left';

    var settings = jQuery.extend({
        speed: 5,
        height: -1,
        width: -1,
        direction: direction_downup,
        gapless: 'false'
    }, options);


    var container = null;
    var div = null;
    var mode = 'v';
    var areaHeight;
    var areaWidth;
    var speed2 = 1;
    var interval = 30;
    var scrollStep = 2;
    var speedDirection = 1;
    var timer = null;
    var originalDiv = null;

    if (settings.direction == direction_rightleft || settings.direction == direction_leftright) {

        $(this).css('display', 'inline');
        $(this).find("div").css({ display: "inline" })
        $(this).css('float', 'left');
    }

    originalDiv = $(this).clone();
    originalDiv.css('display', '');

    div = $(this);
    div.wrap("<div/>");

    container = div.parent("div :first");

    container.mouseover(function() { if (timer != null) clearInterval(timer); });
    container.mouseout(initScroll);
    div.css("margin", 0);

    areaHeight = div.attr("offsetHeight");
    areaWidth = div.attr("offsetWidth");

    if (settings.direction == direction_rightleft || settings.direction == direction_leftright) {

        div.css('display', '');
        div.find("div").css('display', '');
    }

    var divHeight = areaHeight;
    var originalDivHeight = divHeight;
    var divWidth = areaWidth;
    var originalDivWidth = divWidth;

    var heightNoSet = false;
    var widthNoSet = false;

    settings.height = parseInt(settings.height);
    settings.width = parseInt(settings.width);

    if (settings.height < 0) {
        settings.height = areaHeight;
        heightNoSet = true;
    }

    if (settings.width < 0) {
        settings.width = areaWidth;
        widthNoSet = true;
    }

    container.css({ height: settings.height, width: settings.width, overflow: 'hidden' });

    div.height(areaHeight);

    if (widthNoSet)
        div.width(areaWidth);
    else
        div.width(settings.width);

    if (settings.direction == direction_rightleft || settings.direction == direction_leftright) {
        div.width((Math.ceil(settings.width / divWidth) + 1) * divWidth);
        div.find("div :first").css('float', 'left');
    }
    
    if (heightNoSet)
        div.height(areaHeight);
    else
        div.height(settings.height);

    areaHeight = parseInt(div.attr("scrollHeight"));
    areaWidth = parseInt(div.attr("scrollWidth"));

    if (settings.width > areaWidth)
        areaWidth = settings.width;

    if (settings.height > areaHeight)
        areaHeight = settings.height;


    if (settings.direction == direction_updown) {
        speedDirection = -1;
        mode = 'v';
    }
    else if (settings.direction == direction_leftright) {
        speedDirection = -1;
        mode = 'h';
    }
    else if (settings.direction == direction_rightleft) {
        mode = 'h';
    }

    interval = parseInt(settings.speed);
    interval = 100 - (interval * 10);

    if (interval < 15)
        interval = 15;

    speed2 = scrollStep * speedDirection;
    setTimeout(initScroll, 1000);

    var first = true;
    var a = 0;

    function initScroll() {
        if (mode == 'v')
            timer = setInterval(scrollVertical, interval);
        else
            timer = setInterval(scrollHorizontal, interval);
    }

    function scrollVertical() {

        if (first) {

            first = false;

            if (settings.direction == direction_downup)
                div.css('margin-top', settings.height + 5);
            else
                div.css('margin-top', (originalDivHeight * -1) + 5);

            container.parent().css({ visibility: "visible" });

            return;
        }

        var t = parseInt(div.css("margin-top")) - speed2;

        if (settings.gapless == 'true') {

            if (settings.direction == direction_downup) {
                if (parseInt(div.css("margin-top")) < settings.height - divHeight) {

                    divHeight += originalDivHeight;

                    var newDiv = originalDiv.clone();

                    div.append(newDiv);
                }
            }
            else if (parseInt(div.css("margin-top")) > 0) {

                divHeight += originalDivHeight;

                div.prepend(originalDiv.clone());

                t -= originalDivHeight;
            }

            if (settings.direction == direction_downup) {
                if (t < 0 && (t * -1) > originalDivHeight) {

                    var firstDiv = $(div.children('div: first')[0]);
                    firstDiv.remove();
                    t += originalDivHeight;
                    divHeight -= originalDivHeight;
                }
            }
            else if (divHeight - (settings.height - t) > originalDivHeight) {

                var firstDiv = $(div.children('div:last')[0]);
                firstDiv.remove();
                divHeight -= originalDivHeight;
            }
        }
        else if (settings.direction == direction_downup && (t * -1) > originalDivHeight)
            t = settings.height + 5;
        else if (settings.direction == direction_updown && t > settings.height)
            t = (originalDivHeight * -1) + 5;

        div.css('margin-top', t);
    }

    function scrollHorizontal() {
        if (first) {

            first = false;

            if (settings.direction == direction_rightleft)
                div.css('margin-left', settings.width + 5);
            else
                div.css('margin-left', (originalDivWidth * -1) + 5);

            container.parent().css({ visibility: "visible", display: "inline" });
            div.css('float', 'left');

            return;
        }

        var l = parseInt(div.css('margin-left')) - speed2;

        if (settings.gapless == 'true') {

            if (settings.direction == direction_rightleft) {
                if (parseInt(div.css("margin-left")) < settings.width - divWidth) {

                    divWidth += originalDivWidth;

                    var newDiv = originalDiv.clone();
                    
                    div.append(newDiv);
                }
            }
            else if (parseInt(div.css("margin-left")) > 0) {

                divWidth += originalDivWidth;

                div.prepend(originalDiv.clone());

                l -= originalDivWidth;
            }

            if (settings.direction == direction_rightleft) {
                if (l < 0 && (l * -1) > originalDivWidth) {
                    var firstDiv = $(div.children('div: first')[0]);
                    firstDiv.remove();
                    l += originalDivWidth;
                    divWidth -= originalDivWidth;
                }
            }
            else if (divWidth - (settings.width - l) > originalDivWidth) {
                var firstDiv = $(div.children('div:last')[0]);
                firstDiv.remove();
                divWidth -= originalDivWidth;
            }
        }
        else if (settings.direction == direction_rightleft && (l * -1) > originalDivWidth)
            l = settings.width + 5;
        else if (settings.direction == direction_leftright && l > settings.width)
            l = (originalDivWidth * -1) + 5;

        div.css('margin-left', l);
    }
};
