/*
This code was created by the New Hampshire Housing and Finance Authority. 
Use of any part of this code is prohibited without written permission.
http://www.nhhfa.org
Created: 12/2006
By: Sean Vickers
*/
function column_graph(dataSets,setNames) {
   this.maxValue  = 0;
   this.minValue  = 999999999;
   this.data	  = new Array();
   this.na		  = new Array();
   this.label     = new Array();
   this.color	  = new Array("#6f80ce",
   							  "#8e3e81",
							  "#ffffcc",
							  "#91c8bb",
							  "purple",
							  "gray",
							  "blue",
							  "lightblue",
							  "tan",
							  "lime");
							
   if (typeof(dataSets) == "number") var ds = dataSets;
   else var ds = 1;
   
   if (setNames) {
      this.setName = new Array();
	  for(var i=0; i<ds; i++) {
	     if(setNames.indexOf("|")>=0) {
		    this.setName.push(setNames.substring(0,setNames.indexOf("|")));
			setNames = setNames.substring(setNames.indexOf("|")+1);
		 }
		 else this.setName.push(setNames);
	  }
   }
   
   for(var i=0; i<ds; i++) {
      this.data[i]  = new Array();
	  this.na[i]	= new Array();
	  this.label[i] = new Array();
   }

   this.add = function(name, value, set) {
      if(!name) this.label[set].push("N/A");
      else this.label[set].push(name);  
	  if(!value) {
	  	this.data[set].push(0);
		this.na[set].push(1);
	  } else if(value.toString() == "Infinity") {
	  	this.data[set].push(0);
		this.na[set].push(1);	  	
	  } else {
	  	this.data[set].push(Math.round(value*100)/100);  
		this.na[set].push(0);
      	if(value > this.maxValue) this.maxValue = Math.round(value);
	  	if(value < this.minValue) this.minValue = Math.round(value);
	  }
   }							

   this.build = function(myDiv, chartTitle, chartHeight, columnWidth, preLabel, postLabel, moveLedgen, useMin) {
      var jg = new jsGraphics(myDiv);

	  /* Chart Height  */
      if (typeof(chartHeight) == "number") var h = chartHeight;
      else var h = 300;	   	   
	   
	  /* Width of Columns  */
      if (typeof(columnWidth) == "number") var dw = columnWidth;
      else var dw = 35;			
	  
	  /* Move Ledgen  */
      if (typeof(moveLedgen) == "number") var ml = moveLedgen;
      else var ml = 0;			     
	  
	  if(!preLabel) preLabel = "";
	  if(!postLabel) postLabel = "";
	   
	  if (this.minValue < 0) useMin = "Yes"; 
	   
	  /* Y Axis Starting Value */
	  var mySign = 1;
      if (useMin == "Yes") {
		  var myMin = Math.round(this.minValue*100)/100;
		  var minLen = myMin.toString().length;
		  if(this.minValue<0) {
		  	minLen = minLen - 1;
			minSign = -1;
			var newMin = Math.pow(10,(minLen-1))
			if(newMin==1) newMin = 0;
		    while(newMin<=(myMin*minSign)) {
		  	  if(newMin>99) newMin = newMin+(Math.pow(10,(minLen-1))/2);
			  else newMin = newMin + 5;
		    }  
			if (newMin <= 5 && newMin > 0) newMin = 5;
		    else if (newMin <= 10 && newMin > 0) newMin = 10; 
		    newMin = newMin*minSign; 			
		  } else {
		    var newMin = Math.pow(10,(minLen-1))
		    while(newMin<myMin) {
		  	  newMin = newMin+(Math.pow(10,(minLen-1))/2);
		    }  
			newMin = newMin-(Math.pow(10,(minLen-1))/2);
		    if (newMin < 0) newMin = 0;
		  }
      } else var newMin = 0;		   

	  /* Max Value on Y Axis */	 
	  var myMax = this.maxValue;
	  if(myMax<5) var newMax = 5;
	  else if (myMax<10) var newMax = 10;
	  else {
		  var maxLen = myMax.toString().length;
		  var newMax = Math.pow(10,(maxLen-1))
		  while(newMax<=myMax) {
		      if(newMax>99) newMax = Math.round(newMax+(Math.pow(10,(maxLen-1))/2));
			  else newMax = newMax + 10;
		  } 
	  }

	  /* Adjust newMin, newMax, and number of Markers */
	  if(newMax<=10) var yl=5; 
	  else if(newMax>=100) var yl=10;
	  else if((newMax/10)>=5) var yl=Math.round(newMax/10);
	  else var yl=Math.round(newMax/5);		  

	  if(newMin<0 && ((-1*newMin) % (newMax/yl) == 0)) {
	    yl = yl + Math.round(-1*newMin/(newMax/yl));
	  } else if (newMin<0 && (newMax/yl)>=(-1*newMin)) {
	  	newMin = -1*newMax/yl;
		yl = yl+1;
	  } else if(newMin<0){
	  	while((-1*newMin) % (newMax/yl) != 0) {
		   newMin = newMin - 1;
		}
		yl = yl + Math.round(-1*newMin/(newMax/yl));
	  }
	  
	  if(newMin == -150 && newMax == 5) {
	  	 newMin = -100;
		 newMax = 10;
		 yl = 11;
	  }	  
	  
	  var span = newMax - newMin;	  
	  
      /* Where Bars Start On X Axis */
      if(newMax < 1000000) {
         var sx = 65;
         var xx = 10;
      } else {
      	 var sx = 75;
       	 var xx = 20;
      } 
	   
      var sx0		= sx
      var shadow 	= 3;
      var fnt    	= 10;  
	  var zVal		= h+20;     

      /* Length of X Axis */
      var rtmax = sx + xx + ((dw*ds)+Math.round((dw/2))+shadow)*(this.data[0].length) - 15;

	  /* Draw Graph Background */
	  jg.setColor("#c0c0c0");
	  jg.fillRect((sx-10),20,rtmax-(sx-10),h);		  
	  
      /* Draw Max Value Markers */
      jg.setColor("black");
      jg.drawLine((sx-10),Math.round((0))+20,rtmax,Math.round((0))+20); /* Max Data Point Line */
      if(newMax < 1000000) {
         var yLabel = "<div style='width:45px; text-align:right;'>" + preLabel +
		  			  addCommas((Math.round(newMax - (0))).toString()) + postLabel + "</div>";
      } else {
         var yLabel = "<div style='width:55px; text-align:right;'>" + preLabel +	 
		              addCommas((Math.round(newMax - (0))).toString()) + postLabel + "</div>";
      }
      jg.setFont("Verdana", fnt,  Font.BOLD);
      jg.drawString(yLabel,4,Math.round(0)+14);
	  /******/ 
	   
	  var linesAbove = Math.round((newMax/span)*yl);
	  lineDiv = h*newMax/span/linesAbove;
	  var linesBelow = Math.round(((-1*newMin)/span)*yl);
 
	  /* Draw Value Markers */	
      for(var i=0; i<yl; i++) {
         if(newMax < 1000000) {
            var yLabel = "<div style='width:45px; text-align:right;'>" + preLabel +
		  	  		     addCommas(Math.round(newMax-(newMax/linesAbove*(i+1))).toString()) + postLabel + "</div>";
         } else {
            var yLabel = "<div style='width:55px; text-align:right;'>" + preLabel +	 
		                 addCommas(Math.round(newMax-(newMax/linesAbove*(i+1))).toString()) + postLabel + "</div>";
         }
         jg.setFont("Verdana", fnt,  Font.BOLD);
         jg.drawString(yLabel,4,Math.round((lineDiv*(i+1))-2)+14);
         jg.drawLine((sx-10),Math.round(lineDiv*(i+1))+20,rtmax,Math.round(lineDiv*(i+1))+20);  
		 if(Math.round(newMax-Math.round(newMax/linesAbove*(i+1))) == 0)
		 	zVal = Math.round(lineDiv*(i+1))+20;     		
      }
 
	  /* Box-in Chart */
      jg.drawLine(rtmax,Math.round((0))+20,rtmax,Math.round((h))+20);
      jg.drawLine((sx-10),Math.round((0))+20,(sx-10),Math.round((h))+20);

      /* Draw Columns */
      for(var i=0; i<this.data[0].length; i++) {
	     var j=0;
	     while (j<ds) {
            var ht1 = Math.round((this.data[j][i]-newMin)*h/(newMax-newMin));

		    /* Fix IE bug when ht1=0 */
            var ht2 = (ht1 > 0 ? ht1 : (ht1 == 0 ? 2 : ht1*-1));
            if (ht1 < 0) ht1 = 0;			 

            /* Create Shadow */
			if(this.na[j][i]==0) {
	            jg.setColor("gray");
				if(!(h-ht1+20)) h=h;
				else if(zVal-(h-ht1+20) <= shadow && zVal-(h-ht1+20) > 0) h=h;
				else if(h-ht1+20-zVal <= shadow && h-ht1+20-zVal > 0) h=h;
				else if(h-ht1+20==zVal || h-ht1+20+1==zVal) jg.fillRect(sx+shadow,zVal-2,dw,1);		
				else if(h-ht1+20+shadow < zVal) jg.fillRect(sx+shadow,h-ht1+20+shadow,dw,ht2-(h+20-zVal)-shadow);
				else jg.fillRect(sx+shadow,zVal,dw,-ht2+(h+20-zVal));	
				
			    /* Create Column */
			    jg.setColor(this.color[j]);
				if(!(h-ht1+20)) h=h;
				else if(h-ht1+20==zVal || h-ht1+20+1==zVal) jg.fillRect(sx,zVal-2,dw,2);		
				else if(h-ht1+20 <= zVal) jg.fillRect(sx,h-ht1+20,dw,ht2-(h+20-zVal));
				else jg.fillRect(sx,zVal,dw,-ht2+(h+20-zVal));
				
				/* Outline Column */
	            jg.setColor("black");
				if(!(h-ht1+20)) h=h;
				else if(h-ht1+20==zVal || h-ht1+20+1==zVal) jg.drawRect(sx,zVal-2,dw,2);		
				else if(h-ht1+20-1==zVal) jg.drawRect(sx,zVal,dw,2);	
				else if(h-ht1+20 <= zVal) jg.drawRect(sx,h-ht1+20,dw,ht2-(h+20-zVal));
				else jg.drawRect(sx,zVal,dw,-ht2+(h+20-zVal));
			}
			   
		    /* X Axis Label */
	        jg.setFont("Verdana", fnt,  Font.BOLD);
			if(j==0) jg.drawStringRect(this.label[j][i], sx-(dw/(4*ds)), h+20+5, (dw*ds)+(dw/4), "center");
		 
		    /* Space Between Columns */
	        if((j+1)==ds) sx = sx+dw+Math.round(dw/2)+shadow;
			else sx = sx+dw;

			j=j+1;
		 }		
      }  

	  /* Create Ledgen */
	  if(ds>1) {
         var ledgen = "<div id='ledgen' style='position:relative;padding:2px;border:solid 1px black;" +
		 			  "width:75%;background-color:white;color:black;text-align:center;'>" +
					  "<table cellspacing='0' cellpadding='0'><tr><td><font size='1'>" +
					  "&nbsp;&nbsp;</font></td><td>";
		 for(var i=0; i<ds; i++) {
		    ledgen = ledgen + "<div id='color"+i+"' style='position:relative;width:10px;height:5px;" +
							  "line-height:5px;padding:5px;background-color:" +
							  this.color[i] +
							  ";border:solid 1px black;float:left;'>&nbsp;</div>" +
							  "<div id='text"+i+"' style='position:relative;width:"+(((rtmax)/ds)*.60)+"px;" +
							  "padding:3px;float:left;font-size:10px;font-weight:bold;text-align:left;'>" +
							  this.setName[i] +
							  "</div>";
		 }		  
		 ledgen = ledgen + "</td></tr></table></div>";
         jg.drawStringRect(ledgen, 0, h+50+15+ml, rtmax, "center"); 
	  }	 
	 
	  /* Label X Axis */
      jg.setFont("Verdana", fnt+4,  Font.BOLD);
      jg.drawStringRect(chartTitle, 0, h+fnt+4+15, rtmax, "center");
      jg.paint();        
    }
}

