/*!
 * Stock charts library for g.RaphaÃ«l
 *
 * Copyright (c) 2010 Hugo Schmitt
 * Licensed under the MIT (http://www.opensource.org/licenses/mit-license.php) license.
 */
	
function candlechart (x, y, width, height, quotes, q_offset, q_len) {

	var paper = this,
	 	gutter = 40,
        chart = this.set();

    var minx = 0,
        maxx = q_len,
        ydim = quotesDim(quotes, q_offset, q_len),
        miny = ydim.from,
        maxy = ydim.to,
        kx = (width - gutter * 2) / ((maxx - minx) || 1),
        ky = (height - gutter * 2) / ((maxy - miny) || 1);
        
   	var cur_col_x = x + gutter;
    var column_width = (width - 2 * gutter) / q_len; 
    var rect_width = column_width*(2/3);
    var rect_x, rect_y, line_x, line_y, line_h;
    
    var red_candles_path = [];
    var green_candles_path = [];

	function quotesDim () {
		function qmax(q) { 
			return Math.max(q.open, q.close, q.low, q.high);
		}
		function qmin(q) { 
			return Math.min(q.open, q.close, q.low, q.high);
		}

		var min = qmin(quotes[q_offset]);
		var max = qmax(quotes[q_offset]);
		
		for (var i=q_offset; i < q_offset+q_len; i++) {
			if (qmin(quotes[i]) < min) {
				min = qmin(quotes[i]);
			}
			if (qmax(quotes[i]) > max) {
				max = qmax(quotes[i]);
			}
		}
		return { from:min, to:max };
	};
	
	function candle_path(line_x, line_y, line_h, rect_x, rect_y, rect_w, rect_h) {
		return ['M',line_x,line_y,'l 0',line_h,'M',rect_x,rect_y,'l 0',rect_h,'l',rect_w,'0','l 0',-rect_h,'l',-rect_w,'0'];
	};
	
	function path2string(p) {
		return p.concat(['z']).join(',');
	}
	
    for (var i=q_offset; i < q_offset+q_len; i++) {
    	var q = quotes[i];
    	rect_x = cur_col_x + rect_width;
    	rect_y = y + gutter + (Math.abs(Math.max(q.open, q.close)-maxy) * ky);
    	line_x = cur_col_x + column_width;
    	line_y = y + gutter + Math.abs(q.high-maxy)*ky;
    	line_h = (q.high-q.low)*ky;
    	
    	if (q.close > q.open) {
    		green_candles_path = green_candles_path.concat(candle_path(line_x, line_y, line_h, rect_x, rect_y, rect_width, Math.abs(q.open-q.close)*ky));
    	}
    	else {
    		red_candles_path = red_candles_path.concat(candle_path(line_x, line_y, line_h, rect_x, rect_y, rect_width, Math.abs(q.open-q.close)*ky));
    	}

    	cur_col_x += column_width;
    }
    
    if (green_candles_path.length > 0) {
	    chart.push(paper.path(path2string(green_candles_path)).attr({fill:"#7e8ca8",stroke:"#7e8ca8"}));
    }
    
    if (red_candles_path.length > 0) {
    	chart.push(paper.path(path2string(red_candles_path)).attr({fill:"#da4b3b",stroke:"#da4b3b"}));
    }

    return chart;
};

Raphael.fn.g.stockchart = function (x, y, width, height, quotes) {
	var paper = this;
	var mini_win_size = 50;
	var gutter = 40;
	var closes = [];
	var days = [];
	var master = null;
	var context;
	
	function px_to_idx (x) {
		return Math.floor(x * (quotes.length / width));
	};
	
	function zoomWindow (zw_x, zw_y, zw_total_width, zw_height, zw_gutter) {
    	var zw_gutter = zw_gutter || 0;
    	var zw_width = mini_win_size;
    	var zw_max_x = zw_total_width - zw_width - zw_gutter;
    	var redsquare = this.rect(zw_max_x, zw_y + zw_gutter, zw_width, zw_height - 2*zw_gutter).attr({fill:'red',opacity:.2})
    			  .mouseover(function(event){this.attr("opacity", .4)})
    			  .mouseout(function(event){this.attr("opacity", .2)})
    			  .drag(
					function (dx, dy) { // move
						var new_x = Math.max(Math.min(this.ox + dx, zw_max_x),zw_x + zw_gutter);
						this.attr('x', new_x);
						
						master.remove();
						master = null;
						
						var slice_beg = px_to_idx(new_x);
						var slice_len = px_to_idx(zw_width);
						master = candlechart.call(paper, x, y, width, height-150, quotes, slice_beg, slice_len);
						
					},
					function () { // start
						this.ox = this.attr("x"); 
						this.attr('opacity',.5);
					},
					function () { // end
						this.attr('opacity',.2);
					});
    	
    	return redsquare;
    }

	for (var i=0; i<quotes.length; i++) {
	    days[i] = i;
	    closes[i] = quotes[i].close;
	}
	
	context = paper.g.linechart(x, height-180, width, 150, days, [closes], {gutter:gutter, shade: true});
	
	redsquare = zoomWindow.call(paper, x, height-180, width, 150, 40);
	
	var slice_beg = px_to_idx(redsquare.attr('x'));
	var slice_len = px_to_idx(mini_win_size);
	master = candlechart.call(paper, x, y, width, height-150, quotes, slice_beg, slice_len);
}

