﻿Type.registerNamespace('Zecco.Integration.QuoteComponent');

Zecco.Integration.QuoteComponent.QuoteEngine = function(element)
{
    //Module level variables    
    this._id = ''; // the unique id of this QuoteEngine
    this._btnID = '';    // the trigger button's clientid
    this._interval = 15*60*1000;// 15 minutes as default interval for achieving quote data
    this._isProcessing = false; // whether the callback operation is processing
    this._enableCallback = true; // turn on/off the callback of webmethod to async-refresh quote data
    this._idleTimer = null; // timer to disable the callback 
    this._idleInterval = 15*60*1000; // 15 minutes as default interval, to disable the callback to achieve quote data
    this._serializeLevels = ''; // a string to keep all registered controls' serializeLevel property
    this._symbols = ''; // a string to keep all registered controls' Symbol property

    //Required Event Handlers
    this._clickHandler = null;

    //Calling the base class constructor
    Zecco.Integration.QuoteComponent.QuoteEngine.initializeBase(this, [element]);
}

Zecco.Integration.QuoteComponent.QuoteEngine.prototype =
{       
    //Getter for id Property    
   get_id : function()    
   {    
     return this._id;    
   },    
     
   //Setter for id Property    
   set_id : function(value)    
   {    
     this._id = value;    
   }, 
   
   //Getter for btnID Property    
   get_btnID : function()    
   {    
     return this._btnID;    
   },    
     
   //Setter for btnID Property    
   set_btnID : function(value)    
   {    
     this._btnID = value;    
   },    
   
   //Getter for interval Property    
   get_interval : function()    
   {    
     return this._interval;    
   },    
     
   //Setter for interval Property    
   set_interval : function(value)    
   {    
     this._interval = value;    
   },  
   
   //Getter for isProcessing Property    
   get_isProcessing : function()    
   {    
     return this._isProcessing;    
   },    
     
   //Setter for isProcessing Property    
   set_isProcessing : function(value)    
   {    
     this._isProcessing = value;    
   }, 
   
   //Getter for enableCallback Property    
   get_enableCallback : function()    
   {    
     return this._enableCallback;    
   },    
     
   //Setter for enableCallback Property    
   set_enableCallback : function(value)    
   {    
     if( value != this._enableCallback)
        log.debug(value?'Current page is active.':'Current page is idle');
     this._enableCallback = value;    
   },  
   
   //Getter for idleTimer Property    
   get_idleTimer : function()    
   {
     return this._idleTimer;    
   },    
     
   //Setter for idleTimer Property    
   set_idleTimer : function(value)    
   {
     this._idleTimer = value;    
   },  
   
   //Getter for idleInterval Property    
   get_idleInterval : function()    
   {    
     return this._idleInterval;    
   },          
     
   //Setter for idleInterval Property    
   set_idleInterval : function(value)    
   {    
     this._idleInterval = value;    
   },  
   
   //Getter for serializeLevels Property    
   get_serializeLevels : function()    
   {    
     return this._serializeLevels;    
   },
   
   //Getter for symbols Property    
   get_symbols : function()    
   {    
     return this._symbols;    
   },

    initialize : function()
    {
        //Call the base class method
        Zecco.Integration.QuoteComponent.QuoteEngine.callBaseMethod(this, 'initialize');

        var target = this.get_element();
      
        this._clickHandler = Function.createDelegate(this, this._onClick);

        //Attach the required event handlers
        $addHandlers(target, {'click': this._clickHandler}, this);
        
        // register all client refresh functions to the trigger button
        this.registerRefreshFuncs();
        // schedule the callback method to async-achieve quote data
        this.scheduleCallback();
        // schedule an idle timer to disable callback
        this.initIdleTimer();
    },

    dispose : function()
    {
        $clearHandlers(this.get_element()); // Detach all event handlers
      
        delete this._clickHandler;

        //Call the base class method
        Zecco.Integration.QuoteComponent.QuoteEngine.callBaseMethod(this, 'dispose');
    },

    add_click : function(handler)
    {
        this.get_events().addHandler('click', handler);
    },

    remove_click : function(handler)
    {
        this.get_events().removeHandler('click', handler);
    },

    _onClick : function(e)
    {
        e.preventDefault();

        var handler = this.get_events().getHandler('click');

        // Check if there is any subscriber of this event
        if (handler != null)
        {
            handler(this, Sys.EventArgs.Empty);
        }
    },

    registerRefreshFuncs : function()
    {        
        var btnID = this.get_btnID();        
        var btn = $get(btnID);
        var controlRegInfos = QuoteEngine_ControlRegInfos;
        if(controlRegInfos==null || controlRegInfos == '')
            return;
        
        var existingSymbols = new Hash();
        for(i=0; i<controlRegInfos.length; i++)
	    {	        
	        if( controlRegInfos[i].ClientRefreshFunction )
	        {
	            if( existingSymbols.get(controlRegInfos[i].Symbol) == null || controlRegInfos[i].SerializeLevel > existingSymbols.get(controlRegInfos[i].Symbol) )
	            {
	                existingSymbols.set( controlRegInfos[i].Symbol, controlRegInfos[i].SerializeLevel );
	            }
	                
	            var callback = Function.createCallback(this.refreshQuoteData, controlRegInfos[i]);
	            $addHandler(btn,'click',callback); 
	        }
	    }	
	    
	    var keys = existingSymbols.keys();
	    for (var index = 0; index < keys.length; ++index)
	    {
            var item = keys[index];
            
            if(index == 0)
	            this._symbols = item;
	        else
	            this._symbols += ',' + item;
        }
        
	    var values = existingSymbols.values();
	    for (var index = 0; index < values.length; ++index)
	    {
            var item = values[index];
            
            if(index == 0)
	            this._serializeLevels = item;
	        else
	            this._serializeLevels += ',' + item;
        }	    	   
    },
    
    refreshQuoteData : function(sender, controlRegInfo)
    {        
        if(QuoteEngine_Quotes==null)
            return;
        var quote = QuoteEngine_Quotes[controlRegInfo.Symbol];
        if(quote != null)
            eval(controlRegInfo.ClientRefreshFunction)(quote);
    },

    triggerRefreshFuncs : function()
    {        
        var btnID = this.get_btnID(); 
        $get(btnID).click();
    },
    
    scheduleCallback : function()
    {
        var scriptCode = "$find('"+this.get_id()+"').callbackWebMethod();";
        var t = window.setInterval(scriptCode,this.get_interval());
        log.debug('start a callback timer:'+t);
    },
    
    callbackWebMethod : function()
    {
        if(!this.get_isProcessing() && this.get_enableCallback())
        {
            try
            {
                log.debug('call web method: GetQuotesData');
                this.set_isProcessing(true);
                //CommunityServerWeb.QuoteMedia.Widgets.WidgetService.GetQuotesData(QuoteEngine_Symbols.toString(),this.onSucceed,this.onFailed,this.get_id());
                CommunityServerWeb.QuoteMedia.Widgets.WidgetService.GetQuotesData(this.get_symbols(),this.get_serializeLevels(),this.onSucceed,this.onFailed,this.get_id());
            }catch(e)
            {
                log.error('error happens when GetQuotesData.' + e.name + ": " + e.message);
                this.set_isProcessing(false);
            }
        }else
        {
            if(!this.get_enableCallback())
            {
                log.debug('Can not fulfill GetQuotesData: the page is idle!');
            }
            else if(this.get_isProcessing())
            {
                log.debug('Can not fulfill GetQuotesData: the page is still processing the last callback!');
            } 
        }
    },
    
    onSucceed : function(result,id)
    {    
        try
        {
            eval(result);
         }catch(e)
         {
            log.error('error happens when onSucceed of GetQuotesData.' + e.name + ": " + e.message);
         }finally
         {
            $find(id).set_isProcessing(false);
         }
    },
    
    onFailed : function(error,id)
    {    
        // do nothing with error
        log.error("GetQuotesData Failed: " + error.get_message());
        $find(id).set_isProcessing(false);
    },
    
    initIdleTimer : function()
    {
        // start the idle timer
        this.scheduleIdleTimer(null,this.get_id());
        
        //attach event listener to reschedule the idle timer
        var idleHandler = Function.createCallback(this.scheduleIdleTimer, this.get_id());
        Event.observe(window,"mousedown",idleHandler,true);
        Event.observe(window,"mousemove",idleHandler,true);
        Event.observe(window,"keydown",idleHandler,true);
        Event.observe(window,"resize",idleHandler,true);
        Event.observe(window,"scroll",idleHandler,true);
    },
    
    scheduleIdleTimer : function(e,id)
    {        
        var thisObj = $find(id);
        
        thisObj.set_enableCallback(true);
        
        var scriptCode = "$find('"+id+"').set_enableCallback(false);";
        if(thisObj.get_idleTimer()!=null)
        {
            window.clearInterval(thisObj.get_idleTimer());    
        }                
        var t = window.setInterval(scriptCode, thisObj.get_idleInterval());
        thisObj.set_idleTimer(t);
    }
}

Zecco.Integration.QuoteComponent.QuoteEngine.registerClass('Zecco.Integration.QuoteComponent.QuoteEngine', Sys.UI.Control);

if (typeof(Sys) != 'undefined')
{
    Sys.Application.notifyScriptLoaded();
}
