//*******************************************************************************************
function QuotedSymbol(itemId, ticker)
{
	this._itemId = itemId;
	this._ticker = ticker.toUpperCase();
	this._attached = new Array();
};
QuotedSymbol.prototype.getItemId = function() {return this._itemId;};
QuotedSymbol.prototype.getTicker = function() {return this._ticker;};
QuotedSymbol.prototype.attach = function(target) 
{
	this._attached[this._attached.length] = target;
};

QuotedSymbol.prototype.detach = function(target)
{
	for(var index = 0; index != this._attached.length; ++index)
	{
		if (this._attached[index] == target)
			this._attached[index] = null;
	}
};

QuotedSymbol.prototype.onPickup = function(item)
{
	this._pickupItem = item;
	
	for(var index = 0; index != this._attached.length; ++index)
	{
		var target = this._attached[index];
		if (target != null)
		{
			try
			{
				target.onPickup(this);
			}
			catch(ex)
			{
				LiveQuotes.writeTrace(ex, "pickup", 4);
			}
		}
	}
};

//*******************************************************************************************

function QuotedElement(htmlElement)
{
	this._htmlElement = htmlElement;
	
	this._format = this._htmlElement.getAttribute("aggformat");
	this._format = this._format==null?'({S}:{P},{C})':this._format.toUpperCase();
	
	this._comparevalue = this._htmlElement.getAttribute("comparevalue");
	if(this._comparevalue==null || this._comparevalue=='') this._comparevalue=null; else this._comparevalue=this._comparevalue*1.0;

	this._lastPriceClass = "";
};

QuotedElement.prototype.getHtmlElement = function() { return this._htmlElement;};
QuotedElement.prototype.getSymbol = function() { return this._symbol;};

QuotedElement.prototype.setSymbol = function(symbol) 
{
	if (this._symbol == symbol)
		return;
	
	if (this._symbol)
		this._symbol.detach(this);

	this._symbol = symbol;

	if (this._symbol)
		this._symbol.attach(this);
};

QuotedElement.prototype.onPickup = function(symbol)
{	
	if (symbol != this._symbol)
		return;
	var item=symbol._pickupItem;
	var format=this._format;
	var comparevalue=this._comparevalue?this._comparevalue:item.price-item.change;
	
	if (this._innerSpanPrice == null || this._innerSpanChange == null)
	{
		this._innerSpanSymbol = document.createElement("span");
		
		this._innerSpanPrice  = document.createElement("span");
		this._innerSpanPriceShell  = document.createElement("span");
		this._innerSpanPriceShell.appendChild(this._innerSpanPrice);
		
		this._innerSpanChange = document.createElement("span");
		this._innerSpanChangeShell  = document.createElement("span");
		this._innerSpanChangeShell.appendChild(this._innerSpanChange);
		
		this._innerSpanChangeV = document.createElement("span");
		this._innerSpanChangeVShell  = document.createElement("span");
		this._innerSpanChangeVShell.appendChild(this._innerSpanChangeV);
					
		this._innerHyperlinkSymbol = document.createElement("a");
		this._innerHyperlinkSymbol.target='_blank';
		
		this._innerHyperlinkSymbol.href='http://www.aigaogao.com/tools/history.html?s='+item.symbol;
		
		this._innerHyperlinkSymbol.innerHTML=item.symbol.toUpperCase();
		this._innerSpanSymbol.appendChild(this._innerHyperlinkSymbol);
					
	}

	var signchange='+';	
	if(item.price*1.0<=0) comparevalue=0;
	var classchagned=false;
	if (item.price > comparevalue)
	{
		if(this._className!="up"){ this._className = "up";  classchagned=true;}
	}
	else if (item.price < comparevalue)
	{
		if(this._className!="down"){ this._className = "down";  classchagned=true;}
		signchange='';
	}
	else
	{
		if(this._className!="nochange"){ this._className = "nochange";  classchagned=true;}
	}
	if(classchagned) this.setClassName();
	//this.setFlashTimeout();
	
	this._innerSpanPrice.innerHTML=item.price;
	this._innerSpanChangeV.innerHTML=signchange+(item.price-comparevalue).toDigit(2);
	this._innerSpanChange.innerHTML=comparevalue==0?'-- --':signchange+((item.price*1.0*100)/comparevalue*1.0-100).toDigit(2)+'%';
			
	this._htmlElement.innerHTML = format
		.replace(/{S}/gi, this._innerSpanSymbol.innerHTML)
		.replace(/{P}/gi, this._innerSpanPriceShell.innerHTML)
		.replace(/{CV}/gi, this._innerSpanChangeVShell.innerHTML)
		.replace(/{C}/gi, this._innerSpanChangeShell.innerHTML);};

QuotedElement.prototype.setFlashTimeout = function()
{
	if (this._flashTimeout != null)
	{
		window.clearTimeout(this._flashTimeout);
	}

	var thunk = this;
	this._flashTimeout = window.setTimeout(
		function()
		{
			thunk._flashTimeout = null;
			thunk.setClassName();
		}, 900);
};

QuotedElement.prototype.setClassName = function()
{
	this._innerSpanPrice.className = this._className;
	this._innerSpanChangeV.className = this._className;
	this._innerSpanChange.className = this._className;
};

//*******************************************************************************************

function QuotedApplication()
{
	this._elementArray = new Array();
	this._symbolArray = new Array();
};

QuotedApplication.getCurrent = function()
{
	if (QuotedApplication._current == null)
		QuotedApplication._current = new QuotedApplication();

	return QuotedApplication._current;
};


QuotedApplication.prototype.LookupSymbol = function(ticker)
{
	for(var index = 0; index != this._symbolArray.length; ++index)
	{		
		var quotedSymbol = this._symbolArray[index];
		if (quotedSymbol.getTicker().toUpperCase() == ticker.toUpperCase())
			return quotedSymbol;
	}
	return null;
};

QuotedApplication.prototype.BindSymbol = function(ticker)
{
	var quotedSymbol = this.LookupSymbol(ticker);
	if (quotedSymbol == null)
	{
		// reserve slot quickly
		var itemId = this._symbolArray.length;		
		this._symbolArray[itemId] = null; 
		
		// create and assign
		quotedSymbol = new QuotedSymbol(itemId, ticker);
		this._symbolArray[itemId] = quotedSymbol;
	}
	
	return quotedSymbol;
};

QuotedApplication.prototype.LookupElement = function(htmlElement)
{
	for(var index = 0; index != this._elementArray.length; ++index)
	{
		var quotedElement = this._elementArray[index];
		if (quotedElement.getHtmlElement() == htmlElement)
			return quotedElement;
	}
	return null;
};

QuotedApplication.prototype.BindElement = function(htmlElement)
{
	var quotedElement = this.LookupElement(htmlElement);
	if (quotedElement == null)
	{
		quotedElement = new QuotedElement(htmlElement);
		this._elementArray[this._elementArray.length] = quotedElement;
	}
	
	return quotedElement;
};

QuotedApplication.prototype.Pickup = function()
{
	if(this._symbolArray.length>0)
	{
    LiveQuotes.writeTrace("Sending pickup for " + this._ticket, "pickup", 1);
    //CT 这里是Ajax的地方了
    var url = '/tools/action.aspx?act=apr';
		var pars = 's=';
		for(var index = 0; index != this._symbolArray.length; ++index)
		{
			if(index>0) pars+=',';
			pars+=this._symbolArray[index].getTicker();
		}
		var myAjax = new Ajax.Request(url, { method: 'post', parameters: pars, onFailure: this.PickupError, onSuccess: this.PickupComplete });
	}
};

QuotedApplication.prototype.refreshInterval = 2000;
QuotedApplication.prototype.PickupError = function(request)
{
	var qa=QuotedApplication.getCurrent();
	window.setTimeout(function() {qa.Pickup();}, 5*qa.refreshInterval);
};
QuotedApplication.prototype.onPickupComplete = null;
QuotedApplication.prototype.PickupComplete = function(request)
{
	//qa在这里不能用this,由event处理时直接调用
	var qa=QuotedApplication.getCurrent();
	try
	{
		var ans=eval('('+request.responseText+')');
		
		if (ans == null || ans.success == null || !ans.success)
		{
	  	LiveQuotes.writeTrace("PickupComplete: not a valaid rquest data", "pickup", 4);
			LiveQuotes.writeTrace(request.responseText, "pickup", 4);
		
			setTimeout(function() {qa.Pickup()}, 4*qa.refreshInterval);
			return;
		}
		
		LiveQuotes.writeTrace(ans.data.length + " items arrived", "pickup", 1);
		var matcheditem=false;
		for(var index = 0; index != ans.data.length; ++index)
		{
			var item = ans.data[index];
			
			var quotedSymbol = qa.LookupSymbol(item.symbol);
			
			if (quotedSymbol != null)
			{
				quotedSymbol.onPickup(item);
				matcheditem=true;
			}
		}
		if(qa.onPickupComplete!=null) qa.onPickupComplete(ans);
		
		if(matcheditem)
		{
			LiveQuotes.writeTrace("Sleeping for 1000 ms", "pickup", 1);
			window.setTimeout(function() {qa.Pickup();}, 1*qa.refreshInterval);
		}
	}
	catch(ex)
	{
		window.setTimeout(function() {qa.Pickup();}, 4*qa.refreshInterval);
	}
};

//*******************************************************************************************

function LiveQuotes()
{
	this._alreadysetup=false;
};

LiveQuotes.setup = function()
{
	if (!this._alreadysetup)
	{
		LiveQuotes.searchAndBindSpanElements();
		QuotedApplication.getCurrent().Pickup();
		this._alreadysetup=true;
	}
};

var blockedTickers = {"us:djia":0, "us:indu":0, "djia":0, "indu":0};

LiveQuotes.searchAndBindSpanElements = function()
{
	var app = QuotedApplication.getCurrent();

	var spanElements = document.getElementsByTagName("span");
	for(var index = 0; index != spanElements.length; ++index)
	{
		var spanElement = spanElements[index];
		var spanElementClassName = spanElement.className;

		if (spanElementClassName.toLowerCase() == "agglivequotes")
		{
			var ticker = spanElement.getAttribute("aggsymbol");
			if(blockedTickers[ticker.toLowerCase()] == 0)
				continue;
				
			var quotedSymbol = app.BindSymbol(ticker);
			var quotedElement = app.BindElement(spanElement);
			quotedElement.setSymbol(quotedSymbol);
		}
	}
};

LiveQuotes.getApplication = function()
{
	return QuotedApplication.getCurrent();
};

LiveQuotes.enableTrace = function(traceHandler)
{
    if (traceHandler == null)
    {
        LiveQuotes.enableTrace("html");
        return;
    }
    else if (typeof(traceHandler) == "string")
    {
        switch(traceHandler)
        {
            case "console":
            {
                if (window.dump != null)
                {
                    LiveQuotes._trace = function(message)
                    {                    
                        window.dump(message + "\n");
                    }
                }
                break;
            }
            case "html":
            {
                var style = document.createElement("link");
                style.rel = "stylesheet";
                style.type = "text/css";
                style.href = "";
                document.body.appendChild(style);

                var div = document.createElement("div");
                div.className = "aggtrace";
                document.body.appendChild(div);
                
                LiveQuotes._trace = function(message)
                {
                    var line = document.createElement("div");
                    line.innerHTML = message;
                    div.appendChild(line);
                };
                break;
            }
        }
    }
    else if (traceHandler.writeTrace != null)
    {
        LiveQuotes._trace = function(message)
        {
            traceHandler.writeTrace(message);
        };
    }
    
    LiveQuotes.writeTrace("Trace enabled", "system", 2);
};

LiveQuotes.disableTrace = function()
{
    LiveQuotes.writeTrace("Trace disabled", "system", 2);
    
    LiveQuotes._trace = null;
};

LiveQuotes._traceLevel = new Object();

LiveQuotes._traceLevel.all = 2;

LiveQuotes.setTraceLevel = function(category, severity)
{
    LiveQuotes._traceLevel[category] = severity;
    LiveQuotes.writeTrace("setTraceLevel " + category + "[" + severity + "]", "system", 4);
};

LiveQuotes.writeTrace = function(message, category, severity)
{
    if (LiveQuotes._trace)
    {
        if (LiveQuotes._traceLevel[category] <= severity ||
            LiveQuotes._traceLevel.all <= severity)
        {    
            LiveQuotes._trace(DateFormat.call(new Date(), "hh:nn:ss.sss ") + category + "[" + severity + "] " + message);
        }
    }
};

//*******************************************************************************************

function InstallLibrary(target)
{
	var t = target||window;
	t.AGGLiveQuotes = LiveQuotes;
};

InstallLibrary();
