/**
 * String.prototype.namespace()
 * http://www.prototypejs.org/api/enumerable/inject
 * http://ajaxian.com/archives/namespaced-made-easy-with-prototype
 *
 * Creates an object namespace chain extended from $object
 * and delimited by the $separator.
 * 
 * @param object $object
 * @param string $separator
 * @return void
 */
 
 /*
OLD CODE
String.prototype.namespace = function(object, separator) {
	this.split(separator || '.').inject(object||window, function(parent, child) {
		return parent[child] = parent[child] || { };
	});
};
*/

String.prototype.namespace = function(separator) {
    var ns = this.split(separator || '.'), p = window;
    for (i = 0; i < ns.length; i++) {
        p = p[ns[i]] = p[ns[i]] || {};
    }
};

"globe.data.stocks".namespace();

var $g = globe.data.stocks;

// external formatting control - vp
if (typeof formatValuesIsOn == 'undefined') formatValuesIsOn = 0;

/**
 * Solves cross-domain AJAX calls by faking them using dynamically
 * generated <script> tags.
 *
 * Author: Jack Hsu
 *
 * @param string $url The request URL.
 * @param function $callback The callback function.
 * @return void
 */

$g.CrossDomainRequest = function ( url, callback ) {
	// Add script element
	var script = document.createElement('script');
	script.src = url;
	script.type = 'text/javascript';
	document.getElementsByTagName('head')[0].appendChild(script);
	
	// Check if script has loaded
	var wait = function () {
		if( typeof $g.menuItems == 'undefined' && typeof $g.data.quote == 'undefined' ) { window.setTimeout( wait, 500 ); }
		else {
			// Execute callback function
			callback();
			
			// Remove script elemented
			document.getElementsByTagName('head')[0].removeChild(script);
			$g.data.quote = undefined;
			$g.menuItems = undefined;
		}
	}
	
	wait();
};

$g.report_is_loaded = {};
$g.default_update_seconds = 5;
$g.all_report_mask = 7; // 3 reports
$g.data = {};
$g.app_time;
$g.isReload = true;
$g.img_base = "/v5/data/stocks/images/";  
$g.total_width = 100;

$g.report_url_arr = {
	financial: "/servlet/Page/document/v5/data/stocks/quote/financial",
	competitor: "/servlet/Page/document/v5/data/stocks/quote/competitor_data",
	earning: "/servlet/Page/document/v5/data/stocks/quote/earning",
	quote:"/servlet/Page/document/v5/data/stocks/quote/quote_data",
	intraday_activity: "/servlet/Page/document/v5/data/stocks/quote/activity_data"
};

$g.find_out_more = {
	chart: "/invest/investSQL/gx.show_chart?iaction=Generate&pl_period=12D&pl_primary_listing=",
	financial: "/invest/investSQL/gx.company_prof?company_id="
};

$g.report_code_arr = {
	financial: 1,
	competitor: 2,
	earning: 4
};

$g.return_types = {
	return_intra: "Intraday",
	return_1wk: "1 week",
	return_1qtr: "3 months",
	return_1yr: "1 year"
};

$g.closeMessage = function () { 
    new Effect.Fade("changeSymbolError", { duration: 1, from: 0.93, to:0 } );
    $("stock_list").focus();
};

$g.validateSymbol = function () {
	var symbols = $("stock_list") ? $F("stock_list").replace(/,/g, " ").replace(/\s\s+/g," ").split(" ") : $F("pi_exchange").replace(/,/g, " ").replace(/\s\s+/g," ").split(" ");
	var symbol = symbols[0];
	var previous_symbol = $("changeSymbolForm").previousSymbol.value;
	
	$("changeSymbolForm").disable();
	
	new Ajax.Request( "/servlet/Page/document/v5/data/stocks/symbol_check", {
    method: "GET",
	parameters: { symbols: symbols.join(",") },
    onSuccess: function( transport ) {
        $("changeSymbolForm").enable();
       var response = transport.responseText.evalJSON();
        var index;
        var numTests = $g.current_page == "Basic Chart" || $g.current_page == "Interactive Chart" ? response.length : 1;
        for ( index=0; index<numTests; ++index ) {
            var q = response[index];
            if ( q.symbols.length > 1 ) {
                $("stock_list").addClassName("error").focus();
                $("errorMessage").update("Multiple symbols found for "+q.query+". Symbols found: "+q.symbols.join(", ")+".");
								//try {
									TransparentMenu.show( "changeSymbolError", { 
                    insideElement: { id: "changeSymbol", height: 50 }, showEffectOptions: { duration: 1, from: 0, to: 0.93 }, showMode: null, hideMode: "none"
									} );
								//}
								//catch (err) {}
                break;
            } else if ( q.symbols.length === 0 ) {
                $("stock_list").addClassName("error").focus();
                $("errorMessage").update("Symbol "+q.query+" was not found. Try symbol lookup.");
								//try {
									TransparentMenu.show( "changeSymbolError", { 
                    insideElement: { id: "changeSymbol", height: 50 }, showEffectOptions: { duration: 1, from: 0, to: 0.93 }, showMode: null, hideMode: "none"
									} );
								//}
								//catch (err) {}
                break;
            } // if
        } // for
        
        if (index == numTests) {
            var forwardUrl = window.location.href.replace(/&symbols=[^&]*/,"");
                        
            var regex = /(.+\?id=)([^&]+)(.*)/;
            var matches = regex.exec(forwardUrl);
            
            if ( $g.current_page == "Basic Chart" || $g.current_page == "Interactive Chart" ) {
                window.location = matches[1] + symbol + ( symbols.length > 0 ? "&other="+symbols.splice(1,2).join(",") : "" );
            } else if ( $g.current_page == "summary" ) {
                window.location = matches[1] + symbol + "&previousSymbol="+previous_symbol;
            } else {
                window.location = matches[1] + symbol + matches[3];
           }
        }

    },
    onFailure: function(){ }
  } ); // Ajax.Request
};

$g.displayData = function (divId, id, content) {
    if (id == "competitor"){
       $g.createCompetitorReport(divId,"return_intra",content);  
       $g.report_is_loaded[id] = true; 
    } else if ( id == "quote" ){
       $g.displayQuote(content.quote); 
   
        var query_time = content.queryTime; //dd/MM/yyyy HH:mm
        var query_hour = (query_time  && query_time.length == 16) ? query_time.substring(11,13) : null;
        
        if ( query_hour  && eval(query_hour) >= 17 ) {
            $g.isReload = false; 
        } 
    } else if ( id == "intraday_activity" ) {
        $g.displayActivity("intraday_activity", content);
    } else if ( content ){
    	$(divId).innerHTML = content; 
    	$g.report_is_loaded[id] = true; 
    } // if
};

$g.getDataFromRequest = function (divId, id, myurl, isParse, params) {
    new Ajax.Request( myurl, {
    method: "GET",
    parameters: params,
    onSuccess: function( transport ) {
        var response = transport.responseText;
				//alert(response);
        if ( isParse ){
            $g.displayData(divId, id, eval(response)); 
        } else {
            $g.displayData(divId, id, response); 
        }
    },
    onFailure: function(){ }
    } ); // Ajax.Request
};

$g.getReport = function (id, divId) {
	divId = id + "_rpt" || divId;
	
	// parameters for AJAX request calls
	var params = {};
	var isParse = true;
	var el;
	
	if (id == "competitor") {
		el = id + "_rpt";
		
		params.listing_id = $g.quote_params.listing_id;
		params.lang = $g.quote_params.lang;
		
	} else if (id == "quote" || id == "intraday_activity") {
		var now = new Date();
		
		el = divId;
		// HACK: check if this is a database page
		if ( id == "quote" && $( d.getElementsByTagName("body")[0] ).hasClassName("db") ) {
			params.pi_symbol = $g.quote_params.symbol + "-" + $g.quote_params.exchange_code;
			params.pi_ord = now.getTime();
		} else {
			params.symbol = $g.quote_params.symbol + "-" + $g.quote_params.exchange_code;
			params.listing_id = $g.quote_params.listing_id;
			params.ord = now.getTime();
		}
		
	} else if (id == "financial") {
	
		$(divId).innerHTML = 'Loading content...';
		
		el = divId;
		
		params.symbol = $g.quote_params.symbol;
		params.exchange_code = $g.quote_params.exchange_code;
		params.lang = $g.quote_params.lang;
		params.company_id = $g.quote_params.company_id;
		
		isParse = false;
		
	} else if (id == "earning") {
		
		$(divId).innerHTML = 'Loading content...';
		
		el = divId;
		
		params.symbol = $g.quote_params.symbol + "-" + $g.quote_params.exchange_code;
		params.company_id = $g.quote_params.company_id;
		
		isParse = false;
	} // if
		
	$g.getDataFromRequest(el, id, $g.report_url_arr[id], isParse, params);
};

$g.hideShowReport = function (report_name,v) {
    var ctrl_arr;
    var rpt_obj = $(report_name + "_rpt"); 
    var rpt_action_obj = $(report_name + "_hideshow");
    
    v = v || rpt_action_obj.alt;
    
    if( v == "hide" ){
        ctrl_arr = ["none","Show","/icon-plus-grey.gif"];
        $g.quote_report_mask = $g.quote_report_mask &( $g.all_report_mask ^ $g.report_code_arr[report_name]);
    } else {
        if ( !$g.report_is_loaded[report_name] ){ $g.getReport(report_name); }
        
        ctrl_arr = ["","Hide","/icon-minus-grey.gif"];
        $g.quote_report_mask = $g.quote_report_mask | $g.report_code_arr[report_name];
    }
    rpt_obj.style.display = ctrl_arr[0];
    rpt_action_obj.alt = ctrl_arr[1].toLowerCase();
    rpt_action_obj.title = ctrl_arr[1] + " this data block";
    
    var src = rpt_action_obj.src;    
    rpt_action_obj.src = src.substring( 0, src.lastIndexOf("/") ) + ctrl_arr[2];
    
    setCookie( "quote_report_mask", $g.quote_report_mask );
};

$g.calSize = function (valArr) {
   var max_value = 0, min_value = 0, cur_value = 0; 
    
   max_value = valArr[0];
   min_value = valArr[0];   
   for (var i=1; i < valArr.length; i++){
      cur_value = (valArr[i] == "-") ? 0: eval(valArr[i]); 
      if (cur_value > max_value) { max_value = cur_value; }
      if (cur_value < min_value) { min_value = cur_value; } 
   }
   var max_abs_value = (Math.abs(max_value) > Math.abs(min_value)) ? Math.abs(max_value) : Math.abs(min_value); 
   return max_abs_value; 
};

$g.createCompetitorHeader = function () {
	return '<tr id="title"><td>Stock</td><td width="50">Symbol</td>' + 
		'<td width="50">Currency</td><td width="50">Price</td>' + 
		'<td align="center" width="50">Net <br>Chg.</td><td width="50">Quote <br> Time</td>' + 
		'<td width="50">Consen. <br> Rec.</td><td width="37">P/E</td>' + 
		'<td class="marketCap" width="60">Mkt Cap <br> $Mil</td><td  width="45">52-Wk <br>High</td>' +
		'<td class="weekLow" width="45">52-Wk <br> Low</td><td width="55">Intraday</td>' +
		'<td align="center" width="100">Performance %</td>' +
		'<td width="100">&nbsp;</td></tr>';
};

$g.createCompetitorRow = function (return_type, return_max_abs_value, stock) { 

	var isSelectedRow = stock.main_listing_yn == "Y";
	var create_newbody = false;
	var sel_return, cell_width;
	
	switch (return_type){
		case "return_intra": sel_return = (stock.return_intra == "-") ? 0 : eval(stock.return_intra); break;
		case "return_1wk": sel_return = (stock.return_1wk == "-") ? 0 : eval(stock.return_1wk);  break;
		case "return_1qtr": sel_return = (stock.return_1qtr == "-") ? 0 : eval(stock.return_1qtr); break;
		case "return_1yr": sel_return = (stock.return_1yr == "-") ? 0 : eval(stock.return_1yr); break;
		default: sel_return = 0; 
	}
	
	var tmpl = "<tr><td class=\"#{className}\"><a href=\"#{db_url}/invest/investSQL/gx.company_prof?company_id=#{company_id}\">#{short_name}</a></td>";
	tmpl += "<td class=\"#{className}\"><a href=\"/servlet/Page/document/v5/data/stock?id=#{full_symbol}\">#{full_symbol}</a></td>";
	tmpl += "<td class=\"#{className}\">#{currency}</td>";
	tmpl += "<td class=\"#{className}\"><span id='comp_price'>#{price}</span></td>";
	tmpl += "<td class=\"#{className}\"><span class='tabletext3#{change_color}'>#{change}</span></td>";
	tmpl += "<td class=\"#{className}\">#{quote_time}</td>";
	tmpl += "<td class=\"#{className}\">#{consensus}</td>";
	tmpl += "<td class=\"#{className}\">#{pe}</td>";
	tmpl += "<td class=\"#{className} marketCap\">#{market_cap}</td>";
	tmpl += "<td class=\"#{className}\">#{high_52wk}</td>"; 
	tmpl += "<td class=\"#{className} weekLow\">#{low_52wk}</td>";
	tmpl += "<td class=\"#{className}\" id=\"return\"><span class='tabletext3#{perf_color}'>#{return_val}</span></td>";
	tmpl += "<td class=\"#{className} performance negative\">#{perf_neg_display}</td>";
	tmpl += "<td class=\"#{className} performance positive\">#{perf_pos_display}</td></tr>";
	
	var rowTemplate = new Template(tmpl);
	
	var cell_width = $g.getChartWidth(sel_return, return_max_abs_value, $g.total_width);
	
	return rowTemplate.evaluate( {
		db_url: $g.website_db_url,
		chart_url: $g.website_db_url+$g.find_out_more.chart,
		className: isSelectedRow ? "competitorSelected" : "",
		company_id: stock.company_id,
		short_name: stock.short_name,
		full_symbol: stock.full_symbol,
		currency: stock.currency,
		price: stock.price,
		change: stock.change,
		change_color: $g.getColor(stock.change),
		quote_time: stock.quote_time,
		consensus: stock.consensus,
		pe: stock.pe,
		market_cap: stock.market_cap,
		high_52wk: stock.high_52wk,
		low_52wk: stock.low_52wk,
		return_val: sel_return,
		perf_color: $g.getColor(sel_return),
		perf_pos_display: sel_return > 0 ? "<a href=\"#\" onclick=\"this.href=replaceURL('"+$g.website_db_url+$g.find_out_more.chart+"', 'pl_primary_listing', '"+stock.full_symbol+"')\"><img src='"+$g.img_base+$g.getColor(sel_return)+".gif' width='"+cell_width+"' height='10'></a>" : "&nbsp;",
		perf_neg_display: sel_return < 0 ? "<a href=\"#\" onclick=\"this.href=replaceURL('"+$g.website_db_url+$g.find_out_more.chart+"', 'pl_primary_listing', '"+stock.full_symbol+"')\"><img src='"+$g.img_base+$g.getColor(sel_return)+".gif' width='"+cell_width+"' height='10'></a>" : "&nbsp;"
	} );
}

$g.createCompetitorReport = function (tableId, return_type, stocks) {
	if (!return_type) {return_type = "return_intra"; }
	var returnArr = $g.getReturn(return_type);  
	var return_max_abs_value = $g.calSize(returnArr); 
	
	var buf;
	
	if (stocks.length === 0){
		buf = "<p class='noData'>Competitor report is not available.</p>";
		$("competitor_form").hide();
	} else {
		
		buf = "<table id='competitor_table' border='0' cellpadding='2' cellspacing='0'>" + $g.createCompetitorHeader();
		
		for (var i=0; i < stocks.length; i++){
			buf += $g.createCompetitorRow(return_type, return_max_abs_value , stocks[i]); 
		}
		
		buf += "</table>";
	}
	
	$(tableId).update(buf);
};

$g.getChartWidth = function (relVal, absVal, baseVal) {
   return (absVal <= 0) ? 0 : Math.round(Math.abs(relVal)/absVal*baseVal); 
};

$g.getNumType = function (myVal) {  
	var result = (myVal == '-' || eval(myVal) == 0) ? "" : ( eval(myVal) > 0 ? "positive" : "negative"); 
	return result;
};

$g.getColor = function (myVal, isSelected) {  
  var result = (isSelected) ? "blue" : ((myVal == '-' || eval(myVal) == 0) ? "" : ( eval(myVal) > 0 ? "green" : "red")); 
  return result;
};

$g.getReturn = function (return_type) {
   var stocks = $g.data.competitor; 
   var valArr = new Array(stocks.length);  
   if (return_type == "return_intra") {
       for (var i = 0; i < stocks.length; i++){
           valArr[i] = stocks[i].return_intra; 
       }
   } else if (return_type == "return_1wk") {
       for (var i = 0; i < stocks.length; i++){
           valArr[i] = stocks[i].return_1wk; 
       }
   } else if (return_type == "return_1qtr") {
       for (var i = 0; i < stocks.length; i++){
           valArr[i] = stocks[i].return_1qtr; 
       }
   } else if (return_type == "return_1yr") {
       for (var i = 0; i < stocks.length; i++){
           valArr[i] = stocks[i].return_1yr; 
       }
   }
   return valArr; 
};


$g.setCompetitorPerf = function (tableId, return_type) {
	var stocks = $g.data.competitor; 
	var row, rowid, cell, cell_width, color, return_cell, neg_cell, pos_cell, i, j=0, isSelectedRow = false;
	var theTable = $(tableId);
	var returnArr = $g.getReturn(return_type);  
	var return_max_abs_value = $g.calSize(returnArr); 
	
	for( i = 0; i < theTable.rows.length; i++ ) {
		row = theTable.rows[i]; 
		rowid = row.id; 
		
		if (rowid == "title") {
			$g.updateReturnTitle(row, row.cells.length - 3, return_type); 
		} else {
			isSelectedRow = stocks[j].main_listing_yn == "Y";
			$g.updateReturnRow(row, returnArr[j], isSelectedRow, return_max_abs_value,  row.cells.length -1, stocks[j].full_symbol); 
			j++;
		} // if
	}  // for
};

$g.updateReturnTitle = function (row, cell_idx, return_type) {
    var cell = row.cells[cell_idx];
    cell.innerHTML = $g.return_types[return_type]; 
};

$g.updateReturnRow = function (row, returnVal, isSelectedRow, return_max_abs_value,  cell_idx_chart, symbol) {
      var return_cell, neg_cell, pos_cell, att_value;     
      return_cell = row.cells[cell_idx_chart - 2]; 
      neg_cell= row.cells[cell_idx_chart - 1];  
      pos_cell = row.cells[cell_idx_chart]; 
      color = $g.getColor(returnVal);     
      att_value = isSelectedRow ? "competitorSelected" : ""; 
        
      return_cell.innerHTML = "<span class='tabletext3"  + $g.getColor(returnVal) + "'>" + returnVal + "</span>";  //returnVal;
      return_cell.className = att_value;
      cell_width = $g.getChartWidth(returnVal, return_max_abs_value, $g.total_width);
      if (returnVal < 0 ) {
        neg_cell.innerHTML = "<a href=\"#\" onclick=\"this.href=replaceURL('" + $g.website_db_url+$g.find_out_more.chart + "', 'pl_primary_listing', '" + symbol + "')\"><img src='" + $g.img_base +  color + ".gif' width='"+cell_width+"' height='10'></a>"; 
        pos_cell.innerHTML = "&nbsp;"; 
      }
      else if (returnVal > 0 ) {
        neg_cell.innerHTML = "&nbsp;"; 
        pos_cell.innerHTML = "<a href=\"#\" onclick=\"this.href=replaceURL('" + $g.website_db_url+$g.find_out_more.chart + "', 'pl_primary_listing', '" + symbol + "')\"><img src='" + $g.img_base +  color + ".gif' width='"+cell_width+"' height='10'></a>"; 
      }    
      else {
        neg_cell.innerHTML = "&nbsp;"; 
        pos_cell.innerHTML = "&nbsp;";    
      }
};

$g.displayActivity = function (divId, activity) {  
  var content, price, volume,name; 
  if (!activity || activity.rc != '0'){
    content =  "<p>Sorry, Stock activity measure data is not available</p>";
  }
  else {
    content = "<p>Today's price and volume strength relative to the last 9 trading days, as of " + activity.time + " EST</p>"; 
    content += "<table id=\"intraday_activityTable\" cellspacing=\"0\" border=\"0\">";
    content += "<tr><td nowrap=\"nowrap\" class=\"tabletext2\" width=\"43\">Measure</td><td colspan=\"2\" align=\"center\" nowrap=\"nowrap\" class=\"tabletext2\">Relative Price</td><td></td><td colspan=\"2\" align=\"center\" nowrap=\"nowrap\" class=\"tabletext2\">Volume Activity</td></tr>";
    content += "<tr><td></td><td width=\"82\" align=\"center\" class=\"tabletext1\">Negative</td><td width=\"83\" align=\"center\" class=\"tabletext1\">Positive</td></td><td></td><td align=\"left\" width=\"80\" class=\"tabletext1\">Low</td><td width=\"81\" align=\"right\" class=\"tabletext1\">High</td></tr>";
    for (var i = 0; i < 3; i++) {
       switch (i){
        case 0: name = activity.symbol; price = (activity.summary.price == '') ? null : eval(activity.summary.price); volume = (activity.summary.volume == '') ? null : eval(activity.summary.volume); break;
        case 1: name = 'Sector'; price = (activity.sectorSummary.price == '') ? null : eval(activity.sectorSummary.price); volume = (activity.sectorSummary.volume == '') ? null : eval(activity.sectorSummary.volume); break;
        case 2: name = 'Market'; price = (activity.marketSummary.price == '') ? null : eval(activity.marketSummary.price); volume = (activity.marketSummary.volume == '') ? null : eval(activity.marketSummary.volume); break;      
      }    
      if (price != null && volume != null){
        content += "<tr><td nowrap=\"nowrap\"><span class=\"tabletext1\">" + name + "</span></td>"; 
        
        content += "<td nowrap=\"nowrap\" align=\"center\" colspan=\"2\" width=\"165\"><table width='100%' class='border4' cellspacing='0'><tr>";
        if (!price || price >= 0){
          content +=  "<td class='negative'><img src=\"/v5/data/stocks/images/pixel.gif\" /></td></td></td><td class='positive'><img src=\"/v5/data/stocks/images/pixel_green.gif\" width=\"" + Math.abs(price*0.82) + "\" height=\"10\" border=\"0\" />";           
        }
        else {
          content +=  "<td class='negative'><img src=\"/v5/data/stocks/images/pixel_red.gif\" width=\"" + Math.abs(price*0.82) + "\" height=\"10\" border=\"0\" /></td></td><td class='positive'><img src=\"/v5/data/stocks/images/pixel.gif\" /></td>"; 
        }
        content += "</tr></table></td>";
        content += "<td nowrap=\"nowrap\" width=\"10\"><img src=\"/v5/data/stocks/images/pixel.gif\" width=\"1\" height=\"1\" border=\"0\" /></td>";
        content += "<td colspan=\"2\" align=\"left\" nowrap=\"nowrap\" width=\"161\"><table width='100%' class='border4' cellspacing='0'><tr><td>";
        content += volume ? "<img src=\"/v5/data/stocks/images/pixel_grey.gif\" width=\"" + Math.abs(volume*0.8) + "\" height=\"10\" border=\"0\" />" : "&nbsp;"; 
        content += "</td></tr></table></td></tr>";
      }
    }
  } 
  content += "</table>";      
  $(divId).update(content);
}  

// format money 20081031
$g.formatBucks = function(num){
    if (formatValuesIsOn) {
        var a = [], n = parseFloat(num);
        if (!isNaN(n)) {
            if (n < 0) {a.push('-'); n = Math.abs(n);}
            a.push('$');
            n = parseInt((n + .005) * 100); n = (n / 100).toString();
            a.push(n);
            if (n.indexOf('.') < 0) a.push('.00');
            else if (n.indexOf('.') == (n.length - 2)) a.push('0');
            return a.join('');
        }
        else return '-';
    }
    else return num;
}

// 2008-11-20
$g.formatEPS = function(num){
    if (formatValuesIsOn) {
        n = parseFloat(num);
        if (!isNaN(n)) {
            if (n<0) return '$('+Math.abs(n)+')';
            else return '$'+n;
        }
        else return '-';
    }
    else return num;
}
//

$g.prev_quote_last = null;
$g.prev_quote_time = null; 
$g.prev_bid = null; 
$g.prev_ask = null, 
$g.prev_priceTrend = null;

$g.displayQuote = function (quote) {
	if ( !quote || quote.last == '-') {
		//$g.isReload = false; 
		return; 
	}
	
	if ( $g.prev_quote_time == quote.dateTime ){
	   return; // no data updated if quote time is not changed. 
	}
	
	$g.class_change = (quote.pctChange == '-' || eval(quote.pctChange) == 0) ? "" : ((eval(quote.pctChange) > 0) ? "positiveChange" : "negativeChange"); 
	var pulsSign = (quote.pctChange != "-" && eval(quote.pctChange) > 0) ? '+' : '';  
	var pctSign = (quote.pctChange != "-" ) ? '%' : '';
	var priceTrend = (quote.lastTrend=="U") ? '<img src="/v5/data/stocks/images/arrow1_up.gif" alt="Up" height="11" width="21" border="0" />' : ((quote.lastTrend=="D") ? '<img src="/v5/data/stocks/images/arrow1_down.gif" alt="Down" height="11" width="21" border="0" />' : ""); 
	
	if (quote.last != $g.prev_quote_last && $g.prev_quote_last){
		var bgColor = (quote.last > $g.prev_quote_last) ? "#e7f2e7" : "#f7eceb";        
		$g.setBgColor (bgColor); 
		setTimeout("$g.setBgColor('white')",1000); 
	}
	
	if (quote.dateTime != "-"){
		$("quote_time").innerHTML = quote.dateTime;  
		$g.prev_quote_time = quote.dateTime; 
	}
	
	$("quote_price_last").innerHTML = quote.last;   
	$g.prev_quote_last = quote.last; 
	
	if ($g.prev_priceTrend != priceTrend){
	  $("quote_price_trend").innerHTML = priceTrend;   
	  $g.prev_priceTrend = priceTrend; 
	} 
	
	$("quote_change").innerHTML =  pulsSign +  quote.change ; 
	$("quote_change").className = $g.class_change;
	$("quote_pct_change").innerHTML =  pulsSign + quote.pctChange + pctSign; 
	$("quote_pct_change").className = $g.class_change;
	
	$("quote_volume").innerHTML = quote.volume ;
	
	if ( !$("quote_open") ) return;	// If this is not the summary page, then the rest of the data are not needed
									// element id="quote_open" only exists on summary page
	
	var bidsizeSign = (quote.bidSize == "") ? "" : "x";
	var asksizeSign = (quote.askSize == "") ? "" : "x";
	var bidTrend = (quote.bidTrend == "U") ? '<img src="/v5/data/stocks/images/arrow2_up.gif"  alt="Up" height="7" width="10" border="0"/>' : (quote.askTrend == 'D' ? '<img src="/v5/data/stocks/images/arrow2_down.gif"  alt="Up" height="7" width="10" border="0"/>' : '');
	var askTrend = (quote.askTrend == "U") ? '<img src="/v5/data/stocks/images/arrow2_up.gif"  alt="Up" height="7" width="10" border="0"/>' : (quote.askTrend == 'D' ? '<img src="/v5/data/stocks/images/arrow2_down.gif"  alt="Up" height="7" width="10" border="0"/>' : '');
	
    // data formatted 2008-10-31
	$("quote_open").innerHTML = $g.formatBucks(quote.open);// controlled by formatValuesIsOn
	$("quote_high").innerHTML = $g.formatBucks(quote.high);
	$("quote_low").innerHTML = $g.formatBucks(quote.low);
	if ($g.prev_bid != quote.bid) {
	  $("quote_bid").innerHTML = bidTrend + $g.formatBucks(quote.bid);  $g.prev_bid = quote.bid;
	}
	$("quote_bid_size").innerHTML = "Bid <span class=\"highlow\">" + bidsizeSign + quote.bidSize + "</span>"; 
	if ($g.prev_ask != quote.ask){  
	  $("quote_ask").innerHTML = askTrend + $g.formatBucks(quote.ask);  $g.prev_ask = quote.ask;
	}
	$("quote_ask_size").innerHTML = "Ask <span class=\"highlow\">" + asksizeSign + quote.askSize + "</span>";
    
    // 2008-11-20 vp
	$("quote_pe").innerHTML = (formatValuesIsOn && !isNaN(parseFloat(quote.peRatio))) ?  quote.peRatio + "x" : quote.peRatio;// adding trailing 'x'
    
	//$("quote_eps").innerHTML = $g.epsCurrency + " " + quote.eps;
	//Removal of the epsCurrency
	$("quote_eps").innerHTML = $g.formatEPS(quote.eps);// controlled by formatValuesIsOn 2008-11-20
    
	$("quote_dividend").innerHTML = quote.dividend ;
	$("quote_yield").innerHTML = (formatValuesIsOn && !isNaN(parseFloat(quote.yield))) ? quote.yield+'%' : quote.yield; 
};

$g.setBgColor = function (bgColor) {
    $("quote_price_last").style.background = bgColor; 
    $("quote_change").style.background = bgColor; 
    $("quote_pct_change").style.background = bgColor;      
};

$g.updateQuote = function () {
	//verify $g.app_time, no streaming in weekend.
	if ($g.app_time == "Sat" || $g.app_time == "Sun" || $g.isReload == false) return;
	
		try
		{			
			$g.getReport("quote");
		}
		finally
		{
			//pulls updated number from back-end and
			var nextUpdate;

			try {
			    // This is in a try block in case, for some strange reason,
			    // .data or .quote is undefined/null.
			    nextUpdate = $g.data.quote.secondsTillNextUpdate;
			} catch (err) {
			    nextUpdate = null;
			}
			
			if (typeof nextUpdate == 'undefined' || nextUpdate == null || nextUpdate <= 0)
				nextUpdate = $g.default_update_seconds;

			setTimeout($g.updateQuote, nextUpdate*1000);
		} //end tryCatchFinally
};

$g.updateMyStocklist = function(action, listing_id) {
    if (action == null || listing_id == null) {
    return; 
    }

    var now = new Date();
    var myurl = "/servlet/Page/document/v5/data/stocks/quote/quote_action?action=" + action + "&listing_id=" + listing_id  +  "&ord=" + now.getTime();; 
    var divId = "mystocklist";
    $g.getDataFromRequest(divId, null, myurl, false);
};

$g.positionTradeNowMenu = function () {

    var width = window.innerWidth || document.body.clientWidth;

    if ( Position.page($("tradeNowButton"))[0]+210+69+25 < width ) {
        Position.clone( $("tradeNowButton"), "tradeNowMenu", { setWidth: false, setHeight: false, offsetLeft: 68 } );
    } else {
        Position.clone( $("tradeNowButton"), "tradeNowMenu", { setWidth: false, setHeight: false, offsetLeft: -210 } );
    }
};

// Check if this is Database page.
if ( $("db_oracle_table") != null ) {
    // Database pages update less frequently
	$g.default_update_seconds = 60;

    $g.getDataFromRequest = function (divId, id, myurl, isParse, params) {
        var now = new Date();
        
        $g.CrossDomainRequest( $g.website_url+myurl+"?symbol="+$g.quote_params.symbol+"-"+$g.quote_params.exchange_code+"&listing_id="+$g.quote_params.listing_id+"&ord="+now.getTime(),
            function () {
                $g.displayData(divId, id, $g.data.quote); 
            }
        );
    };
		
	// AJAX calls will not work for database pages, so we need to handle them differently.
	$g.toggleTradeNow = function () {
		if ( $("tradeNowMenu").style.display == "none" ) {
			var now = new Date();
			
			$g.positionTradeNowMenu();
			
			var symbol_param = $g.quote_params.symbol == "" ? "" : "symbol="+$g.quote_params.symbol+"-"+$g.quote_params.exchange_code+"&";
			$g.CrossDomainRequest( $g.website_url+"/servlet/Page/document/v5/data/stocks/broker/trade_now_items_db?"+symbol_param+"ord="+now.getTime(),
				function () {
					$("tradeNowList").update( $g.menuItems );
					Effect.toggle( "tradeNowMenu", "blind", { duration: .5 } );
				}
			);
			
		} else {
			Effect.toggle( "tradeNowMenu", "blind", { duration: .5 } );
		} // if
	}; // $g.toggleTradeNow

	$g.dropBroker = function () {
		$g.CrossDomainRequest( $g.website_url+"/servlet/Page/document/v5/data/stocks/broker/set?symbol="+$g.quote_params.symbol+"-"+$g.quote_params.exchange_code+"&broker_id=",
			function () { window.location = window.location.href; }
		);
		
		return false;
	} // $g.dropBroker
} else {
	// Non-database pages, we can do things properly.
	$g.toggleTradeNow = function () {
		if ( $("tradeNowMenu").style.display == "none" ) {
			var now = new Date();
			
			$g.positionTradeNowMenu();
			
			new Ajax.Request( "/servlet/Page/document/v5/data/stocks/broker/trade_now_items", {
				method: "GET",
				parameters: { symbol: $g.quote_params.symbol+"-"+$g.quote_params.exchange_code, ord: now.getTime() },
				onSuccess: function ( transport ) {
					$("tradeNowList").update( transport.responseText );
					Effect.toggle( "tradeNowMenu", "blind", { duration: .5 } );
				},
				onFailure: function(){ console.log("AJAX error: %s", transport); }
			} ); // Ajax.Request
			
		} else {
			Effect.toggle( "tradeNowMenu", "blind", { duration: .5 } );
		} // if
	}; // $g.toggleTradeNow

	$g.dropBroker = function () {
		new Ajax.Request( "/servlet/Page/document/v5/data/stocks/broker/set", {
			method: "GET",
			parameters: { symbol: $g.quote_params.symbol+"-"+$g.quote_params.exchange_code, broker_id: "" },
			onSuccess: function( transport ) {
				var response = transport.responseText.evalJSON();
				
				$g.toggleTradeNow();
			},
			onFailure: function(){ console.log("AJAX error: %s", transport); }
		} ); // Ajax.Request
		
		return false;
	} // $g.dropBroker
} // if

    
Event.observe(window, "load", function(){
	try {printThis($("tools"));} catch (err) {};
	$g.updateQuote();
});
