/* jQuery LiveQuote 0.1
 * Author: HW
 * Version: 0.1
 * Requires: jQuery 1.2+
 */
var lqTimer=null;
var lqRunning=0;
var lqToken="";
if(typeof mediadomain=='undefined') var mediadomain="http://m1.smartmoney.net";
function lqStop() { window.clearTimeout(lqTimer); lqRunning=0; lqToken=""; };

(function($){
	$.fn.livequote = function(options){  
		var defaults = {
			key:'',
			action:'start',
			lqServer:'lq.smartmoney.net',
			initURL:'/com/smartmoney/livequote/lqmiddleware.cfc?method=getInitData&tickers=',
			symAt:'smsym',
			fieldAt:'smfield',
			historyLen:2,
			delay:0,
			img_up:"<img src='"+mediadomain+"/framework/images/arrow-up.gif' width='7' height='7' alt='Up' />",
			img_down:"<img src='"+mediadomain+"/framework/images/arrow-down.gif' width='7' height='7' alt='Down' />",
			img_nc:'-'
		};
		var o=$.extend(defaults,options);
		var lqID=[];
		var lqTickers="";
		var lqNumMatch=this.length;
		var lqMap={};
		
		function start(){
			if(lqRunning) stop();
			$.ajax({
				type:"GET",
				url:o.initURL+lqTickers+"&key="+o.key,
				dataType:"json",
				success: function(json){
					lqToken=json.TOKEN;
					update(json.DATA);
					if(lqToken.length){
						lqRunning=1;
						getData();
					} else
						stop();
				},
				error: function(){ stop(); }
			});
		}

		function stop(){ window.clearTimeout(lqTimer); lqRunning=0; lqToken=""; lqMap={}; } 
		
		function getData(){
			if(lqRunning){
				$.ajax({
					type:"GET",
					url:"http://"+o.lqServer+"/q?t="+lqToken+"&"+Math.random(),
					dataType:"script",
					success: function(){
						update(_sm);
						clearTimeout(lqTimer);
						lqTimer=setTimeout(getData, Math.max(1000, (_smv+o.delay) * 1000)); 
					},
					error: function(){ stop(); }
				});
			}
		}
	
		function update(data){
			if(data){
				createMap(lqTickers,data);
				for(var i=0; i<lqID.length; i++){
					$("#"+lqID[i]+" span["+o.symAt+"]").each(	function(){
						thisEl=$(this);
						sym=thisEl.attr(o.symAt);
						if(sym.length && lqMap[sym] && lqMap[sym][0].price.length){
							var netChgClass=lqMap[sym][0].nchg < 0 ? 'down': lqMap[sym][0].nchg > 0 ? 'up' : '';
							switch(thisEl.attr(o.fieldAt)){
								case 'price': 
									var priceChg=previousChg(lqMap[sym][0].price,sym);
									var priceChgClass=priceChg < 0 ? 'down': priceChg > 0 ? 'up' : '';
									chgElement(thisEl,lqMap[sym][0].price,priceChgClass);
									break;
								case 'nchg':  chgElement(thisEl,lqMap[sym][0].nchg,netChgClass); break;
								case 'pchg':  chgElement(thisEl,lqMap[sym][0].pchg+'%',netChgClass); break;
								case 'icon':	chgElement(thisEl,((lqMap[sym][0].nchg < 0) ? o.img_down: (lqMap[sym][0].nchg > 0)?o.img_up:o.img_nc)); break;
							} // switch
						} // endif sym.length
					});
				}
				setTimeout(resetColor, 500);
			}
		}
		
		function chgElement(el,strHTML,className){
			if(strHTML) el.html(strHTML);
			if(typeof className !='undefined'){
				el.removeClass();
				el.addClass(className);
			}
		}
		
		function createMap(tickerList,dataList){
			var tickers=tickerList.split(",");
			var data = dataList.split(',');
			for(var i=0; i<data.length;i++){
				var val = formatData(data[i].split('|'));
				if(tickers[i]){
					if(!lqMap[tickers[i]]) lqMap[tickers[i]]=new Array();
					if(lqMap[tickers[i]].length >= o.historyLen) lqMap[tickers[i]].pop();
					lqMap[tickers[i]].unshift({ price:val[0], nchg:val[1], pchg:val[2] });
				}
			}
		}
		
		function previousChg(current, sym){
			var previous=current;
			if(lqMap[sym] instanceof Array && lqMap[sym].length > 1)
				previous = lqMap[sym][1].price;
			if(current == previous)
				return 0;
			else 
				return previous == null ? 0 : (current-previous);
		}
		
		function formatData(data){
			if(data[0].charAt(0)=="*"){
				data[0]=Number(data[0].substring(1)).toFixed(2);
				data[3]="*";
			} else {
				if(data[0].length && !isNaN(data[0])) data[0]=Number(data[0]).toFixed(2);
				data[3]="";
			}
			data[1] = (!isNaN(data[1])) ? Number(data[1]).toFixed(2) : "NA";
			if(!isNaN(data[0]) && !isNaN(data[1]))
				data[2]=data[0] - data[1] == 0 ? ' ' : ((data[1]/(data[0] - data[1]))*100).toFixed(2);
			else
				data[2]="NA";
			return data;
		}
		
		function resetColor(){
			for(var i=0; i<lqID.length; i++){
				$("#"+lqID[i]+" span["+o.fieldAt+"='price']").each(	function(){
					$(this).removeClass("up down");
				});
			}
		}
		
		function listfind(list,value) {
			var tmp=[];
			var foundIdx=-1;
			list = list.toUpperCase();
			value = value.toUpperCase();
			tmp = list.split(",");
			for(var i=0;i<tmp.length;i++){
				if(tmp[i]==value){ foundIdx=i; break; }
			}
			return foundIdx;
		}
		
		return this.each(function() {
			var thisID=this.id;
			
			function getTickers(){
				$("#"+thisID+" span["+o.symAt+"]").each(	function(){
					sym=$(this).attr(o.symAt);
					if(listfind(lqTickers,sym)==-1){
						if(lqTickers.length) lqTickers+=",";
						lqTickers+=sym.toUpperCase();
					}
				});
				//$(this).data("tickers",lqTickers);
			}

			if($(this).data("ready")){
				lqID.push(thisID);
				getTickers();
			} else
				return;
			
			if(lqID.length==lqNumMatch){
				switch(o.action){
					case 'start': start(); break;
					case 'stop': stop(); break;
				}
			}

		});

	}; 
})(jQuery);
