//Copyright 2006 www.cashmain.com. All Rights Reserved

var g_grid_color = "#BEBED8";
var g_text_color = "#000000";
var g_linechart_color = "#3F4DF3";
var g_volume_color = "#A3A3BE";
var g_cursor_color = "#AEC4FB"
var g_trend_line_color = "#FF6347";
var g_ma10_color = "#F77500";
var g_ma50_color = "#00B500";

var g_macd_color = "#00FF00";
var g_macd_diff_color = "#FFD700";

var g_direct_line_base = "http://chart."+g_cashmain_url+"/standalone.php";

var g_chart_left_margin = 70;
var g_chart_margin = 20;
var g_chart_border = 2;

var g_max_price = -1;
var g_min_price = -1;
var g_max_volume = -1;

var g_symbol = null;
var g_chart_date = null;
var g_chart_open = null;
var g_chart_high = null;
var g_chart_low = null;
var g_chart_close = null;
var g_chart_volume = null;


var g_chart_ma10 = null;
var g_chart_ma50 = null;

var g_chart_rsi = null;

var g_chart_macd = null;

var g_chart_mapper = null;

var g_cursor_hold = false;

var g_base_point = null;

var g_y_pixel_step = null;

var g_lines = new Array();

var MONTH_STRING = new Array("Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec");


function display_direct_link()
{
	var direct_link = document.getElementById("direct_link");
	if(direct_link == null)
		return;

	var link_string = g_direct_line_base + "?s=" + g_symbol;
	for(var i = 0; i < g_lines.length; i++)
		link_string += ("&line" + (i+1) + "=" + escape(g_lines[i]));

	while(direct_link.childNodes.length){
		var temp = direct_link.firstChild;
		direct_link.removeChild(temp);
		delete temp;
	}
	direct_link.setAttribute("href",link_string);
	direct_link.appendChild(document.createTextNode(link_string));
}

function display_symbol(symbol)
{
	var symbol_label = document.getElementById("symbol_label");
	if(symbol_label == null) return;
	while(symbol_label.childNodes.length)
		symbol_label.removeChild(symbol_label.firstChild);
	symbol_label.appendChild(document.createTextNode(symbol));
}

function display_value(id, value)
{
	var label = document.getElementById(id);
	if(label == null) return;
	
	if(label.childNodes.length == 0)
		label.appendChild(document.createTextNode(value));
	else
		label.firstChild.nodeValue = value;
	
	/*while(label.childNodes.length)
		label.removeChild(label.firstChild);
	label.appendChild(document.createTextNode(value));*/
}

function get_date_string(date)
{
	var date_text = "";
	date_text += ((date.getDate() < 10) ? ("0" + date.getDate()) : (date.getDate()));
	date_text += "/";
	date_text += (((date.getMonth()+1) < 10) ? ("0" + (date.getMonth() + 1)) : ((date.getMonth() + 1)));
	date_text += "/";
	date_text += (((date.getYear() % 100) < 10) ? ("0" + (date.getYear() % 100)) : ((date.getYear() % 100)));
	return date_text;
}

function display_date(date)
{
	var label = document.getElementById("date_label");
	if(label == null) return;
	while(label.childNodes.length)
		label.removeChild(label.firstChild);
	label.appendChild(document.createTextNode(get_date_string(date)));
}


function get_grid_step(max, min, number_of_steps)
{
	var step = (max - min)/number_of_steps;
	
	if(step <= 0.0001) 		step = 0.0001;
	else if(step <= 0.0002)	step = 0.0002;
	else if(step <= 0.0005)	step = 0.0005;
	else if(step <= 0.001) 	step = 0.001;
	else if(step <= 0.002)	step = 0.002;
	else if(step <= 0.005)	step = 0.005;
	else if(step <= 0.01)	step = 0.01;
	else if(step <= 0.02)	step = 0.02;
	else if(step <= 0.05)	step = 0.05;
	else if(step <= 0.1)	step = 0.1;
	else if(step <= 0.2)	step = 0.2;
	else if(step <= 0.5)	step = 0.5;
	else if(step <= 1)		step = 1;
	else if(step <= 2)		step = 2;
	else if(step <= 5)		step = 5;
	else if(step <= 10)		step = 10;
	else if(step <= 20)		step = 20;
	else if(step <= 50)		step = 50;
	else if(step <= 100)	step = 100;
	else if(step <= 200)	step = 200;
	else if(step <= 500)	step = 500;
	else if(step <= 1000)	step = 1000;
	else if(step <= 2000)	step = 2000;
	else if(step <= 5000)	step = 5000;
	else if(step <= 10000)	step = 10000;
	else if(step <= 20000)	step = 20000;
	else if(step <= 50000)	step = 50000;
	else step = 100000;
	return step;
}

function parseXCoordinatesToIndex(x)
{
	var index = -1;
	if(g_chart_mapper == null)
		return -1;
		
	for(var i = 1 ; i < g_chart_mapper.length; i++){
		if(x < g_chart_mapper[i])	continue;
		if(Math.abs(x - g_chart_mapper[i]) < Math.abs(x - g_chart_mapper[i - 1]))
			index = i;
		else
			index = i-1;
		break;
	}
	return index;
}

function parseCoordinatesIndexToString(index, y, width, height)
{
	var price = Math.pow(10,(height - g_chart_margin - y) / g_y_pixel_step + (Math.log(g_min_price)/Math.LN10));
	price = Math.round(price * 1000 ) / 1000;
	
	return  get_date_string(g_chart_date[index]) + "," + price;
}
function parseCoordinatesToString(x,y,width,height)
{
	var index = parseXCoordinatesToIndex(x);

	if(index == -1)
		return null;
	return parseCoordinatesIndexToString(index, y, width, height);
}

function draw_single_line(graphics, desc, width, height)
{
	if(g_chart_mapper == null)
		return -1;
	
	var x1 = null,x2 = null,y1 = null,y2 = null;
	
	var temp = desc.split("->");
	var line1 = temp[0].split(",");
	var line2 = temp[1].split(",");

	var date1 = line1[0].split("/");
	
	for(var i = 0 ; i < g_chart_date.length; i++){
		if(g_chart_date[i].getDate() == parseInt(date1[0], 10) &&
		   g_chart_date[i].getMonth() == parseInt(date1[1], 10) -1 && 
		   (g_chart_date[i].getYear() % 100) == parseInt(date1[2], 10)){
		   	x1 = g_chart_mapper[i];
		   	break;
		}
	}
	var date2 = line2[0].split("/");
	for(var i = 0 ; i < g_chart_date.length; i++){
		if(g_chart_date[i].getDate() == parseInt(date2[0], 10) &&
		   g_chart_date[i].getMonth() == parseInt(date2[1], 10) -1 && 
		   (g_chart_date[i].getYear() % 100) == parseInt(date2[2],10)){
		   	x2 = g_chart_mapper[i];
		   	break;
		}
	}
	if(x1 == null || x2 == null)			return;
	
	y1 = ((Math.log(parseFloat(line1[1])) - Math.log(g_min_price))/Math.LN10) * g_y_pixel_step;
	y2 = ((Math.log(parseFloat(line2[1])) - Math.log(g_min_price))/Math.LN10) * g_y_pixel_step;
	
	if(y1 >= height - g_chart_margin) 		return;
	y1 = height - g_chart_margin - y1;
	y1 = Math.round(y1);
	
	if(y2 >= height - g_chart_margin)  		return;
	y2 = height - g_chart_margin - y2;
	y2 = Math.round(y2);
	
	
	
	graphics.drawLine(x1,y1,x2,y2);
}

function draw_persisted_lines(width, height)
{
	var graphics = get_jsgraphics("line");
	graphics.clear();
	graphics.setColor(g_trend_line_color);
	
	var text = "";
	for(var i = 0 ; i < g_lines.length; i++)
		text += g_lines[i] + "\n";
	
	for(var i = 0 ; i < g_lines.length; i++)
		draw_single_line(graphics, g_lines[i],width, height);
	
	graphics.paint();
}

function clean_all_lines()
{
	delete g_lines;
	g_lines = new Array();
	var graphics = get_jsgraphics("line");
	graphics.clear();
	graphics.paint();
	display_direct_link();
}

function basepoint(x, y, width, height){
	
	if(g_base_point == null){
		var index = parseXCoordinatesToIndex(x);
		if(index == -1)
			return;
		g_base_point = new Array(g_chart_mapper[index], y);
	}else{
		g_lines[g_lines.length] = 
					parseCoordinatesToString(g_base_point[0], g_base_point[1], width, height) 
			+ "->" + parseCoordinatesToString(x, y, width, height);
		g_base_point = null;
		draw_persisted_lines(width, height);
		display_direct_link();
	}
}

function lines(x,y, width, height)
{
	var index = parseXCoordinatesToIndex(x);
	
	if(index == -1)
		return;
	
	var graphics = get_jsgraphics("interactive");
	graphics.clear();
	graphics.setColor(g_trend_line_color);
	
	
	graphics.drawString(parseCoordinatesIndexToString(index,y,width,height), x + 10, y);
	
	graphics.paint();
	
	if(g_base_point == null)
		return;
	
	graphics.drawLine(g_base_point[0], g_base_point[1], g_chart_mapper[index], y);
	graphics.paint();
}

function draw_rsi_cursor(graphics, index)
{
	graphics.setColor(g_cursor_color);
	
	graphics.fillRect(g_chart_mapper[index]-1, 0, 3, g_extended_height);
			
	if(index > g_chart_rsi.length){
		graphics.setColor(g_text_color);
		graphics.drawStringRect("RSI: N/A", 0,  0, g_chart_left_margin - 5, "left");
	}else{
		if(g_chart_rsi[index] > 70)
			graphics.setColor("red");
		else if(g_chart_rsi[index] < 30)
			graphics.setColor("green");
		else
			graphics.setColor(g_text_color);
		graphics.setFont("verdana","8px",Font.BOLD);
		graphics.drawStringRect("RSI:" + Math.round(g_chart_rsi[index]), 0,  0, g_chart_left_margin - 5, "left");
	}
}

function draw_macd_cursor(graphics, index)
{
	graphics.setColor(g_cursor_color);
	
	graphics.fillRect(g_chart_mapper[index]-1, 0, 3, g_extended_height);
			
	if(index >= g_chart_macd[0].length){
		graphics.setFont("verdana","8px",Font.BOLD);
		graphics.setColor(g_text_color);
		graphics.drawStringRect("MACD(12,26,9): N/A", g_chart_left_margin + 3,  2, 
								g_chart_width - g_chart_left_margin - 3, "left");
	}else{
		graphics.setFont("verdana","8px",Font.BOLD);
		graphics.setColor(g_text_color);
		graphics.drawStringRect("MACD(12,26,9): ", g_chart_left_margin + 3,  2, 
								80, "left");
								
		graphics.setColor(g_macd_color);
		graphics.drawStringRect(Math.round(g_chart_macd[0][index] * 10000) / 10000, 
								g_chart_left_margin + 83,  2,  40, "right");
								
		graphics.setColor(g_macd_diff_color);
		graphics.drawStringRect(Math.round(g_chart_macd[1][index] * 10000) / 10000, 
								g_chart_left_margin + 123,  2,  40, "right");
		
		graphics.setColor(g_linechart_color);
		graphics.drawStringRect(Math.round(g_chart_macd[2][index] * 10000) / 10000, 
								g_chart_left_margin + 163,  2,  40, "right");
		
		/*var text = "MACD(12,26,9): " + Math.round(g_chart_macd[0][index] * 10000) / 10000 + 
					"," + Math.round(g_chart_macd[1][index] * 10000) / 10000 + 
					"," + Math.round(g_chart_macd[2][index] * 10000) / 10000;
		
		graphics.drawStringRect(text, g_chart_left_margin + 3,  2, 
								g_chart_width - g_chart_left_margin - 3, "left");*/
	}
}

function draw_extended_cursor(index)
{
	var extendedChart = document.getElementById("extendedChart");
	if(extendedChart == null || extendedChart.value == "none") return;
	
	var graphics = get_jsgraphics("extended_interactive_draw");
	if(graphics == null)
		return;
	graphics.clear();
	
	if(extendedChart.value == "rsi9")
		draw_rsi_cursor(graphics, index);
	else if(extendedChart.value == "rsi14")
		draw_rsi_cursor(graphics, index);
	else if(extendedChart.value == "macd")
		draw_macd_cursor(graphics, index);
		
	graphics.paint();
}

function format_volume(num) {
	num = num.toString().replace(/\$|\,/g,'');
	if(isNaN(num))
	num = "0";
	sign = (num == (num = Math.abs(num)));
	num = Math.floor(num*100+0.50000000001);
	cents = num%100;
	num = Math.floor(num/100).toString();
	if(cents<10)
	cents = "0" + cents;
	for (var i = 0; i < Math.floor((num.length-(1+i))/3); i++)
	num = num.substring(0,num.length-(4*i+3))+','+
	num.substring(num.length-(4*i+3));
	if(cents = "00")
		return (((sign)?'':'-') + num);
	else
		return (((sign)?'':'-') + num + '.' + cents);
}

function cursor(x,y, width, height)
{
	if(g_chart_mapper == null)
		return;
	for(var i = 1 ; i < g_chart_mapper.length; i++){
		if(x < g_chart_mapper[i])	continue;

		var index = 0;
		if(Math.abs(x - g_chart_mapper[i]) < Math.abs(x - g_chart_mapper[i - 1]))
			index = i;
		else
			index = i-1;
		
		
		var graphics = get_jsgraphics("interactive");
		graphics.clear();		
		//graphics.setPrintable(true);//cannot be printable because it will affect the mouse click event in internet explorer.
		
		graphics.setColor(g_cursor_color);		
		graphics.fillRect(g_chart_mapper[index]-1, g_chart_margin, 3,height - 2*g_chart_margin);			  

		graphics.paint();
		
		display_date(g_chart_date[index]);
		display_value("price_label",g_chart_close[index]);
		display_value("open_label",g_chart_open[index]);
		display_value("high_label",g_chart_high[index]);
		display_value("low_label",g_chart_low[index]);
		display_value("volume_label",format_volume(g_chart_volume[index]));
		
		if(g_chart_ma10 != null &&  index < g_chart_ma10.length){
			display_value("ma10",g_chart_ma10[index]);
		}else{
			display_value("ma10","N/A");
		}
		
		if(g_chart_ma50 != null &&  index < g_chart_ma50.length){
			display_value("ma50",g_chart_ma50[index]);
		}else{
			display_value("ma50","N/A");
		}

		draw_extended_cursor(index);
		
		if(index != g_chart_volume.length - 1){
			var change = g_chart_close[index] - g_chart_close[index + 1];
			change = Math.round(change * 100) / 100;
			display_value("change_label", change);
			
			var percentage = (g_chart_close[index] - g_chart_close[index + 1]) / g_chart_close[index + 1];
			percentage *= 100;
			percentage = Math.round(percentage * 100) / 100;
			display_value("change_percentage_label", percentage);
		}else{
			display_value("change_label", "--.--");
			display_value("change_percentage_label", "--.--");
		}
		break;
	}
	
}



function draw_ma(chartid, width, height)
{
	var graphics = get_jsgraphics(chartid);
	graphics.clear();

	var y_pixel_step = (height - g_chart_margin * 2) / ((Math.log(g_max_price) - Math.log(g_min_price))/Math.LN10);
	var x_pixel_step =  (width - g_chart_margin - g_chart_left_margin) / g_chart_close.length;
	
	for(var i = 1; g_chart_ma50 != null && i < g_chart_ma50.length; i++){
		
		var y1 = ((Math.log(g_chart_ma50[i - 1]) - Math.log(g_min_price))/Math.LN10) * y_pixel_step;
		var x1 = (g_chart_close.length - i + 1) * x_pixel_step + g_chart_left_margin;
		
		if(y1 >= height - g_chart_margin) continue;
		y1 = height - g_chart_margin - y1;
		
		var y2 = ((Math.log(g_chart_ma50[i]) - Math.log(g_min_price))/Math.LN10) * y_pixel_step;
		var x2 = (g_chart_close.length - i) * x_pixel_step + g_chart_left_margin;
		
		if(y2 >= height - g_chart_margin) continue;
		y2 = height - g_chart_margin - y2;
		
		x1 = Math.round(x1);
		x2 = Math.round(x2);
		y1 = Math.round(y1);
		y2 = Math.round(y2);
		
		graphics.setColor(g_ma50_color);
		graphics.drawLine(x1, y1, x2, y2);
	}
	
	for(var i = 1; g_chart_ma10 != null && i < g_chart_ma10.length; i++){
		
		var y1 = ((Math.log(g_chart_ma10[i - 1]) - Math.log(g_min_price))/Math.LN10) * y_pixel_step;
		var x1 = (g_chart_close.length - i + 1) * x_pixel_step + g_chart_left_margin;
		
		if(y1 >= height - g_chart_margin) continue;
		y1 = height - g_chart_margin - y1;
		
		var y2 = ((Math.log(g_chart_ma10[i]) - Math.log(g_min_price))/Math.LN10) * y_pixel_step;
		var x2 = (g_chart_close.length - i) * x_pixel_step + g_chart_left_margin;
		
		if(y2 >= height - g_chart_margin) continue;
		y2 = height - g_chart_margin - y2;
		
		x1 = Math.round(x1);
		x2 = Math.round(x2);
		y1 = Math.round(y1);
		y2 = Math.round(y2);
		
		graphics.setColor(g_ma10_color);
		graphics.drawLine(x1, y1, x2, y2);
	}
	graphics.paint();
}

function calculate_sma(days)
{
	var sma = new Array();
	for(var i = 0; i < g_chart_close.length; i++){
		if(i + days - 1 >= g_chart_close.length)
			break;
		var total = 0;
		for(var j = 0 ; j < 10; j++)
			total += g_chart_close[i+j];
		sma[i] = total / 10;
		sma[i] = Math.round(sma[i] * 1000) / 1000;
	}
	return sma;
}

function calculate_rsi(days)
{
	var rsi = new Array();
	for(var i = 0; i < g_chart_close.length; i++){
		var rise_total = 0, fall_total = 0;

		if(i + days - 1 < g_chart_close.length){
			for(var j = 0 ; j < days; j++){
				if(g_chart_close[i+j] > g_chart_close[i+j+1])//rise
					rise_total += g_chart_close[i+j] - g_chart_close[i+j+1];
				else if(g_chart_close[i+j] < g_chart_close[i+j+1])//fall
					fall_total += g_chart_close[i+j+1] - g_chart_close[i+j];
			}
			if(rise_total == 0 && fall_total == 0)
				rsi[i] = 50;
			else if(rise_total == 0)
				rsi[i] = 0;
			else if(fall_total == 0)
				rsi[i] = 100;
			else
				rsi[i] = (100 - (100/(1+(/*RS*/(rise_total / days) / (fall_total / days)))));
		}else
			break;
	}
	return rsi;
	
}
function calculate_ema(days, totaldays, data)
{
	var ema = new Array();
	var sma = 0;
	for(var i = totaldays - 1; i >= 0 ; i--){
		if(i + days - 1 >= totaldays){
			if(data == null)
				sma += g_chart_close[i];
			else
				sma += data[i];
			continue;
		}
		if(i+days == totaldays){
			if(data == null)
				sma += g_chart_close[i];
			else
				sma += data[i];
			sma /= days;
			ema[i] = sma;
			ema[i] = Math.round(ema[i] * 1000) / 1000;
		}else{
			if(data == null)
				ema[i] = (g_chart_close[i] - ema[i + 1]) * 2 / (days + 1) + ema[i + 1];
			else
				ema[i] = (data[i] - ema[i + 1]) * 2 / (days + 1) + ema[i + 1];
			ema[i] = Math.round(ema[i] * 1000) / 1000;
		}
	}
	return ema;
}

function price_demain_index(index)
{
	return (g_chart_high[index] + g_chart_low[index] + 2 * g_chart_close[index]) / 4;
}
function calculate_macd(fast_days, slow_days, macd_days)
{
	var macd = new Array(3);//0-macd, 1-diff, 2-diver
	
	var ema_fast = calculate_ema(fast_days, g_chart_close.length, null);
	var ema_slow = calculate_ema(slow_days, g_chart_close.length, null);
	
	macd[1] = new Array();
	for(var i = 0; i < ema_slow.length; i++)
		macd[1][i] = ema_fast[i] - ema_slow[i];
	
	macd[0] = calculate_ema(macd_days, macd[1].length, macd[1]);
	
	macd[2] = new Array();
	for(var i = 0; i < macd[0].length; i++)
		macd[2][i] = macd[1][i] - macd[0][i];
	return macd;
}


function draw_macd(id, width, height)
{
	g_chart_macd = calculate_macd(12, 26, 9);
	
	var graphics = get_jsgraphics(id);
	graphics.clear();
	graphics.setColor(g_grid_color);
	graphics.setStroke(2);
	graphics.drawRect(g_chart_left_margin, 0, 
					  width - g_chart_margin - g_chart_left_margin, 
					  height);
	
	

	var max=-1, min=0;
	for(var i=0; i < g_chart_macd[0].length; i++){
		if(max == -1) max = g_chart_macd[0][i];
		if(max < g_chart_macd[0][i]) max = g_chart_macd[0][i];
		if(max < g_chart_macd[1][i]) max = g_chart_macd[1][i];
		if(max < g_chart_macd[2][i]) max = g_chart_macd[2][i];
		
		if(min == -1) min = g_chart_macd[0][i];
		if(min > g_chart_macd[0][i]) min = g_chart_macd[0][i];
		if(min > g_chart_macd[1][i]) min = g_chart_macd[1][i];
		if(min > g_chart_macd[2][i]) min = g_chart_macd[2][i];
	}
	
	
	graphics.setStroke(1);
	var grid_step = get_grid_step(max, min, 4);

	max = Math.round((max + (grid_step/2)) / grid_step) * grid_step;
	min = Math.round((min - (grid_step/2)) / grid_step) * grid_step;

	var pixel_value = (max - min)/height;
	
	graphics.setColor(g_text_color);
	graphics.drawStringRect(Math.round(max*1000)/1000, 0,  0, g_chart_left_margin - 5, "right");
	for(var i = min + grid_step; i < max; i += grid_step){
		y_value = Math.round((i - min) / pixel_value);
		y_value = height - y_value;
		graphics.setColor(g_grid_color);
		graphics.drawLine(g_chart_left_margin, y_value, width - g_chart_margin, y_value);
		graphics.setColor(g_text_color);
		graphics.drawStringRect(Math.round(i*1000)/1000, 0,  y_value - 6, g_chart_left_margin - 5, "right");
	}
	graphics.setColor(g_text_color);
	graphics.drawStringRect(Math.round(min*1000)/1000, 0,  height - 12, g_chart_left_margin - 5, "right");
	
	graphics.setColor(g_macd_color);	
	for(var i = 1; i < g_chart_macd[0].length; i++){
		var y1 = Math.round((g_chart_macd[0][i-1] - min) / pixel_value);
		var x1 = g_chart_mapper[i-1];
		y1 = height - y1;
		
		var y2 = Math.round((g_chart_macd[0][i] - min) / pixel_value);
		var x2 = g_chart_mapper[i];
		y2 = height - y2;

		graphics.drawLine(x1, y1, x2, y2);	
	}
	
	graphics.setColor(g_macd_diff_color);	
	for(var i = 1; i < g_chart_macd[1].length; i++){
		var y1 = Math.round((g_chart_macd[1][i-1] - min) / pixel_value);
		var x1 = g_chart_mapper[i-1];
		y1 = height - y1;
		
		var y2 = Math.round((g_chart_macd[1][i] - min) / pixel_value);
		var x2 = g_chart_mapper[i];
		y2 = height - y2;

		graphics.drawLine(x1, y1, x2, y2);	
	}
	graphics.setColor(g_linechart_color);	
	
	var y0 = Math.round((0 - min) / pixel_value);
	y0 = height - y0;
	for(var i = 0; i < g_chart_macd[2].length; i++){
		var y = Math.round((g_chart_macd[2][i] - min) / pixel_value);
		var x = g_chart_mapper[i];
		y = height - y;
		if(y == y0)
			continue;
		graphics.drawLine(x, y, x, y0);	
	}
	graphics.paint();
	
}

function draw_rsi(id, width, height, days)
{
	g_chart_rsi = calculate_rsi(days);
	var graphics = get_jsgraphics(id);
	graphics.clear();
	graphics.setColor(g_grid_color);
	graphics.setStroke(2);
	graphics.drawRect(g_chart_left_margin, 0, 
					  width - g_chart_margin - g_chart_left_margin, 
					  height);
	
	graphics.setStroke(1);
	graphics.setColor(g_grid_color);
	graphics.drawLine(g_chart_left_margin, 50, width - g_chart_margin, 50);
	graphics.setColor(g_text_color);
	graphics.drawStringRect("50", 0,  43, g_chart_left_margin - 5, "right");
	
	graphics.setColor(g_grid_color);
	graphics.drawLine(g_chart_left_margin, 30, width - g_chart_margin, 30);
	graphics.setColor(g_text_color);
	graphics.drawStringRect("70", 0,  23, g_chart_left_margin - 5, "right");
	
	graphics.setColor(g_grid_color);
	graphics.drawLine(g_chart_left_margin, 70, width - g_chart_margin, 70);
	graphics.setColor(g_text_color);
	graphics.drawStringRect("30", 0,  63, g_chart_left_margin - 5, "right");
	
	for(var i = 1; i < g_chart_rsi.length; i++){
		var x1 = g_chart_mapper[i];
		var y1 = height - ((height/100) * g_chart_rsi[i]);
		var x2 = g_chart_mapper[i - 1];
		var y2 = height - ((height/100) * g_chart_rsi[i - 1]);
		x1 = Math.round(x1);
		x2 = Math.round(x2);
		y1 = Math.round(y1);
		y2 = Math.round(y2);
		graphics.setColor(g_linechart_color);
		graphics.drawLine(x1, y1, x2, y2);	
	}
	graphics.paint();
}

function transform_to_y_coordinate(value, height)
{
	var y = ((Math.log(value) - Math.log(g_min_price))/Math.LN10) * g_y_pixel_step;
	y = Math.round(y);
	return (height - g_chart_margin - y);
}

function draw_bar_chart(graphics, width, height)
{
	for(var i = 0; i < g_chart_close.length; i++){
		var x = g_chart_mapper[i];
		var y_open = transform_to_y_coordinate(g_chart_open[i], height);
		var y_high = transform_to_y_coordinate(g_chart_high[i], height);
		var y_low =  transform_to_y_coordinate(g_chart_low[i] , height);
		var y_close= transform_to_y_coordinate(g_chart_close[i], height);
		
		if(g_chart_open[i] > g_chart_close[i])
			graphics.setColor("red");
		else
			graphics.setColor("blue");
		graphics.drawLine(x, y_high, x, y_low);
		
		graphics.drawLine(x-1, y_open, x, y_open);
		graphics.drawLine(x, y_close, x+1, y_close);
		
		
	}
}

function draw_line_chart(graphics, width, height)
{
	for(var i = 1; i < g_chart_close.length; i++){
		var y1 = transform_to_y_coordinate(g_chart_close[i-1], height);
		var x1 = g_chart_mapper[i-1];
		
		var y2 = transform_to_y_coordinate(g_chart_close[i], height);
		var x2 = g_chart_mapper[i];

		graphics.setColor(g_linechart_color);
		graphics.drawLine(x1, y1, x2, y2);	
	}
}

function draw_chart(chartid, volumeid, width, height)
{
	var chart_graphics = get_jsgraphics(chartid);
	var volume_graphics = get_jsgraphics(volumeid);

	chart_graphics.clear();
	//chart_graphics.setPrintable(true);
	
	volume_graphics.clear();
	//volume_graphics.setPrintable(true);
	var y_pixel_step = (height - g_chart_margin * 2) / ((Math.log(g_max_price) - Math.log(g_min_price))/Math.LN10);
	var x_pixel_step =  (width - g_chart_margin - g_chart_left_margin) / g_chart_close.length;
	g_y_pixel_step = y_pixel_step;
	
	var vol_pixel_step = g_max_volume / ((height - g_chart_margin * 2) / 3);
	g_chart_mapper = new Array();
	
	
	for(var i = 0; i < g_chart_close.length; i++){
		var x = (g_chart_close.length - i) * x_pixel_step + g_chart_left_margin;
		x = Math.round(x);
		g_chart_mapper[i] = x;
	}
	
	if( document.chart_options==null || document.chart_options.chart_type[1].checked)
		draw_bar_chart(chart_graphics, width, height);
	else
		draw_line_chart(chart_graphics, width, height);
		
	
	for(var i = 0; i < g_chart_close.length; i++){
		var vol = Math.round(g_chart_volume[i] / vol_pixel_step);
		volume_graphics.setColor(g_volume_color);
		volume_graphics.drawLine(g_chart_mapper[i], height - vol - g_chart_margin, 
								 g_chart_mapper[i], height - g_chart_margin);
	}

	chart_graphics.paint();
	volume_graphics.paint();
}
function draw_grid(id, width, height)
{
	var graphics = get_jsgraphics(id);
	graphics.clear();
	//graphics.setPrintable(true);
	graphics.setColor(g_grid_color);
	graphics.setStroke(g_chart_border);
	
	graphics.drawRect(g_chart_left_margin, g_chart_margin, 
					  width - g_chart_margin - g_chart_left_margin, 
					  height - g_chart_margin * 2);

	graphics.setStroke(1);
	
	//LOG
	var step = get_grid_step(g_max_price, g_min_price, 10);
	g_max_price = Math.round((g_max_price + (step/2)) / step) * step;
	g_min_price = Math.round((g_min_price - (step/2)) / step) * step;
	
	graphics.setColor(g_text_color);
	graphics.drawStringRect(g_max_price, 0,  g_chart_margin - 5, g_chart_left_margin - 5, "right");
	graphics.drawStringRect(g_min_price, 0,  height - g_chart_margin - 5, g_chart_left_margin - 5, "right");
	
	var pixel_step = ((Math.log(g_max_price) - Math.log(g_min_price))/Math.LN10) / (height - g_chart_margin * 2);
	
	for(var i = g_min_price + step; i < g_max_price; i += step){
		
		var y_value = ((Math.log(i) - Math.log(g_min_price))/Math.LN10)/pixel_step;
		if(y_value >= height - g_chart_margin)
			continue;
		y_value = height - g_chart_margin - y_value;
		
		graphics.setColor(g_grid_color);
		graphics.drawLine(g_chart_left_margin, y_value, width - g_chart_margin, y_value);
		
		graphics.setColor(g_text_color);
		graphics.drawStringRect(Math.round(i * 1000)/1000, 0,  y_value - 5, 
								g_chart_left_margin - 5, "right");
	}
	
	
	var pixel_step =  (width - g_chart_margin - g_chart_left_margin) / g_chart_date.length;
	var previous_month = g_chart_date[g_chart_date.length - 1].getMonth();
	
	for(var i = 0; i < g_chart_date.length; i ++){
		if(previous_month != g_chart_date[g_chart_date.length - 1 - i].getMonth()){
			
			previous_month = g_chart_date[g_chart_date.length - 1 - i].getMonth();
			
			graphics.setColor(g_grid_color);
			graphics.drawLine((i + 1) * pixel_step + g_chart_left_margin, 
							  g_chart_margin, 
							  (i + 1) * pixel_step + g_chart_left_margin, 
							  height - g_chart_margin);

			graphics.setColor(g_text_color);
			graphics.drawStringRect(MONTH_STRING[previous_month], (i + 1) * pixel_step + g_chart_left_margin - 35,  
									height - g_chart_margin + 5,  70 , "center");
		}
	}

	
	graphics.setColor(g_text_color);
	
	graphics.setFont("verdana","10px",Font.BOLD);
	graphics.drawStringRect("Copyright 2006 www.cashmain.com. All Rights Reserved",
							g_chart_left_margin, 5, width - g_chart_left_margin - g_chart_margin,  
							"right");
	graphics.paint();
}


function get_subnode_value(element, tagName)
{
	var elements = element.getElementsByTagName(tagName);
	if(elements.length == 1 && elements[0].getFirstChild() != null)
		return elements[0].getFirstChild().getNodeValue();
	else
		return null;
}
function get_bound_prices()
{
	g_max_price = -1;
	g_min_price = -1;
	for(var i = 0 ; i < g_chart_close.length; i++){
		if(g_max_price == -1) g_max_price = g_chart_open[i];
		if(g_chart_open[i] > g_max_price) g_max_price = g_chart_open[i];
		if(g_chart_high[i] > g_max_price) g_max_price = g_chart_high[i];
		if(g_chart_low[i] > g_max_price) g_max_price = g_chart_low[i];
		if(g_chart_close[i] > g_max_price) g_max_price = g_chart_close[i];
		
		if(g_min_price == -1) g_min_price = g_chart_open[i];
		if(g_chart_open[i] < g_min_price) g_min_price = g_chart_open[i];
		if(g_chart_high[i] < g_min_price) g_min_price = g_chart_high[i];
		if(g_chart_low[i] < g_min_price) g_min_price = g_chart_low[i];
		if(g_chart_close[i] < g_min_price) g_min_price = g_chart_close[i];
	}
	g_max_volume = -1;
	for(var i = 0 ; i < g_chart_volume.length; i++){
		if(g_max_volume == -1) g_max_volume = g_chart_volume[i];
		if(g_chart_volume[i] > g_max_volume) g_max_volume = g_chart_volume[i];
	}
}

function parse_date(str)
{
	var temp = str.split("-");
	var dd, mm, yy;
	dd = parseInt(temp[2], 10);
	mm = parseInt(temp[1], 10) - 1;

	yy = parseInt(temp[0], 10);
	return new Date(yy, mm, dd);
}


function parse_date_version_1(str)
{
	var temp = str.split("-");
	var dd, mm, yy;
	dd = parseInt(temp[0], 10);

	for(var i = 0; i < MONTH_STRING.length; i++)
		if(temp[1] == MONTH_STRING[i]){
			mm = i; break;
		}

	yy = parseInt(temp[2], 10);
	return new Date(yy, mm, dd);
}

function parse_data(data)
{
	if(!data || data.length == 0 || data == "N/A"){
		return;
	}else{
		var lines = data.split("\n");
		g_symbol = lines[0];
		display_symbol(g_symbol);
		
		g_chart_date = new Array();
		g_chart_open = new Array();
		g_chart_high = new Array();
		g_chart_low = new Array();
		g_chart_close = new Array();
		g_chart_volume = new Array();
		
		for(var i = 1 ; i < lines.length; i++){
			if(lines[i].length == 0) continue;
			var values = lines[i].split(":");
			
			g_chart_date[g_chart_date.length] = parse_date(values[0]);
			g_chart_open[g_chart_open.length] = parseFloat(values[1]);
			g_chart_high[g_chart_high.length] = parseFloat(values[2]);
			g_chart_low[g_chart_low.length] = parseFloat(values[3]);
			g_chart_close[g_chart_close.length] = parseFloat(values[4]);
			g_chart_volume[g_chart_volume.length] = parseFloat(values[5]);
			
		}
		get_bound_prices();
	}
}
function http_callback(data, arg1, arg2)
{
	var div = document.getElementById("gridline");
	while(div.childNodes.length)
		div.removeChild(div.firstChild);
	parse_data(data);
	
	if(!g_chart_date || g_chart_date.length == 0){
		div.appendChild(document.createTextNode("Fail to retrieve symbol - " + arg1));
		return;
	}
	
	draw_grid("gridline",g_chart_width,g_chart_height);
	draw_chart("chart","volume",g_chart_width,g_chart_height);
	
	var extendedChart = document.getElementById("extendedChart");
	
	if(extendedChart != null && extendedChart.value == "rsi9")
		draw_rsi("extended", g_chart_width,g_extended_height, 9);
	else if(extendedChart != null && extendedChart.value == "rsi14")
		draw_rsi("extended", g_chart_width,g_extended_height, 14);
	else if(extendedChart != null && extendedChart.value == "macd")
		draw_macd("extended", g_chart_width,g_extended_height);
	
	on_ma10_click();
	on_ma50_click();
	
	
	draw_persisted_lines(g_chart_width,g_chart_height);
	display_direct_link();
	
	var request = getXMLHTTPRequest();
	if (request){
		request.onreadystatechange = function(){};
		request.open("POST" , "webfunctions/wf_log.php", true);
		request.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
		request.send("data=sharechart/" + g_symbol);
	}
	
}

function load_symbol(data)
{
	get_jsgraphics("gridline").clear();
	get_jsgraphics("chart").clear();
	get_jsgraphics("volume").clear();
	get_jsgraphics("ma").clear();
	
	var div = document.getElementById("gridline");
	var symbol;
	if(data == null){
		var symbol = document.getElementById("symbol");
		if(symbol == null)
			return;
		symbol = symbol.value;
	}else
		symbol = data;
	
	while(div.childNodes.length)
		div.removeChild(div.firstChild);

	div.appendChild(document.createTextNode("Loading " + symbol + ", Please wait a while......"));
	var now = new Date();
	var param;
	if(now.getYear() < 1900)
		param = "symbol=" + symbol + "&sy=" + (now.getYear() - 1 + 1900) + 
				 					"&sm=" + (now.getMonth() + 1) + 
				 					"&sd=" + now.getDate() +
				 					"&ey=" + (now.getYear() + 1900) + 
				 					"&em=" + (now.getMonth() + 1) + 
				 					"ed=" + now.getDate();
	else
		param = "symbol=" + symbol + "&sy=" + (now.getYear() - 1) + 
				 					"&sm=" + (now.getMonth() + 1) + 
				 					"&sd=" + now.getDate() +
				 					"&ey=" + (now.getYear()) + 
				 					"&em=" + (now.getMonth() + 1) + 
				 					"ed=" + now.getDate();
				 					
	http_request("webfunctions/wf_history_quote.php",  param,
				 "POST", http_callback, symbol, null);
}


function interactive_onclick(e)
{
	if( document.chart_options==null || 
		document.chart_options.mode[0].checked){
		if(g_cursor_hold)
			g_cursor_hold = false;
		else
			g_cursor_hold = true;
	}else{
		var posx = 0;
		var posy = 0;
		if (!e) 
			var e = window.event;
		if (e.layerX || e.layerY){
			posx = e.layerX;
			posy = e.layerY;
		}else if (e.offsetX || e.offsetY){
			posx = e.offsetX;
			posy = e.offsetY;
		}
		basepoint(posx, posy, g_chart_width,g_chart_height);
	}
}

function extended_interactive_onclick(e)
{
	if( document.chart_options==null || 
		document.chart_options.mode[0].checked){
		if(g_cursor_hold)
			g_cursor_hold = false;
		else
			g_cursor_hold = true;
	}
}
function extended_interactive_onmousemove(e)
{
	var posx = 0;
	var posy = 0;
	if (!e) 
		var e = window.event;
	if (e.layerX || e.layerY){
		posx = e.layerX;
		posy = e.layerY;
	}else if (e.offsetX || e.offsetY){
		posx = e.offsetX;
		posy = e.offsetY;
	}
	
	if(document.chart_options){
		if(document.chart_options.mode[0].checked){
			if(g_cursor_hold) return;
			cursor(posx, posy, g_chart_width,g_chart_height);
		}
	}else{
		if(g_cursor_hold) return;
		cursor(posx, posy, g_chart_width,g_chart_height);
	}
}
function interactive_onmousemove(e)
{
	var posx = 0;
	var posy = 0;
	if (!e) 
		var e = window.event;
	if (e.layerX || e.layerY){
		posx = e.layerX;
		posy = e.layerY;
	}else if (e.offsetX || e.offsetY){
		posx = e.offsetX;
		posy = e.offsetY;
	}
	
	if(document.chart_options){
		if(document.chart_options.mode[0].checked){
			if(g_cursor_hold) return;
			cursor(posx, posy, g_chart_width,g_chart_height);
		}else if(document.chart_options.mode[1].checked)
			lines(posx, posy, g_chart_width,g_chart_height);		
	}else{
		if(g_cursor_hold) return;
		cursor(posx, posy, g_chart_width,g_chart_height);
	}
}

function symbol_onkeypress(e)
{
	if (!e){
		e = window.event;
	}
	if(e){
		if (e.keyCode) 
			code = e.keyCode;
		else if (e.which) 
			code = e.which;

		if(code == 13)
			load_symbol(null);
	}
}
function on_ma10_click()
{
	if(g_chart_close == null){
		return;
	}
	var ma10 = document.getElementById("MA_10_ENABLE");
	if(ma10 == null)
		return;
	if(ma10.checked){
		g_chart_ma10 = calculate_ema(10, g_chart_close.length, null);
		draw_ma("ma", g_chart_width,g_chart_height);
	}else{
		g_chart_ma10 = null;
		draw_ma("ma", g_chart_width,g_chart_height);
	}
}

function on_ma50_click()
{
	if(g_chart_close == null)
		return;
	var ma50 = document.getElementById("MA_50_ENABLE");
	if(ma50 == null)
		return;
	if(ma50.checked){
		g_chart_ma50 = calculate_ema(50, g_chart_close.length, null);
		draw_ma("ma", g_chart_width,g_chart_height);
	}else{
		g_chart_ma50 = null;
		draw_ma("ma", g_chart_width,g_chart_height);
	}
}

function extendedChart_onChange()
{
	var extendedChart = document.getElementById("extendedChart");
	if(extendedChart == null) return;
	if(extendedChart.value == "rsi9")
		draw_rsi("extended", g_chart_width,g_extended_height, 9);
	else if(extendedChart.value == "rsi14")
		draw_rsi("extended", g_chart_width,g_extended_height, 14);
	else if(extendedChart.value == "macd")
		draw_macd("extended", g_chart_width,g_extended_height);
	else{
		var graphics = get_jsgraphics("extended");
		graphics.clear();
		graphics.paint();
		
		graphics = get_jsgraphics("extended_interactive_draw");
		graphics.clear();
		graphics.paint();
	}
}

function chart_type_onChange()
{
	if(g_chart_close == null || g_chart_close.length==0) return;
	var graphics = get_jsgraphics("chart");
	graphics.clear();
	if(document.chart_options==null || document.chart_options.chart_type[1].checked)
		draw_bar_chart(graphics, g_chart_width, g_chart_height);
	else
		draw_line_chart(graphics, g_chart_width, g_chart_height);
	graphics.paint();
}


