/*****************************
 iCanChart.js
 HTML5 canvas bar chart API
 Author: Scott Umsted
 Created: August 8, 2009
 *****************************/

function BarChart(){
	
	// values set by calling application
	this.canvasId="";
	this.width=0;
	this.height=0;
	this.title="";
	this.legendy1="";
	this.dataPoints=0; //array
	this.barWidth=0;
	this.threshold=0;
	this.tickCounty1=0;
	this.roundUpy1;
	
	// internal to BarChart
	this.originx=0;
	this.originy=0;
	this.maxx=0;
	this.maxy=0;
	this.scalex=0;
	this.scaley1;
	this.tickx=0;
	this.ticky1=0;

	// methods	
	this.setDefaults=setDefaults;
	this.drawChart=drawChart;
	this.initBarChart=initBarChart;
	this.clearSlate=clearSlate;
	this.drawArtifacts=drawArtifacts;
	this.drawBars=drawBars;
	this.drawY1Legend=drawY1Legend;
	this.drawXLabel=drawXLabel;
	this.drawY1Label=drawY1Label;
	this.drawBar=drawBar;
	this.calculateBoundries=calculateBoundries;
	this.calculateXScale=calculateXScale;
	this.calculateY1Scale=calculateY1Scale;
	this.translate1=translate1;
	this.translatey1=translatey1;
	this.translatex=translatex;
	this.loadDefaultData=loadDefaultData;
	this.canvasElement=canvasElement;
	this.drawLine=drawLine;
	this.drawText=drawText;
	this.drawRectangle=drawRectangle;
}

function setDefaults(){
	this.filename = "BarChart.jpg";
	this.height = 300;
	this.width = 400;
	this.title = "Bar Chart";
	this.legendy1 = "Series 1";
	this.dataPoints = loadDefaultData();
	this.replaceFile = true;
	this.barWidth = 8;
	this.threshold = 50;
	this.tickCounty1 = 5;
	this.tickx = 1;
	this.roundUpy1 = 100;
}

function drawChart(){
    this.clearSlate();

    this.calculateBoundries();
    this.calculateXScale();
    this.calculateY1Scale();

    this.drawBars();
    this.drawArtifacts();
}

function canvasElement(){
	return document.getElementById(this.canvasId).getContext('2d');
}

function initBarChart(_canvasId,_height,_width,_dataPoints,_title,_legendy1){
	this.setDefaults();
	this.canvasId = _canvasId;
    this.dataPoints = _dataPoints;
    this.height = _height;
    this.width = _width;
    this.title = _title;
    this.legendy1 = _legendy1;
    this.drawChart();
}

function clearSlate(){
}

function drawLine(_color,_width,_x1,_y1,_x2,_y2){
	var ctx = this.canvasElement();
	ctx.beginPath();
	ctx.strokeStyle = _color;
	ctx.lineWidth = _width;
	ctx.moveTo(_x1,_y1);
	ctx.lineTo(_x2,_y2);
	ctx.stroke();
	ctx.closePath();
}

function drawRectangle(_color,_x,_y,_height,_width){
	var ctx = this.canvasElement();
	ctx.beginPath();
	ctx.fillStyle = _color;
	ctx.fillRect(_x,_y,_width,_height);
	ctx.fill();
	ctx.closePath();
}

function drawText(_color,_align,_font,_text,_x,_y){
	var ctx = this.canvasElement();
	ctx.beginPath();
	ctx.font = _font;
	ctx.textAlign = _align;
  	ctx.fillStyle = _color;
  	ctx.fillText(_text, _x, _y);
  	ctx.fill();
 	ctx.closePath();
}

function drawArtifacts(){
	var i = 0;

	// Draw the title
	this.drawText("black","center","bold 16pt Arial",this.title,this.width/2, 22);
	
	this.drawLine("black",1,50,this.height-50,50,50);
	this.drawLine("black",1,50,this.height-50,this.width-50,this.height-50);

	// Draw the legends
    this.drawY1Legend(this.legendy1);

    // Create Hash Marks
    for (i = 0; i <= this.scalex; i++)
	{
    	if ((i % this.tickx) == 0)
        {
        	var x;
            x = this.translatex(i);
			this.drawLine("black",1,x,this.originy-2,x,this.originy+2);
        }
    }
	for (i = 0; i <= this.scaley1; i++)
    {
    	if ((i % this.ticky1) == 0)
        {
        	var y;
            y = this.translatey1(i);
            this.drawY1Label(i, i+"");
			this.drawLine("black",1,this.originx-2,y,this.originx+2,y);
        }
    }

    // Draw threshold
    if (this.threshold > 0)
    {
    	this.drawLine("red",1,this.originx,this.translatey1(this.threshold),this.maxx,this.translatey1(this.threshold));
    }
}

function drawBars(){
	var i = 0;
	for (i = 0; i < this.dataPoints.length; i++)
    {
    	var x = i + 1;
        this.drawXLabel(x, this.dataPoints[i].Label);
        this.drawBar(x, this.dataPoints[i].Value);
    }
}

function drawY1Legend(_label){
	var x, y;
    
    y = this.originy + 20;
    x = this.originx - 20;
	
	this.drawText("blue","center","bold 8pt Arial",_label,x,y);
}

function drawXLabel(_x, _label){
    var x, y;
    y = this.originy + 10;
	x = this.translatex(_x);

	this.drawText("black","center","bold 8pt Arial",_label,x,y);
}

function drawY1Label(_y, _label){
	var x, y;
   	y = this.translatey1(_y);
    x = this.originx - 30;

	this.drawText("blue","center","bold 8pt Arial",_label,x,y);
}

function drawBar(_x, _height){
	var x, y, w, h;

	w = 8;
    y = this.translatey1(_height);
    h = this.originy - y;
	x = this.translatex(_x) - w / 2;
	this.drawRectangle("blue",x,y,h,w);
}

function calculateBoundries(){
	this.originx = 50;
    this.originy = this.height - 50;
    this.maxx = this.width - 50;
    this.maxy = 50;
}

function calculateXScale(){
	this.scalex = this.dataPoints.length + 1;
    this.tickx = 1;
}

function calculateY1Scale(){
    var my1 = 0;
    var i = 0;
    for (i = 0; i < this.dataPoints.length; i++)
	{
    	my1 = this.dataPoints[i].Value > my1 ? this.dataPoints[i].Value : my1;
    }

    this.scaley1 = my1 + (this.roundUpy1 - (my1 % this.roundUpy1));
    this.ticky1 = this.scaley1 / this.tickCounty1;
}

function translate1(_x,_y){
    result = new Object();
    result.actualx = translatex(_x);
    result.actualy = translatey1(_y);
    return result;
}

function translatey1(_y){
    return (this.originy - ((this.originy - this.maxy) / this.scaley1) * _y);
}

function translatex(_x){
	return (this.originx + ((this.maxx - this.originx) / this.scalex) * _x);
}

function loadDefaultData(){
	var dps = new Array();
	var i = 0;
    for (i = 0; i < 15; i++)
    {
    	dps[i] = new Object();
        dps[i].Label = "#" + i;
    	dps[i].Value = i * 10;
    }
	return dps;
}

