﻿Type.registerNamespace('MattBerseth.WebControls.AJAX.Marquee.MarqueeBehavior');

MattBerseth.WebControls.AJAX.Marquee.MarqueeBehavior = function(element) {
    this._wrapper = null;
    this._ticker = null;
    this._mouseOverHandler = null;
    this._mouseOutHandler = null;
    this._intervalID = null;
    this._isPaused = null;

    this._isRightToLeft = null;
    this._serviceMethod = null;
    this._servicePath = null;
    this._itemCssClass = null;
    this._itemMouseOverCssClass = null;
    this._pixelsPerSecond;

    MattBerseth.WebControls.AJAX.Marquee.MarqueeBehavior.initializeBase(this, [element]);
}

MattBerseth.WebControls.AJAX.Marquee.MarqueeBehavior.prototype = {
    initialize: function() {
        MattBerseth.WebControls.AJAX.Marquee.MarqueeBehavior.callBaseMethod(this, 'initialize');
        //  cache the ticker and wrapper elements
        this._wrapper = $get(this.get_id() + "_wrapper");
        this._ticker = $get(this.get_id() + "_ticker");

        //  attach to the mouse over/out events
        this._mouseOverHandler = Function.createDelegate(this, function() { this._isPaused = true; });
        $addHandler(this._ticker, 'mouseover', this._mouseOverHandler);

        this._mouseOutHandler = Function.createDelegate(this, function() { this._isPaused = false; });
        $addHandler(this._ticker, 'mouseout', this._mouseOutHandler);

        //  kick off the marquee
        this._start();
    },

    dispose: function() {
        if (this._intervalID) {
            window.clearInterval(this._intervalID);
        }
        if (this._mouseOverHandler) {
            $removeHandler(this._ticker, 'mouseover', this._mouseOverHandler);
        }
        if (this._mouseOutHandler) {
            $removeHandler(this._ticker, 'mouseout', this._mouseOutHandler);
        }

        MattBerseth.WebControls.AJAX.Marquee.MarqueeBehavior.callBaseMethod(this, 'dispose');
    },

    _start: function() {
        //  do any clean up from previous running
        this._isPaused = true;
        if (this._intervalID) {
            window.clearInterval(this._intervalID);
        }

        //  fetch the marquee items from the web method
        Sys.Net.WebServiceProxy.invoke(
           this._servicePath,
           this._serviceMethod,
           false,
           null,
           Function.createDelegate(this, this._onServiceMethodComplete),
           Function.createDelegate(this, this._onServiceMethodFailed));
    },

    _onServiceMethodComplete: function(result, userContext, methodName) {
        this._initLayout(this.get_IsRightToLeft(), result);

        this._isPaused = false;
        this._intervalID = window.setInterval(Function.createDelegate(this, this._onInterval), 10);
    },

    _onServiceMethodFailed: function(webServiceError, userContext, methodName) {
        var e = this.get_element();
        e.innerHTML = 'Unable to retrieve Marquee';
    },

    _onInterval: function() {
        this._performLayout(this.get_IsRightToLeft());
    },

    _initLayout: function(isRightToLeft, result) {
        var i;
        //  clear the handlers if the ticker
        //  has any children
        if (this._ticker.childNodes.length > 0) {
            //  remove the handlers
            for (i = 0; i < this._ticker.childNodes.length; i++) {
                $clearHandlers(this._ticker.childNodes[i]);
            }

            //  clear any child elements
            this._ticker.innerHTML = '';
        }

        var width = 0;
        //  loop through the results and create a span for 
        //  each of the items
        for (i = 0; i < result.length; i++) {
            //  create the items container and add it to
            //  the document
            var item = document.createElement('SPAN');
            var itemCssClass = this.get_ItemCssClass();
            if (itemCssClass) {
                Sys.UI.DomElement.addCssClass(item, itemCssClass);
            }
            item.innerHTML = result[i];
            this._ticker.appendChild(item);

            //  attach mousover and out events to the item
            //  so we can pause the marquee when it is moused over
            var itemMouseOverCssClass = this.get_ItemMouseOverCssClass();
            if (itemMouseOverCssClass) {
                $addHandler(item, 'mouseover',
                    Function.createDelegate(item, function() {
                        Sys.UI.DomElement.addCssClass(this, itemMouseOverCssClass);
                    })
                );
                $addHandler(item, 'mouseout',
                    Function.createDelegate(item, function() {
                        Sys.UI.DomElement.removeCssClass(this, itemMouseOverCssClass);
                    })
                );
            }
        }

        var tickerWidth = this._getTickerWidth();
        //  set the width of the span to the sum of its
        //  embedded elements
        this._ticker.style.width = tickerWidth + 'px';

        if (isRightToLeft) {
            //  the ticker is moving right to left, set the 
            //  left bounds to the value of the containers width
            this._ticker.style.left = $common.getSize(this._wrapper).width + 'px';
        }
        else {
            //  the ticker moves left to right, set the
            this._ticker.style.left = -tickerWidth + 'px';
        }
    },

    _performLayout: function(isRightToLeft) {
        if (!this._isPaused) {
            if (isRightToLeft) {
                // subtract a value from the left
                var newLeft = ($common.parseUnit(this._ticker.style.left).size - Math.ceil((this.get_PixelsPerSecond() / 100)));
                //  if the new left is equal to the negative of the width
                if (-newLeft > $common.getSize(this._ticker).width) {
                    this._start();
                }
                else {
                    this._ticker.style.left = newLeft + 'px';
                }
            }
            else {
                var newLeft = ($common.parseUnit(this._ticker.style.left).size + Math.ceil((this.get_PixelsPerSecond() / 100)));
                //  if the new left is equal to the negative of the width
                if (newLeft > $common.getSize(this._wrapper).width) {
                    this._start();
                }
                else {
                    this._ticker.style.left = newLeft + 'px';
                }
            }
        }
    },

    _getTickerWidth: function() {
        var width = 0;
        //  add all of the items to the body
        for (var i = 0; i < this._ticker.childNodes.length; i++) {

            var originalNode = this._ticker.childNodes[i];
            var node = originalNode.cloneNode(true);
            //  add it to the document
            document.body.appendChild(node);

            var paddingBox = $common.getPaddingBox(originalNode);
            var marginBox = $common.getMarginBox(originalNode);
            var borderBox = $common.getBorderBox(originalNode);

            var contentWidth = $common.getContentSize(node).width;
            //  add the padding ...
            contentWidth += (paddingBox.right + paddingBox.left);
            //  add the border ...
            contentWidth += (borderBox.right + borderBox.left);
            //  add the margin ...
            contentWidth += (marginBox.right + marginBox.left);

            //  get its width
            width += contentWidth;

            //  add it to the document
            document.body.removeChild(node);
        }

        return width;
    },

    get_ServicePath: function() {
        return this._servicePath;
    },
    set_ServicePath: function(value) {
        if (this._servicePath != value) {
            this._servicePath = value;
            this.raisePropertyChanged('ServicePath');
        }
    },

    get_ServiceMethod: function() {
        return this._serviceMethod;
    },
    set_ServiceMethod: function(value) {
        if (this._serviceMethod != value) {
            this._serviceMethod = value;
            this.raisePropertyChanged('ServiceMethod');
        }
    },

    get_IsRightToLeft: function() {
        return this._isRightToLeft;
    },
    set_IsRightToLeft: function(value) {
        if (this._isRightToLeft != value) {
            this._isRightToLeft = value;
            this.raisePropertyChanged('IsRightToLeft');
        }
    },

    get_ItemMouseOverCssClass: function() {
        return this._itemMouseOverCssClass;
    },
    set_ItemMouseOverCssClass: function(value) {
        if (this._itemMouseOverCssClass != value) {
            this._itemMouseOverCssClass = value;
            this.raisePropertyChanged('ItemMouseOverCssClass');
        }
    },

    get_ItemCssClass: function() {
        return this._itemCssClass;
    },
    set_ItemCssClass: function(value) {
        if (this._itemCssClass != value) {
            this._itemCssClass = value;
            this.raisePropertyChanged('ItemCssClass');
        }
    },

    get_PixelsPerSecond: function() {
        return this._pixelsPerSecond;
    },
    set_PixelsPerSecond: function(value) {
        if (this._pixelsPerSecond != value) {
            this._pixelsPerSecond = value;
            this.raisePropertyChanged('PixelsPerSecond');
        }
    }
}
MattBerseth.WebControls.AJAX.Marquee.MarqueeBehavior.registerClass('MattBerseth.WebControls.AJAX.Marquee.MarqueeBehavior', Sys.UI.Control);

if(typeof(Sys)!=='undefined')Sys.Application.notifyScriptLoaded();