﻿Type.registerNamespace('ABS.Web.UI.Controls.MarqueeBehavior');

ABS.Web.UI.Controls.MarqueeBehavior = function(element) {

    this._wrapper = null;
    this._ticker = null;
    
    this._mouseOverHandler = null;
    this._mouseOutHandler = null;
    
    this._paused = null;
    this._hovering = null;
    
    this._timerDrawID = null;    
    this._timerPauseID = null;
    this._timerRefreshID = null;
    
    this._items = null;
    this._itemsTemp = null;
    
    this._itemIndex = null;
    
    this._servicePath = null;
    this._serviceMethod = null;
    this._serviceRefreshInterval = null;
    
    this._itemPauseTimeout = null;

    this._itemCssClass = null;
    this._itemMouseOverCssClass = null;
    
    ABS.Web.UI.Controls.MarqueeBehavior.initializeBase(this, [element]);
}

ABS.Web.UI.Controls.MarqueeBehavior.prototype = {
    
    initialize : function() {    
        ABS.Web.UI.Controls.MarqueeBehavior.callBaseMethod(this, 'initialize');  
        
        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._hovering = true; });
        $addHandler(this._ticker, 'mouseover', this._mouseOverHandler);        
        
        this._mouseOutHandler = Function.createDelegate(this, function(){ this._hovering = false; });
        $addHandler(this._ticker, 'mouseout', this._mouseOutHandler);      
 
        this._refreshData();
    },
    
    dispose : function() {
        ABS.Web.UI.Controls.MarqueeBehavior.callBaseMethod(this, 'dispose');
        
        if (this._timerDrawID) {
            window.clearInterval(this._timerDrawID);
            this._timerDrawID = null;
        }
        
        if (this._timerPauseID) {
            window.clearTimeout(this._timerPauseID);
            this._timerPauseID = null;
        }
        
        if (this._timerRefreshID) {
            window.clearTimeout(this._timerRefreshID);
            this._timerRefreshID = null;
        }
        
        if (this._mouseOverHandler) {
            $removeHandler(this._ticker, 'mouseover', this._mouseOverHandler);
            this._mouseOverHandler = null;
        }
        
        if (this._mouseOutHandler) {
            $removeHandler(this._ticker, 'mouseout', this._mouseOutHandler);
            this._mouseOutHandler = null;
        }
          
    },
    
    _refreshData : function() {
    
        if (this._timerRefreshID) {
            window.clearTimeout(this._timerRefreshID);
            this._timerRefreshID = null;
        }

        if (this._checkCookie()) {
            Sys.Net.WebServiceProxy.invoke(
               this._servicePath, 
               this._serviceMethod, 
               false, 
               {"clientID" : this.get_id()},
               Function.createDelegate(this, this._onServiceMethodComplete), 
               Function.createDelegate(this, this._onServiceMethodFailed));
        } else {
            this._reset();
            this._ticker.innerHTML = '';
        }
    },
    
    _onServiceMethodComplete : function(result, userContext, methodName) {
    
        if (this._itemsTemp) {
            for (i = 0; i < this._itemsTemp.length; i++) {
                $clearHandlers(this._itemsTemp[i]);
            }            
            this._itemsTemp = null;
        }
        
        if (result && (result.length > 0)) {

            this._itemsTemp = new Array();
                       
            for (i = 0; i < result.length; i++) {
            
                var item = document.createElement('DIV');
                var itemCssClass = this.get_ItemCssClass();
                
                if (this._itemCssClass) {
                    Sys.UI.DomElement.addCssClass(item, this._itemCssClass);
                }
                
                item.style.top = '0';
                item.style.position = 'relative';
                
                item.innerHTML = result[i];
                this._itemsTemp[i] = item;
                
                var itemMouseOverCssClass = this.get_ItemMouseOverCssClass();
                if (this._itemMouseOverCssClass) {
                    $addHandler(item, 'mouseover', 
                        Function.createDelegate(item, function() {
                            Sys.UI.DomElement.addCssClass(this, this._itemMouseOverCssClass);
                        })
                    );
                    $addHandler(item, 'mouseout', 
                        Function.createDelegate(item, function() {
                            Sys.UI.DomElement.removeCssClass(this, this._itemMouseOverCssClass);
                        })
                    );                
                } 
            }        
        }
        
        if (!this._timerDrawID) {
            this._timerDrawID = window.setInterval(Function.createDelegate(this, this._redraw), 20);
        }
        
        this._scheduleRefresh();
    },
    
    _onServiceMethodFailed : function(error, userContext, methodName) {      
        this._reset();
        this._ticker.innerHTML = 'Unable to retrieve service alerts.';
        this._scheduleRefresh();
    },
    
    _reset : function() {
    
        if (this._items) {
            for (i = 0; i < this._items.length; i++) {
                $clearHandlers(this._items[i]);
            }            
            this._items = null;
        }
        
        if (this._itemTemp) {
            for (i = 0; i < this._itemTemp.length; i++) {
                $clearHandlers(this._itemTemp[i]);
            }            
            this._itemTemp = null;
        }
        
        this._ticker.innerHTML = '';
        this._itemIndex = 0;
    },

    _scheduleRefresh : function() {
        if (!this._timerRefreshID) {
            var interval = this.get_ServiceRefreshInterval();
            if (interval > 0) {
                this._timerRefreshID = window.setTimeout(Function.createDelegate(this, this._refreshData), (interval * 1000));
            }
        }
    },
    
    _checkCookie: function() {     
        return (document.cookie.indexOf(this.get_id() + '=Y') > -1);
    },
    
    _redraw : function() {
        if (!this._items) {
            this._resetLayout();
        }
        this._performLayout();
    },
    
    _resetLayout : function() {
        
        var i;
        
        // Cleanup and remove the old items
        if (this._items) {
            for (i = 0; i < this._items.length; i++) {
                $clearHandlers(this._items[i]);
            }            
            this._items = null;
            this._ticker.innerHTML = '';
        }
        
        if (this._itemsTemp) {
            this._items = new Array();
            for (i = 0; i < this._itemsTemp.length; i++) {
                this._items[i] = this._itemsTemp[i];
                this._ticker.appendChild(this._items[i]);
            }           
            this._itemsTemp = null;
        }
        
        this._itemIndex = 0;
        this._pauseDisplay();
    },
    
    _performLayout : function() {
    
        if (!this._paused) {

            if (!this._items || (this._items.length < 2)) {
                // Check if we have fetched new items
                if (this._itemsTemp) {
                    this._resetLayout();
                }
            } else {
            
                // TODO: This could be optimized by holding references to some of these
                // and not recalculate 
                var heightT = $common.getSize(this._ticker).height;
                
                var index1 = this._getIndex();
                var index2 = this._getIndexNext(index1);
                
                var item1 = this._items[index1];
                var item2 = this._items[index2];
                
                var top1 = $common.parseUnit(item1.style.top).size;
                var top2 = $common.parseUnit(item2.style.top).size;
                            
                var height1 = $common.getSize(item1).height;

                // Check if it's time for the control to start moving off the screen
                if (top1 + height1 <= 0) {
                
                    // Only perform this is we are not moused over the control
                    if (!this._hovering) {
                    
                        // Check if we have fetched new items
                        if (this._itemsTemp) {
                        
                            this._resetLayout();
                        
                        } else {
                        
                            // Move this element to the end
                            this._ticker.removeChild(item1);
                            this._ticker.appendChild(item1);
                            
                            item1.style.top = '0';
                            item2.style.top = '0';
                            
                            this._itemIndex = index2;
                            this._pauseDisplay();
                        }                   
                    }
                } else {
                    item1.style.top = (top1 - 1) + 'px';
                    item2.style.top = (top2 - 1) + 'px';
                }
            }
        }
    },
    
    _pauseDisplay : function() {
        this._paused = true;                
        this._timerPauseID = window.setTimeout(Function.createDelegate(this, this._pauseTimeout), (this.get_ItemPauseTimeout() * 1000));
    },
    
    _pauseTimeout: function() {
        this._paused = false;
    },
    
    _getIndex : function() {
        return this._itemIndex;
    },
    
    _getIndexNext : function(index) {    
        if (index < (this._items.length - 1)) {
            return index + 1;
        } else {
            return 0;
        }
    },
    
    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_ServiceRefreshInterval : function() {
        return this._serviceRefreshInterval;
    },
    set_ServiceRefreshInterval : function(value) {
        if (this._serviceRefreshInterval != value) {
            this._serviceRefreshInterval = value;
            this.raisePropertyChanged('ServiceRefreshInterval');
        }
    },
    
    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_ItemPauseTimeout : function() {
        return this._itemPauseTimeout;
    },
    set_ItemPauseTimeout : function(value) {
        if (this._itemPauseTimeout != value) {
            this._itemPauseTimeout = value;
            this.raisePropertyChanged('ItemPauseTimeout');
        }
    }                  
}
ABS.Web.UI.Controls.MarqueeBehavior.registerClass('ABS.Web.UI.Controls.MarqueeBehavior', Sys.UI.Control);

if(typeof(Sys)!=='undefined')Sys.Application.notifyScriptLoaded();