/* This notice must remain at all times.

graph.js
Copyright (c) Balamurugan S, 2005. sbalamurugan @ hotmail.com
Development support by Jexp, Inc http://www.jexp.com 

This package is free software. It is distributed under GPL - legalese removed, it means that you can use this for any purpose, but cannot charge for this software. Any enhancements you make to this piece of code, should be made available free to the general public! 

Latest version can be downloaded from http://www.sbmkpm.com

This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  

line.js provides a simple mechanism to draw line graphs. It  uses 
wz_jsgraphics.js  which is copyright of its author. 

Usage:
var g = new line_graph();
g.add("title1",value);
g.add("title2",value2);

g.render("canvas_name", "graph title");

//where canvas_name is a div defined INSIDE body tag 
<body>
<div id="canvas_name" style="overflow: auto; position:relative;height:300px;width:400px;"></div>


*/

hD="0123456789ABCDEF";

function d2h(d) 
{
 var h = hD.substr(d&15,1);
 while(d>15) {d>>=4;h=hD.substr(d&15,1)+h;}
 return h;
}

function h2d(h) 
{
 return parseInt(h,16);
}

function line_graph()
{
 this.ct = 0;
 
 this.data      = new Array();
 this.x_name    = new Array();
 this.x_color = new Array();
 this.scale = 1;
 this.titleFrequency = 1;
 this.max       = -64000; //MAX INT
 this.min       = 64000;

 this.c_array = new Array();
 this.c_array[0] = new Array(255, 192, 95);
 this.c_array[1] = new Array(80, 127, 175);
 this.c_array[2] = new Array(159, 87, 112);
 this.c_array[3] = new Array(111, 120, 96);
 this.c_array[4] = new Array(224, 119, 96);
 this.c_array[5] = new Array(80, 159, 144);
 this.c_array[6] = new Array(207, 88, 95);
 this.c_array[7] = new Array(64, 135, 96);
 this.c_array[8] = new Array(239, 160, 95);
 this.c_array[9] = new Array(144, 151, 80);
 this.c_array[10] = new Array(255, 136, 80);

 this.getColor = function()
  {
   if(this.ct >= (this.c_array.length-1))
      this.ct = 0;
   else
      this.ct++;

   return "#" + d2h(this.c_array[this.ct][0]) + d2h(this.c_array[this.ct][1]) + d2h(this.c_array[this.ct][2]);
  }

 this.setTitleFrequency = function(frequency)
 {
    this.titleFrequency = frequency;
 }

 this.setScale = function(scale)
  {
   this.scale  = scale;
  }

  this.add = function(x_name, value, color) {
      value = parseFloat(value, 10); //*this.scale;

      this.x_name.push(x_name);
      this.data.push(parseFloat(value, 10));      
      this.x_color.push(color);

      if (value > this.max)
          this.max = parseFloat(value, 10);
      if ((value < this.min) && (value != -99999))
          this.min = parseFloat(value, 10);

  }

 this.clear = function()
 {
    this.max       = -64000; //MAX INT
    this.min       = 64000;    
    while (this.data.length > 0)
      this.data.pop();
    while (this.x_name.length > 0)
      this.x_name.pop();

 }

 this.render = function(canvas, ForecastTitle, ActualTitle, wind, symbol, startatzero, textwidth, width, height) {
     var jg = new jsGraphics(canvas, wind);

     jg.setColor("white");
     jg.fillRect(1, 1, width, height);


     var canvasGapLeft = 40;
     var canvasGapRight = 5;
     var canvasGapTop = 14;
     var canvasGapBottom = 30;

     var canvasWidth = width - (canvasGapLeft + canvasGapRight);
     var canvasHeight = height - (canvasGapTop + canvasGapBottom);

     var canvasX = canvasGapLeft;
     var canvasY = canvasGapTop;



     var tmax = parseFloat(this.max);
     tmax = (parseInt(tmax / 5) * 5) + 5;
     var tmin = parseFloat(this.min);
     if (tmin < 0)
         tmin = (parseInt(tmin / 5) * 5) - 5;
     else if (startatzero == true)
         tmin = 0;
     else
         tmin = (parseInt(tmin / 5) * 5);
     var maxRange = parseFloat(tmax - tmin);


     var itemGap = canvasHeight / maxRange;
     verticalLines = Math.ceil(canvasHeight / itemGap);
     var displayScale = tmax;
     lineStartY = canvasGapTop;

     jg.setFont("Calibri", "8pt", "normal");

     jg.setColor("black");
     jg.drawStringRect(ForecastTitle, 396, lineStartY - 12, 100, "center");
     jg.drawStringRect(ActualTitle, 200, lineStartY - 12, 100, "left");


     for (i = 0; i <= verticalLines; i++) {

         if (i % (verticalLines / 5) == 0) {
             jg.setColor("silver");
             jg.drawLine(canvasX, lineStartY, canvasX + canvasWidth - 1, lineStartY);
             jg.setColor("black");
             jg.drawStringRect(displayScale.toFixed(0) + symbol, 2, lineStartY - ((itemGap / 2) + 4), textwidth, "right");
             displayScale -= (verticalLines / 5);
         }
         lineStartY += itemGap;
     }

     var columnWidth = canvasWidth / this.data.length;

     var x = canvasX;
     var oldX = x;
     var oldY = 0; // heightYMin+(heightMax - Math.round((this.data[0]-tmin)*heightMax/maxRange));
     var value = this.data[0];
     var columnHeight = Math.round((value - tmin) * canvasHeight / maxRange);
     var columnStartY = canvasY + canvasHeight - (columnHeight);


     var over24 = false;
     for (i = 0; i < this.data.length; i++) {
         if (this.data[i] == -99999) {
         }
         else {
             // Draw the lines;
             jg.setStroke(2);

             var value = this.data[i];
             var columnHeight = Math.round((value - tmin) * canvasHeight / maxRange);
             if (i == 24) {
                 columnStartY = canvasY + canvasHeight - (columnHeight);
                 jg.setStroke(1);
                 jg.setColor("silver");
                 jg.drawLine(x, canvasGapTop, x, 150);
                 over24 = true;
                 this.x_color[i] = "purple";
             }
             else 
             if (i >= 1) {
                 columnStartY = canvasY + canvasHeight - (columnHeight);

                 jg.setColor("gray");
                 jg.drawLine(oldX + (columnWidth / 2) + 1, oldY + 1, x + (columnWidth / 2) + 1, columnStartY + 1);

                 //jg.setColor("maroon");
                 jg.setColor(this.x_color[i]);
                 jg.drawLine(oldX + (columnWidth / 2), oldY, x + (columnWidth / 2), columnStartY);
             }
         }

         jg.setColor("black");
         if (i % this.titleFrequency == 0)
             jg.drawStringRect(this.x_name[i], x, canvasY + canvasHeight + 2, columnWidth * this.titleFrequency, "center");

         oldX = x;
         oldY = columnStartY;
         x = x + columnWidth;

     }
     jg.paint();
 }
}
