var blinkingFields = new Array();
var quoteFields = new Array();
		 
var quoteFormatters = new Array();
	//Market Hours
	quoteFormatters['fxprc'] = fieldFXPriceFormatter;
	quoteFormatters['fxbid'] = fieldFXPriceFormatter;
	quoteFormatters['fxask'] = fieldFXPriceFormatter;
	quoteFormatters['fxperchg'] = fieldFXPercentagefieldChangeFormatter;
	quoteFormatters['fxchg'] = fieldFXChangeFormatter;
	quoteFormatters['fxhigh'] = fieldFXPriceFormatter;
	quoteFormatters['fxlow'] = fieldFXPriceFormatter;
	
	quoteFormatters['prc'] = fieldPriceFormatter;
	
	quoteFormatters['chg'] = fieldChangeFormatter;
	quoteFormatters['perchg'] = fieldPercentagefieldChangeFormatter;
	quoteFormatters['vol'] = fieldVolumeFormatter;
	quoteFormatters['high'] = fieldPriceFormatter;
	quoteFormatters['low'] = fieldPriceFormatter;
	quoteFormatters['bid'] = fieldPriceFormatter;
	quoteFormatters['ask'] = fieldPriceFormatter;
	quoteFormatters['vvperchg'] = fieldPercentagefieldChangeFormatter;
	//After Hours
	quoteFormatters['ahprc'] = fieldPriceFormatter;
	quoteFormatters['ahchg'] = fieldChangeFormatter;
	quoteFormatters['ahperchg'] = fieldPercentagefieldChangeFormatter;
	quoteFormatters['ahvol'] = fieldVolumeFormatter;
	
	//Options
	quoteFormatters['uprc'] = fieldPriceFormatter;
	quoteFormatters['stk'] = fieldPriceFormatter;
	quoteFormatters['dlo'] = fieldPriceFormatter;
	quoteFormatters['rco'] = fieldPercentagefieldChangeFormatter;
	quoteFormatters['ccr'] = fieldPercentagefieldChangeFormatter;
	quoteFormatters['delta'] = fieldPriceFormatter;
	quoteFormatters['gamma'] = fieldPriceFormatter;
	quoteFormatters['theta'] = fieldPriceFormatter;
	quoteFormatters['vega'] = fieldPriceFormatter;
	quoteFormatters['rho'] = fieldPriceFormatter;
	quoteFormatters['intrval'] = fieldPriceFormatter;
	quoteFormatters['openint'] = fieldVolumeFormatter;
	quoteFormatters['tval'] = fieldPriceFormatter;
	quoteFormatters['impvol'] = fieldPercentageFormatter;
	quoteFormatters['overvalba'] = fieldPercentageFormatter;
	quoteFormatters['overvalvol'] = fieldPercentageFormatter;

var updateFrequencyMillis = -1;

if((typeof ajaxQuotes_updateInterval)+"" != ""+undefined){
	updateFrequencyMillis = ajaxQuotes_updateInterval;
}

function setBasicQuotes(on){
	savePreference("Quotes_basicView", on);
	ajaxQuotes_quotesBasic = on;
}
function setAdvancedQuotes(on){
	savePreference("Quotes_detailedView", on);
	ajaxQuotes_quotesDetailed = on;
}

var quoteArea = document.getElementById("searchResults_container");
if(quoteArea == null) quoteArea = document;
var blinkRate = 600;
var quotesOn = (updateFrequencyMillis > 4000);;
var requestid = 0;
var messageNumber = 0;
var curMarketState = "";
var isMarketOpen = true;

var quotesActiveReq = null;
var timer = null;

var QuoteManager = new Object();
QuoteManager.Quote = function(symbol, fields) {
	this.symbol = symbol;
	if(QuoteManager.quotes == null)
		QuoteManager.quotes = new Array();
	QuoteManager.quotes[symbol] = this;
	if(fields == null){
	this.fields = new Array();
		for(var i = 0; i < quoteFields.length; i++){
			var field = new QuoteManager.Quote.Field(symbol, quoteFields[i], quoteFormatters[i]);
			if(field.elements.length > 0)
				this.fields.push(field);
		}
	}else
		this.fields = fields;
}
var once = true;
QuoteManager.Quote.Field = function(symbol, name, formatter, element){
	this.formatter = formatter;
	this.name = name;
	this.symbol = symbol;
	if(element == null){
		this.elements = quoteArea.getElementsByName(name+'_'+symbol);
	}else{
		this.elements = new Array();
		this.elements.push(element);
	}
}
QuoteManager.Quote.Field.prototype = {

	update:function(valuesXML) {
		var val = getFieldValue(attbs, this.name);
		for(var i = 0; i < this.elements.length; i++){
			if(this.elements[i].onQuoteChange == null){
				updateField(this.elements[i], val, this.formatter);
			}else{
				this.element.onQuoteChange.call(this, this, val);
			}
		}
	}
}
function updateTheField(field, attbs){
		var val = getFieldValue(attbs, field.name);
		
		if(field.elements == null) return;
		for(var i = 0; i < field.elements.length; i++){
			if(field.elements[i].onQuoteChange == null){
				updateField(field.elements[i], val, field.formatter);
			}else{
				field.element.onQuoteChange.call(field, field, val);
			}
		}
}
var firstquotes = 5;
//var lastquote = -1;
function getQuote(symbol){
	return QuoteManager.quotes[symbol];
}
function updateQuote(quoteXML, index){
	attbs = quoteXML.attributes;
	var symbol = "";
	attbs = quoteXML.attributes;
	var symbolNode = attbs.getNamedItem('symbol');
	if(symbolNode == null) 	return;
	else symbol = symbolNode.value;
	var quote = getQuote(symbol);
	if(quote == null){ 
		return;
	}
	for(var f = 0; f < quote.fields.length; f++){
		quote.fields[f].update(attbs);
	}
}
function updateField(element, newValue, formatter){
	if(element.value == null || element.value+"" == "undefined"){
		element.value = element.getAttribute("value");
	}
	if(element.value != newValue){
		element.lastValue = element.value;
		element.value = newValue;
		cField = element;
		formatter.call(this, element);
		var currentValue = parseFloat(element.value);
		if(currentValue == "NaN") return;
		var lastValue = parseFloat(element.value);
		if(element.lastValue != null){
			lastValue = parseFloat(element.lastValue);
		}
		var dif = currentValue - lastValue;
		if(dif != 0){
			var bgc;
		    if (dif > 0) {
		        bgc = '#ccffcc';
		    } else if (dif < 0) {
		        bgc = '#efcccc';
		    }
		    if (lastValue==0&&currentValue>0){
		    	element.className = element.className + " greenText";
		    	//set to black
		    } else if (lastValue==0&&currentValue<0){
		    	element.className = element.className + " redText";
		    	//set to black
		    } else if (lastValue<0&&currentValue==0){
		    	element.className = element.className.replace("redText", "");
		    	//set to black
		    } else if (lastValue>0&&currentValue==0){
		    	element.className = element.className.replace("greenText", "");
		    	//set to green
		    } else if (lastValue<0&&currentValue>0){
		    	element.className = element.className.replace("redText", "greenText");
		    	//set to green
		    } else if (lastValue>0&&currentValue<0){
		    	element.className = element.className.replace("greenText", "redText");
		    	//set to red
		    }
			blinkField(bgc, element)
		}
	}
}
function getFieldValue(attbs, attribute){
	if(attbs == null) return "N/A";
	if(attribute == null || attribute == "") return "N/A";
	var attr = attbs.getNamedItem(attribute);
	if(attr == null)
		return "N/A";
	else
		return attr.value;
}
var blinking = false;
function blinkField(bgc, element){
	blinking = true;
	element.style.backgroundColor = bgc;
	blinkingFields.push(element);
}
function unblinkField(){
	if (blinking){
		blinking = false;
		for (var i = 0; i < blinkingFields.length; i++){
			blinkingFields[i].style.backgroundColor = '';
		}
	}
	blinkingFields.length=0;
	return;
}
function formatField(target, v){
	if(target != null){
	    if(v.indexOf("NaN") > -1) v = "N/A";
		target.innerHTML = v;
	}
	return v;
}
function fieldChangeFormatter(element){
	var numericValue = parseFloat(cField.value);
    return formatField(element, signNumber(numericValue.toFixed(2)));
}
function fieldFXChangeFormatter(element){
	var numericValue = parseFloat(cField.value);
    return formatField(element, signNumber(numericValue.toFixed(4)));
}
function signNumber(number) {
    if (number > 0) {
        return '+' + number;
    } else {
        return number;
    }
}
function commatizeNumber(nStr) {
    nStr += '';
    x = nStr.split('.');
    x1 = x[0];
    x2 = x.length > 1 ? '.' + x[1] : '';
    var rgx = /(\d+)(\d{3})/;
    while (rgx.test(x1)) {
        x1 = x1.replace(rgx, '$1' + ',' + '$2');
    }
    return x1 + x2;
}
function fieldVolumeFormatter(element){
	var numericValue = parseFloat(element.value);
    return formatField(element, commatizeNumber(numericValue.toFixed(0)));
}
function fieldPriceFormatter(element){
	var currentValue = parseFloat(element.value);
    return formatField(element, currentValue.toFixed(2));
}
function fieldFXPriceFormatter(element){
	var currentValue = parseFloat(element.value);
    return formatField(element, currentValue.toFixed(4));
}
function fieldPercentagefieldChangeFormatter(element){
	var numericValue = parseFloat(element.value);
    return formatField(element, signNumber(numericValue.toFixed(2)) + '%');
}
function fieldFXPercentagefieldChangeFormatter(element){
	var numericValue = parseFloat(element.value);
    return formatField(element, signNumber(numericValue.toFixed(4)) + '%');
}
function fieldPercentageFormatter(element){
	var numericValue = parseFloat(element.value);
	numericValue = numericValue * 100;
    return formatField(element, numericValue.toFixed(2) + '%');
}
function getFieldChangeClass(numericValue) {
    var changeClass = '';
    if (numericValue > 0) {
        changeClass = 'greenText';
    } else if (numericValue < 0) {
        changeClass = 'redText';
    }
    return changeClass;
}

function showDebug(message){
	messageNumber++;
	document.getElementById('resultSize').innerHTML = "Message #"+messageNumber+" "+message;
}
function isArray(obj){ 
	return(obj.constructor.toString().indexOf("Array")!=-1); 
}
var windupIndex = 0;
var quoteSymbols = new Array();
var domElements = new Array();

function startQuotes(theQuoteInfo, theUpdateFrequencyMillis){
	if(theQuoteInfo.length < 1 || theUpdateFrequencyMillis < 0){
		quotesOn = false;
		return;
	}
	var start = false;
	
	QuoteManager.QuoteInfo = theQuoteInfo;
		
	elements = getElementSet("CQ", 'span');
	for(var e = 0; e < elements.length; e++){
		var id = elements[e].getAttribute("name");
		if(id != null && id.length > 0){
			if (!domElements[id]){
				domElements[id] = new Array();
				domElements[id][0] = elements[e];
			} else {
				domElements[id][domElements[id].length] = elements[e];
			}
		}
	}
	
	if(theUpdateFrequencyMillis != null)
		changeIntervalTimer(theUpdateFrequencyMillis);
	windup();
}
function windup(){
	if(windupIndex >= quoteSymbols.length){
		if(timer == null)
			timer = setInterval(getQuoteValues, updateFrequencyMillis);
		started = true;
		return;
	}
	var windupseg = windupIndex + 25;
	for(var i = windupIndex; i < quoteSymbols.length && i < windupseg; i++){
		windupIndex++;
	}
	setTimeout(windup, 150);
}
function startQuotesPreBuilt(){
	if(QuoteManager.quotes.length < 1){
		quotesOn = false;
		return;
	}
	var start = false;
	if(timer == null){
		timer = setInterval(getQuoteValues, updateFrequencyMillis);
	}
	started = true;
}
function setQuotesPaused(pause){
	quotesOn = !pause;
}
function changeIntervalTimer(theUpdateFrequencyMillis){
	blinkRate = 1000;
	updateFrequencyMillis = 5000;
	if (theUpdateFrequencyMillis!=null) updateFrequencyMillis = theUpdateFrequencyMillis;
	if (blinkRate >= updateFrequencyMillis) blinkRate = updateFrequencyMillis;
	quotesOn = (updateFrequencyMillis > 4000);
	setQuotesPaused(updateFrequencyMillis < 1000);
	if(timer != null){
		clearInterval(timer);
		timer = setInterval(getQuoteValues, updateFrequencyMillis);
	}
	
}
function changeUpdateInterval(selectID){
	var newInterval = getSelectedValue(selectID);
	changeIntervalTimer(newInterval * 1000);
	savePreference("Quotes_updateInterval", newInterval);
}
var quoteOverride = null;
function getQuoteValues(){
	if(!quotesOn) return;
	if(quoteOverride != null && !quoteOverride.call(this)) return;
	if(quotesActiveReq != null) return;
	
	requestid += 1;
	var xml = "<"+"request name='getQuotes' reqid='"+requestid+"' interval='"+updateFrequencyMillis+"'>";
	for (var i=0; i<QuoteManager.QuoteInfo.length; i++){
		var curSet = QuoteManager.QuoteInfo[i];
		var fields = curSet['fields'];
		var symbols = curSet['symbols'];
		var hasAfterHours = curSet['afterhours'];
		//if (!hasAfterHours && !isMarketOpen) continue;
		xml += "<QuoteSet>";
		xml += "<Fields>";
		for (var f=0; f<fields.length; f++){
			xml += "<"+fields[f]+"/>";
		}
		xml += "</Fields>";
		xml += "<Symbols>";
		for (var s=0; s<symbols.length; s++){
			xml += "<s v='"+escape(symbols[s])+"'/>";
		}
		xml += "</Symbols>";
		xml += "</QuoteSet>";
	}
	xml += "<"+"/request>";
	quotesActiveReq = new CATS.RequestMaker(contextPath + '/ajaxbridge/quotes.iedu', 
		updateFieldQuotes, null, xml, false, null);
	quotesActiveReq.loadXMLDoc();
}
var updateContainer = document.getElementById("quoteUpdateTime");
var quotecounter = 0;
var quoteQue = new Array();
var setsize = 1;
var sets = 0;

function continueUpdate(){
	if(quotecounter >= quoteQue.length){
		sets = 0;
		quoteQue = new Array();
		setTimeout(unblinkField, blinkRate);
		quotesActiveReq = null;
		if(updateContainer == null)
			updateContainer = document.getElementById("quoteUpdateTime");
		
		if(updateContainer != null){
			var d = new Date();
			updateContainer.innerHTML = "Quotes last updated at: " + d.toString();
		}
		return;
	}else{
		if(sets == 10){
			unblinkField();
			sets = -1;
		}
		sets++
		var quoteseg = quotecounter + setsize;
		for(; quotecounter < quoteQue.length && quotecounter < quoteseg; quotecounter++){
			updateQuote(quoteQue[quotecounter]);
		}
	}
	setTimeout(continueUpdate, 10);
}
		
function updateFieldQuotes(){
	var quotesArray = new Array();
	if(quotesActiveReq == null) return;
	if(blinking) unblinkField();
	var xml = this.req.responseXML;
	var mainresponse = xml.getElementsByTagName("response");
	if(mainresponse.length == 0){
	 	quotesActiveReq = null;
		return;
	}
	mainattbs = mainresponse[0].attributes;
	var market = mainattbs.getNamedItem("market");
	if (market!=null && curMarketState!=market.value){
		var marketState = market.value;
		var fQPAH = document.getElementById("fullQuotePanelAfterHours");
		var mQPAH = document.getElementById("miniQuotePanelAfterHours");
		if (marketState=="o"){
			isMarketOpen = true;
			if (fQPAH) fQPAH.style.display = 'none';
			if (mQPAH) mQPAH.style.display = 'none';
		} else {
			isMarketOpen = false;
			var marketText = (marketState=="a")? "After Hours" : "Pre Market";
			var mQPOMT = document.getElementById("mQPoffMarketText");
			var fQPOMT = document.getElementById("fQPoffMarketText");
			if (mQPOMT) mQPOMT.innerHTML = marketText;
			if (fQPOMT) fQPOMT.innerHTML = marketText;
			if (fQPAH) fQPAH.style.display = 'block';
			if (mQPAH) mQPAH.style.display = 'block';
		}
		curMarketState = marketState;
	}
	
	var reqId = mainattbs.getNamedItem('reqid');
	var quotes = xml.getElementsByTagName("quote");
	for(var i=0; i<quotes.length; i++){
		var quote = quotes[i];
		var symbolNode = quote.attributes.getNamedItem('symbol');
		if(symbolNode == null) 	continue;
		var symbol = unescape(symbolNode.value);
		var fields = quote.childNodes;
		for (var f=0; f<fields.length; f++){
			var tag = fields[f];
			var field = tag.tagName;
			var value = tag.attributes.getNamedItem("v").value;
			var domElement = field+"_"+symbol;
			if (!domElements[domElement]){
				continue;
			}
			for (var e=0; e<domElements[domElement].length; e++){
				updateField(domElements[domElement][e], value, quoteFormatters[field]);
			}
		}
	}
		
	setTimeout(unblinkField, blinkRate);
	quotesActiveReq = null;
	xml = null;
	if(updateContainer == null)
		updateContainer = document.getElementById("quoteUpdateTime");
	
	if(updateContainer != null){
		var d = new Date();
		updateContainer.innerHTML = "Quotes last updated at: " + d.toString();
	}
}