///////////////////////////////////////////////////////////////////////////
// Copyright (c) 2005 MarketWatch, Inc. All rights reserved.
//
// Subject to terms and conditions located at 
// http://www.marketwatch.com/api/livequotes/termsconditions.html.
//
// NumberFormat portion of this softare is released to 
// the public domain without copyright, and can be used 
// without restriction. (http://mredkj.com/legal.html)
//


function LiveQuotesNamespace()
{


//////////////////////////////
// LiveQuotesGateway

function LiveQuotesGateway(endpoint)
{
	this._endpoint = endpoint;
};

LiveQuotesGateway.create = function(endpoint)
{
	var gateway;

	if (endpoint.indexOf("http") == 0)
	{
		gateway = new ScriptSrc_LiveQuotesGateway(endpoint);
	}
	else
	{
		gateway = new XmlHttp_LiveQuotesGateway(endpoint);
	}
	
	return gateway;
};

LiveQuotesGateway.prototype.getEndpoint = function()
{
	return this._endpoint;
};

LiveQuotesGateway.prototype.setEndpoint = function(endpoint)
{
	this._endpoint = endpoint;
};

LiveQuotesGateway.prototype.sendRequestResponse = function(address, callbackObject, callbackMethod, callbackState)
{
	//virtual
};

LiveQuotesGateway.prototype.Subscribe = function(proof, ticket, symbols, callback, state)
{
	var src = "/subscribe.js?";
	if (proof != null)
		src = src + "&proof=" + proof;

	if (ticket != null)
		src = src + "&ticket=" + ticket;
	
	src = src + "&referer=" + document.location.hostname;
	
	var parts = new Array();
	for(var index = 0; index != symbols.length; ++index)
	{
		var quotedSymbol = symbols[index];
		parts[index] = quotedSymbol.getItemId() + "=" + quotedSymbol.getTicker();
	}
	
	if (parts.length != 0)
		src = src + "&ticker=" + parts.join(",");

	this.sendRequestResponse(src, callback, callback.SubscribeComplete, state);
};

LiveQuotesGateway.prototype.Pickup = function(ticket, callback, state)
{
	var src = "/pickup.js?";

	if (ticket != null)
		src = src + "&ticket=" + ticket;

	this.sendRequestResponse(src, callback, callback.PickupComplete, state);
};

//////////////////////////////
// ScriptSrc_LiveQuotesGateway

function ScriptSrc_LiveQuotesGateway(endpoint)
{
	LiveQuotesGateway.call(this, endpoint);
};

ScriptSrc_LiveQuotesGateway.prototype = new LiveQuotesGateway;

ScriptSrc_LiveQuotesGateway._nonce = 1;

ScriptSrc_LiveQuotesGateway.prototype.sendRequestResponse = function(src, callbackObject, callbackMethod, callbackState)
{
	var nonce = ++ScriptSrc_LiveQuotesGateway._nonce;
//	var id = "ScriptSrc_LiveQuotesGateway_id" + nonce;
	var cb = "_lq_cb" + nonce;
	
	var scriptElement = document.createElement("script");
//	scriptElement.id = id;
	scriptElement.type = "text/javascript";
	scriptElement.src = this._endpoint + src + "&cb=" + cb;

	var appendComplete = false;
	var callbackComplete = false;
	var windowTimeout = null;
	
	window[cb] = function(response)
	{
		if (windowTimeout != null)
		{
			window.clearTimeout(windowTimeout);
			windowTimeout = null;
		}

		callbackComplete = true;
		if (appendComplete)
		{
			document.body.removeChild(scriptElement);
			window[cb] = null;
		}		
		
		try
		{
			callbackMethod.call(callbackObject, response, callbackState);
		}
		catch(ex)
		{
			/*
			try
			{
				var callException = new Object();
				callException.exception = new Object();
				callException.exception.message = "callback error";
				callbackMethod.call(callbackObject, callException, callbackState);
			}
			catch(ex2)
			{
			}
			*/
		};
	};

	windowTimeout = window.setTimeout(function()
		{
			if (window[cb] != null)
			{
				var response = new Object();
				response.exception = new Object();
				response.exception.message = "request timeout";
				window[cb](response);
			}
		}, 25000);

	document.body.appendChild(scriptElement);
	
	appendComplete = true;
	if (callbackComplete)
	{
		document.body.removeChild(scriptElement);
		window[cb] = null;
	}
};


//////////////////////////////
// XmlHttp_LiveQuotesGateway

function XmlHttp_LiveQuotesGateway(endpoint)
{
	LiveQuotesGateway.call(this, endpoint);
};

XmlHttp_LiveQuotesGateway.prototype = new LiveQuotesGateway;

XmlHttp_LiveQuotesGateway.nullFunction = function() 
{
};

XmlHttp_LiveQuotesGateway.prototype.sendRequestResponse = function(src, callbackObject, callbackMethod, callbackState)
{
    LiveQuotes.writeTrace(src, "gateway", 1);

	var xmlhttp = null;
	if (window.XMLHttpRequest)
	{
		xmlhttp = new XMLHttpRequest();
	}
	else if (window.ActiveXObject)
	{
		try
		{
			xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
		}
		catch(ex1)
		{
			xmlhttp = new ActiveXObject("Msxml2.XMLHTTP");
		};
	}

	var windowTimeout = null;

	xmlhttp.open("GET", this._endpoint + src + "&r=" + Math.random(), true);
	try
	{
	    xmlhttp.setRequestHeader("Cookie", "none");
	    xmlhttp.setRequestHeader("Cookie", "");
    } catch(ex) {};
	
	xmlhttp.onreadystatechange = function() 
	{
		if (xmlhttp.readyState==4)
		{
			if (windowTimeout != null)
			{
				window.clearTimeout(windowTimeout);
				windowTimeout = null;
			}

		    xmlhttp.onreadystatechange = XmlHttp_LiveQuotesGateway.nullFunction;
		    var responseText = xmlhttp.responseText;
		    xmlhttp = null;

			try
			{
			    LiveQuotes.writeTrace(responseText, "gateway", 1);
			    
				var response;
				try
				{
					response = eval('(' + responseText + ')');
				}
				catch(parseEx)
				{
					response = new Object();
					response.exception = new Object();
					response.exception.message = "parse error";
					try
					{
					    response.exception.detail = responseText;
					}catch(ex5){};
				};
				callbackMethod.call(callbackObject, response, callbackState);
			}
			catch(ex)
			{
			/*
				try
				{
					var callException = new Object();
					callException.exception = new Object();
					callException.exception.message = "callback error";
					callbackMethod.call(callbackObject, callException, callbackState);
				}
				catch(ex2)
				{
				}
			*/
			};
		}
    };

	windowTimeout = window.setTimeout(function()
		{
			if (windowTimeout != null)
			{
				windowTimeout = null;
				try
				{
					xmlhttp.onreadystatechange = XmlHttp_LiveQuotesGateway.nullFunction;
					xmlhttp.abort();
				}
				catch(ex5)
				{
				};
				xmlhttp = null;

				var timeoutResponse = new Object();
				timeoutResponse.exception = new Object();
				timeoutResponse.exception.message = "request timeout";
				try
				{
					callbackMethod.call(callbackObject, timeoutResponse, callbackState);
				}
				catch(ex3)
				{
				};
			}
		}, 25000);


    xmlhttp.send(null);
};


//////////////////////////////
// IFrame_LiveQuotesGateway

function IFrame_LiveQuotesGateway()
{
};

IFrame_LiveQuotesGateway.prototype = new LiveQuotesGateway;


/////////////////////////////
// QuotedSymbol

function QuotedSymbol(itemId, ticker)
{
	this._itemId = itemId;
	this._ticker = ticker;
	this._attached = new Array();
};

QuotedSymbol.StatusEnum = new Object();
QuotedSymbol.StatusEnum.Init = "Init";
QuotedSymbol.StatusEnum.Adding = "Adding";
QuotedSymbol.StatusEnum.Subscribed = "Subscribed";

QuotedSymbol.prototype._status = QuotedSymbol.StatusEnum.Init;

QuotedSymbol.prototype.getItemId = function() {return this._itemId;};
QuotedSymbol.prototype.getTicker = function() {return this._ticker;};
QuotedSymbol.prototype.getStatus = function() {return this._status;};

QuotedSymbol.prototype.setStatus = function(status) {this._status = status;};

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);
			}
		}
	}
};


// a global month names array
var gsMonthNames = new Array(
'January',
'February',
'March',
'April',
'May',
'June',
'July',
'August',
'September',
'October',
'November',
'December'
);

// a global day names array
var gsDayNames = new Array(
'Sunday',
'Monday',
'Tuesday',
'Wednesday',
'Thursday',
'Friday',
'Saturday'
);

// the date format prototype
function DateFormat(f)
{
    if (!this.valueOf())
        return '&nbsp;';

    //var d = this;
  
    function zf(val, places)
    {
        var result = "00" + val.toString();
        return result.substr(result.length - places, places);
    }
    
    var result = new String(f);
    result = result.replace("yyyy", this.getFullYear());
    result = result.replace("mmmm", gsMonthNames[this.getMonth()]);
    result = result.replace("mmm", gsMonthNames[this.getMonth()].substr(0, 3));
    result = result.replace("mm", zf((this.getMonth() + 1),2));
    result = result.replace("dddd", gsDayNames[this.getDay()]);
    result = result.replace("ddd", gsDayNames[this.getDay()].substr(0, 3));
    result = result.replace("dd", zf(this.getDate(),2));
    result = result.replace("hh", zf(((h = this.getHours() % 12) ? h : 12),2));
    result = result.replace("h", ((h = this.getHours() % 12) ? h : 12));
    result = result.replace("nn", zf(this.getMinutes(),2));
    result = result.replace("sss", zf(this.getMilliseconds(),3));
    result = result.replace("ss", zf(this.getSeconds(),2));
    result = result.replace("a/p", this.getHours() < 12 ? 'a' : 'p');
    result = result.replace("A/P", this.getHours() < 12 ? 'A' : 'P');
    
    return result;

    /*
    return f.replace(/(yyyy|mmmm|mmm|mm|dddd|ddd|dd|hh|nn|ss|a\/p)/gi,
        function($1)
        {
            switch ($1.toLowerCase())
            {
            case 'yyyy': return d.getFullYear();
            case 'mmmm': return gsMonthNames[d.getMonth()];
            case 'mmm':  return gsMonthNames[d.getMonth()].substr(0, 3);
            case 'mm':   return (d.getMonth() + 1).zf(2);
            case 'dddd': return gsDayNames[d.getDay()];
            case 'ddd':  return gsDayNames[d.getDay()].substr(0, 3);
            case 'dd':   return d.getDate().zf(2);
            case 'hh':   return ((h = d.getHours() % 12) ? h : 12).zf(2);
            case 'nn':   return d.getMinutes().zf(2);
            case 'ss':   return d.getSeconds().zf(2);
            case 'a/p':  return d.getHours() < 12 ? 'a' : 'p';
            }
        }
    );
    */
};

QuotedSymbol.prototype.Timestamp = function()
{
    var value = new Date(this._pickupItem.timestamp);
    value.format = DateFormat;
    return value;
};


QuotedSymbol.prototype.Name = function()
{
	return this._pickupItem.name;
};
QuotedSymbol.prototype.Price = function()
{
	return this._pickupItem.price;
};
QuotedSymbol.prototype.Volume = function()
{
	return this._pickupItem.volume;
};
QuotedSymbol.prototype.Change = function()
{
	return this._pickupItem.change;
};
QuotedSymbol.prototype.PercentChange = function()
{
	return this._pickupItem.percentchange;
};


/////////////////////////////
// QuotedElement

function QuotedElement(htmlElement)
{
	this._htmlElement = htmlElement;
	
	this._field = this._htmlElement.getAttribute("mwfield");
	if (this._field == null)
		this._field = "Price";

	this._format = this._htmlElement.getAttribute("mwformat");
	
	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;
	
	if (this._innerSpan == null)
	{
		this._innerSpan = document.createElement("span");
		this._htmlElement.innerHTML = "";
		this._htmlElement.appendChild(this._innerSpan);
	}
	
	var fieldValue = symbol[this._field]();
	var priceValue = symbol.Price();

	if (fieldValue > 0)
	{
		this._lastFieldClass = "up";
	}
	else if (fieldValue < 0)
	{
		this._lastFieldClass = "down";
	}
	else
	{
		this._lastFieldClass = "unchanged";
	}
	
	if (this._lastPrice != null)
	{
		if (this._lastPrice < priceValue)
		{
			this.setFlashTimeout();
			this._lastPriceClass = " tradeup";
		}
		else if (this._lastPrice > priceValue)
		{
			this.setFlashTimeout();
			this._lastPriceClass = " tradedown";
		}
	}   


	var fieldString = this.formatValue(fieldValue);
	
	
	if (this._innerSpan.innerHTML != fieldString)
		this._innerSpan.innerHTML = fieldString;
	if (this._innerSpan.className != this.getClassName())
		this._innerSpan.className = this.getClassName();
	this._lastPrice = priceValue;
	//this._htmlElement.innerHTML = symbol[this._field]().toString();
};

QuotedElement.prototype.formatValue = function(fieldValue)
{
	if (this._format == null || this._format == "")
		return fieldValue.toString();

    if (fieldValue.format != null)
    {
        return fieldValue.format(this._format);
    }

	var leadingPlus = "";
	var trailingPercent = "";
	
	var formatter = new NumberFormat(fieldValue);
	formatter.setCommas(false);
	for (var index = 0; index != this._format.length; ++index)
	{
		var formatChar = this._format.charAt(index);
		if (formatChar == ",")
		{
			formatter.setCommas(true);
		}
		else if (formatChar == "%")
		{
			trailingPercent = "%";
		}
		else if (formatChar == "+")
		{
			leadingPlus = "+";
		}
		else if (formatChar >= "0" && formatChar <= "9")
		{
			formatter.setPlaces(new Number(formatChar));
		}
	}
	
	if (formatter.toUnformatted() <= 0)
		leadingPlus = "";
	
	return leadingPlus + formatter.toFormatted() + trailingPercent;
};

QuotedElement.prototype.setFlashTimeout = function()
{
	if (this._flashTimeout != null)
	{
		window.clearTimeout(this._flashTimeout);
	}

	var thunk = this;
	this._flashTimeout = window.setTimeout(
		function()
		{
			thunk._flashTimeout = null;
			thunk._lastPriceClass = "";
			thunk._innerSpan.className = thunk.getClassName();
		}, 900);
};

QuotedElement.prototype.getClassName = function()
{
	return this._lastFieldClass + this._lastPriceClass;
};

/////////////////////////////
// QuotedApplication

function QuotedApplication()
{
	this._elementArray = new Array();
	this._symbolArray = new Array();
	this._endpoint = window["LiveQuotes_Endpoint"];
	this._proof = window["LiveQuotes_Proof"];
	this._ticket = null;

	this._gateway = LiveQuotesGateway.create(this._endpoint);
};

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() == ticker)
			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.Subscribe = function()
{
	var state = new Object();
	state.symbols = new Array();
	for(var index = 0; index != this._symbolArray.length; ++index)
	{
		var quotedSymbol = this._symbolArray[index];
		quotedSymbol.setStatus(QuotedSymbol.StatusEnum.Adding);
		state.symbols[state.symbols.length] = quotedSymbol;
	}

	this._gateway.Subscribe(this._proof, null, state.symbols, this, state);
};

QuotedApplication.prototype.SubscribeComplete = function(response, state)
{
	if (response == null || 
		response.exception != null)
	{
	    LiveQuotes.writeTrace("SubscribeComplete exception " + response.exception.message, "subscribe", 4);
	    if (response.exception.detail != null)
	        LiveQuotes.writeTrace(response.exception.detail, "subscribe", 4);

		var thunk = this;
		setTimeout(function() {thunk.Subscribe()}, 5000);
		return;
	}	
	
	if (response.proof != null)
	{
		this._proof = response.proof;

		LiveQuotes.writeTrace("New proof " + this._proof, "subscribe", 2);
	}

	if (response.ticket != null)
	{
		this._ticket = response.ticket;
		
		LiveQuotes.writeTrace("Obtained ticket " + this._ticket, "subscribe", 2);

		var img = document.getElementById("LiveQuoteLogo");
		if (img != null)
		{
			img.src = this._endpoint + "/activate.png?ticket=" + this._ticket + "&referer=" + document.location.hostname;
		}

		var scriptElement = document.createElement("script");
		scriptElement.type = "text/javascript";
		scriptElement.src = this._endpoint + "/activate.js?ticket=" + this._ticket + "&referer=" + document.location.hostname;
		document.body.appendChild(scriptElement);

		for(var index = 0; index != state.symbols.length; ++index)
		{
			var quotedSymbol = state.symbols[index];
			if (quotedSymbol.getStatus() == QuotedSymbol.StatusEnum.Adding)
				quotedSymbol.setStatus(QuotedSymbol.StatusEnum.Subscribed);
		}
		
		this.Pickup();
	}
};

QuotedApplication.prototype.Pickup = function()
{
    LiveQuotes.writeTrace("Sending pickup for " + this._ticket, "pickup", 1);
	this._gateway.Pickup(this._ticket, this);
};

QuotedApplication.prototype.PickupComplete = function(response)
{
	try
	{
		if (response == null || 
			response.exception != null)
		{
		    LiveQuotes.writeTrace("PickupComplete exception " + response.exception.message, "pickup", 4);
		    if (response.exception.detail != null)
		        LiveQuotes.writeTrace(response.exception.detail, "pickup", 4);
		    
			var thunk = this;
			setTimeout(function() {thunk.Subscribe()}, 4000);
			return;
		}

        LiveQuotes.writeTrace(response.items.length + " items arrived", "pickup", 1);
		for(var index = 0; index != response.items.length; ++index)
		{
			var item = response.items[index];
			var quotedSymbol = this._symbolArray[item.itemId];
			if (quotedSymbol != null)
				quotedSymbol.onPickup(item);
		}

        LiveQuotes.writeTrace("Sleeping for " + response.backoff + "ms", "pickup", 1);
		var thunk = this;
		window.setTimeout(function() {thunk.Pickup();}, response.backoff);
	}
	catch(ex)
	{
		this.Subscribe();
	}
};


/////////////////////////////
// LiveQuotes

function LiveQuotes()
{
};

LiveQuotes.setup = function()
{
	LiveQuotes.searchAndBindSpanElements();

	QuotedApplication.getCurrent().Subscribe();
};

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() == "mwlivequotes")
		{
			var ticker = spanElement.getAttribute("mwsymbol");
			
			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 = this.getApplication()._endpoint.replace("service.ashx", "trace.css");
                document.body.appendChild(style);

                var div = document.createElement("div");
                div.className = "mwtrace";
                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);
        }
    }
};

///////////////////////////
// InstallLibrary

function InstallLibrary(target)
{
	var t = target||window;
	t._LiveQuotes = LiveQuotes;
	t.MWLiveQuotes = LiveQuotes;
	t.DJLiveQuotes = LiveQuotes;
};

InstallLibrary();



///////////////////////
// NumberFormat154.js
///////////////////////

// mredkj.com
function NumberFormat(num, inputDecimal)
{
this.VERSION = 'Number Format v1.5.4';
this.COMMA = ',';
this.PERIOD = '.';
this.DASH = '-'; 
this.LEFT_PAREN = '('; 
this.RIGHT_PAREN = ')'; 
this.LEFT_OUTSIDE = 0; 
this.LEFT_INSIDE = 1;  
this.RIGHT_INSIDE = 2;  
this.RIGHT_OUTSIDE = 3;  
this.LEFT_DASH = 0; 
this.RIGHT_DASH = 1; 
this.PARENTHESIS = 2; 
this.NO_ROUNDING = -1 
this.num;
this.numOriginal;
this.hasSeparators = false;  
this.separatorValue;  
this.inputDecimalValue; 
this.decimalValue;  
this.negativeFormat; 
this.negativeRed; 
this.hasCurrency;  
this.currencyPosition;  
this.currencyValue;  
this.places;
this.roundToPlaces; 
this.truncate; 
this.setNumber = setNumberNF;
this.toUnformatted = toUnformattedNF;
this.setInputDecimal = setInputDecimalNF; 
this.setSeparators = setSeparatorsNF; 
this.setCommas = setCommasNF;
this.setNegativeFormat = setNegativeFormatNF; 
this.setNegativeRed = setNegativeRedNF; 
this.setCurrency = setCurrencyNF;
this.setCurrencyPrefix = setCurrencyPrefixNF;
this.setCurrencyValue = setCurrencyValueNF; 
this.setCurrencyPosition = setCurrencyPositionNF; 
this.setPlaces = setPlacesNF;
this.toFormatted = toFormattedNF;
this.toPercentage = toPercentageNF;
this.getOriginal = getOriginalNF;
this.moveDecimalRight = moveDecimalRightNF;
this.moveDecimalLeft = moveDecimalLeftNF;
this.getRounded = getRoundedNF;
this.preserveZeros = preserveZerosNF;
this.justNumber = justNumberNF;
this.expandExponential = expandExponentialNF;
this.getZeros = getZerosNF;
this.moveDecimalAsString = moveDecimalAsStringNF;
this.moveDecimal = moveDecimalNF;
this.addSeparators = addSeparatorsNF;
if (inputDecimal == null) {
this.setNumber(num, this.PERIOD);
} else {
this.setNumber(num, inputDecimal); 
}
this.setCommas(true);
this.setNegativeFormat(this.LEFT_DASH); 
this.setNegativeRed(false); 
this.setCurrency(false); 
this.setCurrencyPrefix('$');
this.setPlaces(2);
}
function setInputDecimalNF(val)
{
this.inputDecimalValue = val;
}
function setNumberNF(num, inputDecimal)
{
if (inputDecimal != null) {
this.setInputDecimal(inputDecimal); 
}
this.numOriginal = num;
this.num = this.justNumber(num);
}
function toUnformattedNF()
{
return (this.num);
}
function getOriginalNF()
{
return (this.numOriginal);
}
function setNegativeFormatNF(format)
{
this.negativeFormat = format;
}
function setNegativeRedNF(isRed)
{
this.negativeRed = isRed;
}
function setSeparatorsNF(isC, separator, decimal)
{
this.hasSeparators = isC;
if (separator == null) separator = this.COMMA;
if (decimal == null) decimal = this.PERIOD;
if (separator == decimal) {
this.decimalValue = (decimal == this.PERIOD) ? this.COMMA : this.PERIOD;
} else {
this.decimalValue = decimal;
}
this.separatorValue = separator;
}
function setCommasNF(isC)
{
this.setSeparators(isC, this.COMMA, this.PERIOD);
}
function setCurrencyNF(isC)
{
this.hasCurrency = isC;
}
function setCurrencyValueNF(val)
{
this.currencyValue = val;
}
function setCurrencyPrefixNF(cp)
{
this.setCurrencyValue(cp);
this.setCurrencyPosition(this.LEFT_OUTSIDE);
}
function setCurrencyPositionNF(cp)
{
this.currencyPosition = cp
}
function setPlacesNF(p, tr)
{
this.roundToPlaces = !(p == this.NO_ROUNDING); 
this.truncate = (tr != null && tr); 
this.places = (p < 0) ? 0 : p; 
}
function addSeparatorsNF(nStr, inD, outD, sep)
{
nStr += '';
var dpos = nStr.indexOf(inD);
var nStrEnd = '';
if (dpos != -1) {
nStrEnd = outD + nStr.substring(dpos + 1, nStr.length);
nStr = nStr.substring(0, dpos);
}
var rgx = /(\d+)(\d{3})/;
while (rgx.test(nStr)) {
nStr = nStr.replace(rgx, '$1' + sep + '$2');
}
return nStr + nStrEnd;
}
function toFormattedNF()
{	
var pos;
var nNum = this.num; 
var nStr;            
var splitString = new Array(2);   
if (this.roundToPlaces) {
nNum = this.getRounded(nNum);
nStr = this.preserveZeros(Math.abs(nNum)); 
} else {
nStr = this.expandExponential(Math.abs(nNum)); 
}
if (this.hasSeparators) {
nStr = this.addSeparators(nStr, this.PERIOD, this.decimalValue, this.separatorValue);
} else {
nStr = nStr.replace(new RegExp('\\' + this.PERIOD), this.decimalValue); 
}
var c0 = '';
var n0 = '';
var c1 = '';
var n1 = '';
var n2 = '';
var c2 = '';
var n3 = '';
var c3 = '';
var negSignL = (this.negativeFormat == this.PARENTHESIS) ? this.LEFT_PAREN : this.DASH;
var negSignR = (this.negativeFormat == this.PARENTHESIS) ? this.RIGHT_PAREN : this.DASH;
if (this.currencyPosition == this.LEFT_OUTSIDE) {
if (nNum < 0) {
if (this.negativeFormat == this.LEFT_DASH || this.negativeFormat == this.PARENTHESIS) n1 = negSignL;
if (this.negativeFormat == this.RIGHT_DASH || this.negativeFormat == this.PARENTHESIS) n2 = negSignR;
}
if (this.hasCurrency) c0 = this.currencyValue;
} else if (this.currencyPosition == this.LEFT_INSIDE) {
if (nNum < 0) {
if (this.negativeFormat == this.LEFT_DASH || this.negativeFormat == this.PARENTHESIS) n0 = negSignL;
if (this.negativeFormat == this.RIGHT_DASH || this.negativeFormat == this.PARENTHESIS) n3 = negSignR;
}
if (this.hasCurrency) c1 = this.currencyValue;
}
else if (this.currencyPosition == this.RIGHT_INSIDE) {
if (nNum < 0) {
if (this.negativeFormat == this.LEFT_DASH || this.negativeFormat == this.PARENTHESIS) n0 = negSignL;
if (this.negativeFormat == this.RIGHT_DASH || this.negativeFormat == this.PARENTHESIS) n3 = negSignR;
}
if (this.hasCurrency) c2 = this.currencyValue;
}
else if (this.currencyPosition == this.RIGHT_OUTSIDE) {
if (nNum < 0) {
if (this.negativeFormat == this.LEFT_DASH || this.negativeFormat == this.PARENTHESIS) n1 = negSignL;
if (this.negativeFormat == this.RIGHT_DASH || this.negativeFormat == this.PARENTHESIS) n2 = negSignR;
}
if (this.hasCurrency) c3 = this.currencyValue;
}
nStr = c0 + n0 + c1 + n1 + nStr + n2 + c2 + n3 + c3;
if (this.negativeRed && nNum < 0) {
nStr = '<font color="red">' + nStr + '</font>';
}
return (nStr);
}
function toPercentageNF()
{
nNum = this.num * 100;
nNum = this.getRounded(nNum);
return nNum + '%';
}
function getZerosNF(places)
{
var extraZ = '';
var i;
for (i=0; i<places; i++) {
extraZ += '0';
}
return extraZ;
}
function expandExponentialNF(origVal)
{
if (isNaN(origVal)) return origVal;
var newVal = parseFloat(origVal) + ''; 
var eLoc = newVal.toLowerCase().indexOf('e');
if (eLoc != -1) {
var plusLoc = newVal.toLowerCase().indexOf('+');
var negLoc = newVal.toLowerCase().indexOf('-', eLoc); 
var justNumber = newVal.substring(0, eLoc);
if (negLoc != -1) {
var places = newVal.substring(negLoc + 1, newVal.length);
justNumber = this.moveDecimalAsString(justNumber, true, parseInt(places));
} else {
if (plusLoc == -1) plusLoc = eLoc;
var places = newVal.substring(plusLoc + 1, newVal.length);
justNumber = this.moveDecimalAsString(justNumber, false, parseInt(places));
}
newVal = justNumber;
}
return newVal;
} 
function moveDecimalRightNF(val, places)
{
var newVal = '';
if (places == null) {
newVal = this.moveDecimal(val, false);
} else {
newVal = this.moveDecimal(val, false, places);
}
return newVal;
}
function moveDecimalLeftNF(val, places)
{
var newVal = '';
if (places == null) {
newVal = this.moveDecimal(val, true);
} else {
newVal = this.moveDecimal(val, true, places);
}
return newVal;
}
function moveDecimalAsStringNF(val, left, places)
{
var spaces = (arguments.length < 3) ? this.places : places;
if (spaces <= 0) return val; 
var newVal = val + '';
var extraZ = this.getZeros(spaces);
var re1 = new RegExp('([0-9.]+)');
if (left) {
newVal = newVal.replace(re1, extraZ + '$1');
var re2 = new RegExp('(-?)([0-9]*)([0-9]{' + spaces + '})(\\.?)');		
newVal = newVal.replace(re2, '$1$2.$3');
} else {
var reArray = re1.exec(newVal); 
if (reArray != null) {
newVal = newVal.substring(0,reArray.index) + reArray[1] + extraZ + newVal.substring(reArray.index + reArray[0].length); 
}
var re2 = new RegExp('(-?)([0-9]*)(\\.?)([0-9]{' + spaces + '})');
newVal = newVal.replace(re2, '$1$2$4.');
}
newVal = newVal.replace(/\.$/, ''); 
return newVal;
}
function moveDecimalNF(val, left, places)
{
var newVal = '';
if (places == null) {
newVal = this.moveDecimalAsString(val, left);
} else {
newVal = this.moveDecimalAsString(val, left, places);
}
return parseFloat(newVal);
}
function getRoundedNF(val)
{
val = this.moveDecimalRight(val);
if (this.truncate) {
val = val >= 0 ? Math.floor(val) : Math.ceil(val); 
} else {
val = Math.round(val);
}
val = this.moveDecimalLeft(val);
return val;
}
function preserveZerosNF(val)
{
var i;
val = this.expandExponential(val);
if (this.places <= 0) return val; 
var decimalPos = val.indexOf('.');
if (decimalPos == -1) {
val += '.';
for (i=0; i<this.places; i++) {
val += '0';
}
} else {
var actualDecimals = (val.length - 1) - decimalPos;
var difference = this.places - actualDecimals;
for (i=0; i<difference; i++) {
val += '0';
}
}
return val;
}
function justNumberNF(val)
{
newVal = val + '';
var isPercentage = false;
if (newVal.indexOf('%') != -1) {
newVal = newVal.replace(/\%/g, '');
isPercentage = true; 
}
var re = new RegExp('[^\\' + this.inputDecimalValue + '\\d\\-\\+\\(\\)eE]', 'g');	
newVal = newVal.replace(re, '');
var tempRe = new RegExp('[' + this.inputDecimalValue + ']', 'g');
var treArray = tempRe.exec(newVal); 
if (treArray != null) {
var tempRight = newVal.substring(treArray.index + treArray[0].length); 
newVal = newVal.substring(0,treArray.index) + this.PERIOD + tempRight.replace(tempRe, ''); 
}
if (newVal.charAt(newVal.length - 1) == this.DASH ) {
newVal = newVal.substring(0, newVal.length - 1);
newVal = '-' + newVal;
}
else if (newVal.charAt(0) == this.LEFT_PAREN
&& newVal.charAt(newVal.length - 1) == this.RIGHT_PAREN) {
newVal = newVal.substring(1, newVal.length - 1);
newVal = '-' + newVal;
}
newVal = parseFloat(newVal);
if (!isFinite(newVal)) {
newVal = 0;
}
if (isPercentage) {
newVal = this.moveDecimalLeft(newVal, 2);
}
return newVal;
}

///////////////////////
// NumberFormat154.js
///////////////////////

};


LiveQuotesNamespace();
