// Chart constructor:
/////////////////////
// title	: Title for graph
// hlabel	: Label for horizontal axis
// vlabel	: Label for vertical axis
// orientation	: "horizontal" or "vertical"
// hsize        : length of horizontal axis (left and right)
// vsize        : length of vertical axis (up and down)
// barsize	: width/length of bar as a percentage of the axis length
//                it is on divided by the number of bars
// tickimg	: image to use for scale tick
// baseimg	: image to make base of graph
// ticks	: approximate # of ticks to show
// BaseValues	: Display the BaseValues

function Chart (title,hlabel,vlabel,orientation,hsize,vsize,barsize,tickimg,baseimg,ticks,minTick,yAxisEnd,valueLabelsOn,nValuesOn,LabelWidth,BarHeight,SizeFactor,DecimalPlaces) {
// User defined
  this.title       = title;
  this.hlabel      = hlabel;
  this.vlabel      = vlabel;
  this.orientation = orientation;
  this.hsize       = hsize;
  this.vsize       = vsize;
  this.barsize     = barsize;
  this.tickimg     = tickimg;
  this.baseimg     = baseimg;
  this.ticks       = ticks;
  this.minTick     = minTick;
  this.yAxisEnd    = yAxisEnd;
  this.valueLabelsOn = valueLabelsOn;
  this.nValuesOn   = nValuesOn;
  this.LabelWidth  = LabelWidth;
  this.BarHeight   = BarHeight;
  this.SizeFactor  = SizeFactor;
  this.BaseValuesOn =false;
  this.DecimalPlaces=(DecimalPlaces)?DecimalPlaces:2;

// System defined
  this.scale       = new Array();
  this.data        = new Array();
  this.scalesize   = 0;
  this.labelsize   = 0;
  this.scaledelta  = 0;

  this.ScaleTextOn     = false;
  this.ScaleTextValues = new Array();

}

// Data constructor:
////////////////////
// label    : the label to show for the bar
// num      : the number to use (can be int or float)
// img      : the image to use for the bar
// url      : the url for the bar to link to ("-1" for no link)
// nsize    : the number of responses collected for this item

function Data (label, num, clr, img, url, nsize, base, gap, dmsn) {
  this.label = label;
  this.num   = num;
  this.clr   = clr;
  this.img   = img;
  this.url   = url;
  this.nsize = nsize;
  this.base  = base;                   // Added 7/7/2
  this.gap   = gap;                    // Added 7/8/2
  this.dmsn  = dmsn;                   // Added 2/17/3
}


///////////////////////////////////////////////
// Special definitions
var border = 0;

///////////////////////////////////////////////
// __chart : chart to plot
// popup   : 1 or 0
// preinit : if you already have a window to draw to specify it
//           here, otherwise use "__default"
function doChart(__chart,popup,preinit) {
  if(__chart.data.length == 0) { 
    window.document.write("<font size=2>No data to display.</font>")
    return;
  }
  if(popup == 1) {
    if(preinit != "__default") {
      drawChart(__chart,preinit);
    } else {
      __popup = open("","__popup","width=400,height=300");
      __popup.document.write("<BODY Bgcolor=#FFFFFF>\n");
      drawChart(__chart,__popup);
      __popup.document.close();
    }
  } else {
    drawChart(__chart,window);
  }
}
///////////////////////////////////////////////

function initChart(__chart,__win) {
  if(__chart.data.length == 0) return;
  var max = __chart.data[0].num;
  var min = __chart.data[0].num;
  
  for(var i=0; i<(__chart.data.length); i++) {
    if(max <= __chart.data[i].num) max = __chart.data[i].num;
    if(min >= __chart.data[i].num && min > 0) min = __chart.data[i].num;
  }
  computeAutoScale(max,min,__chart);
  if(__chart.orientation == "vertical") {
    __chart.labelsize = __chart.hsize / __chart.data.length
  } else {
    __chart.labelsize = __chart.vsize / __chart.data.length
  }
  __chart.labelsize = 25
  __chart.barsize = (__chart.barsize / 100) * __chart.labelsize;
  if(__chart.BarHeight) __chart.barsize=__chart.BarHeight;

}

function drawChart(__chart,__win) {
  border=0
  initChart(__chart,__win);
  if(__chart.title) doTitle(__chart,__win);
  __win.document.write("<TABLE Border=" + border + " Cellpadding=0 Cellspacing=0><TR>");
  if(__chart.vlabel) doVlabel(__chart,__win);
  doMainGr(__chart,__win);
  __win.document.write("</TABLE>");
  doFooter(__chart,__win);
}

// Finds decent scaling for an array of numbers
function computeAutoScale(max,min,__chart) {

  if(max == min) {
    max+=1;
    min-=1;
  }

  var ticks = __chart.ticks;

  range = nicenum(max - min, 0);
  casd = nicenum(range/(ticks - 1), 1);
  if( __chart.minTick > 0 ) casd =__chart.minTick;
  graphmin = Math.floor(min/casd)*casd;
  if(graphmin>0) graphmin = 0;                                         // Was Zero
//graphmin=1
  graphmax = Math.ceil(max/casd)*casd;
  if( __chart.yAxisEnd ) graphmax =__chart.yAxisEnd;
//  if( __chart.yAxisEnd && __chart.orientation == "horizontal" ) graphmax =__chart.yAxisEnd;
  if(graphmax<0) graphmax = 0;
  nfrac = Math.max( -Math.floor(Math.log(casd)/Math.E), 0);
  i = 0;
  for( x=graphmin; x < (graphmax+0.5*casd); x+=casd ) {
    __chart.scale[i] = doRound(x,nfrac,"after");
    i++;
  }
  __chart.scaledelta = casd;

  // Make the chart stay an apprx size
  if(__chart.orientation == "vertical")
    __chart.scalesize = doRound(__chart.vsize / __chart.scale.length,0, "after");
  else
    __chart.scalesize = doRound(__chart.hsize / __chart.scale.length,0, "after");

  if(__chart.SizeFactor) __chart.scalesize*=__chart.SizeFactor;

}

// Finds a nice number
function nicenum(x,round) {
  var expt = Math.floor(Math.log(x)/Math.E);
  var f = x/Math.pow(10,expt);

  var nf;
  if(round == 1) {
    if (f< 1.5) nf = 1.;
    else if (f<3) nf = 2.;
    else if (f<7) nf = 5.;
    else nf = 10.;
  } else {
    if (f<= 1) nf = 1.;
    else if (f<=2) nf = 2.;
    else if (f<=5) nf = 5.;
    else nf = 10.;
  }
  return nf*Math.pow(10, expt);
}

// Rounds 'num' to 'p' places 'after'/'before' the decimal point
function doRound(num,p,point) {
  if(point == "after" && p==0) {
    num=Math.round(num);
    return num;
  }
  p = Math.pow(10,p);
  if(point == "after")
    num = Math.round(parseFloat(num)*(p))/(p);
  else
    num = Math.round(parseFloat(num)/(p))*(p);
  return num;
}
function doValueRound(preValue,decPlaces) {
  preFactor=Math.pow(10,decPlaces)
  preValue=Math.round(preValue*preFactor)/preFactor;
  preValue=preValue+'';
  if(preValue.indexOf(".")<0 && decPlaces>0){ preValue=preValue+"."; }
  numZeros=decPlaces-(preValue.length-(preValue.indexOf('.')+1));
  for(;numZeros>0;numZeros--) { preValue=preValue+'0'; }
  return preValue
}

function doTitle(__chart,__win) {
  var ChartTitleWidth=((__chart.SizeFactor<1 && __chart.SizeFactor>0)?((__chart.hsize+__chart.LabelWidth)*__chart.SizeFactor):(__chart.hsize+__chart.LabelWidth)); 
  __win.document.write(
    "<TABLE Width=" + ChartTitleWidth + " Border=" + border + " Cellpadding=3 Cellspacing=0><TR>" +
    "<TD Align=center><FONT Size=4><B>" + __chart.title + "</B></FONT></TD>" +
    "</TR></TABLE>"
  );
}

function doVlabel(__chart,__win) {
  __win.document.write(
    "<TD Valign=middle rowspan="+__chart.data.length+" >" +
    "<TABLE Height=" + __chart.vsize + " Border=" + border +
    " Cellpadding=3 Cellspacing=0><TR>" +
    "<TD Valign=middle><B>" + __chart.vlabel + "</B></TD>" +
    "</TR></TABLE></TD>"
  );
}

function doMainGr(__chart,__win) {
  var lessthanzero = 0;
  var morethanzero = 0;

  for(i=0; i<__chart.scale.length; i++) {
    if(__chart.scale[i] < 0)
      lessthanzero++;
    else if(__chart.scale[i] > 0)
      morethanzero++;
  }
  var OldBorder
  OldBorder=border
  var NeedToShowHeader
  NeedToShowHeader=false;
  if(__chart.nValuesOn) NeedToShowHeader=true;

  if(NeedToShowHeader==true) {
    var ncols;
    ncols = 3;
    if(__chart.nValuesOn) {
      __win.document.write("<TD Align=left>Item</TD>");
      __win.document.write("<TD WIDTH=1 bgcolor=#000000 ><IMG SRC="+__chart.baseimg+" WIDTH=1></TD><TD align=center>n</TD>");
      ncols+=2;
      if(__chart.valueLabelsOn) {
        __win.document.write("<TD WIDTH=1 bgcolor=#000000 ><IMG SRC="+__chart.baseimg+" WIDTH=1></TD><TD align=center>xBar</TD>");
        ncols+=2;
      }
      __win.document.write("<TD WIDTH=1 bgcolor=#000000 ><IMG SRC="+__chart.baseimg+" WIDTH=1></TD>");
      __win.document.write("<td></td></tr><tr>");
    }
    __win.document.write("<tr><td HEIGHT=1 bgcolor=#000000 COLSPAN="+ncols+"></td></tr><tr>");
  }

  lessthanzero = doRound(lessthanzero * __chart.scalesize,0,'after');
  if(lessthanzero) lessthanzero += doRound(__chart.scalesize/2,0,'after');
  lessthanzero += 1;

  morethanzero = doRound(morethanzero * __chart.scalesize,0,'after');
  if(morethanzero) morethanzero += doRound(__chart.scalesize/2,0,'after');
  morethanzero -= 1;

  var scaledeltas = doRound((__chart.scalesize-1)/2,0,'after');
  for(var i=0; i<__chart.data.length; i++) {
    var bh;
    bh=(__chart.BarHeight)?__chart.BarHeight:__chart.labelsize-4;
    MyPreHref =""; MyPostHref =""; MyImage =""; MyColor = ""; MyBoxStart=""; MyBoxEnd="";
    MyBaseImage ="";
    MyClass=((i%2)==1)?"Odd":"Even";
    if( i > 0 ) __win.document.write("<TR>");
    __win.document.write("<TD Align=right class=\"Label"+MyClass+"\">"+ __chart.data[i].label+"</TD>");
    if(__chart.nValuesOn) {
      __win.document.write("<TD WIDTH=1 bgcolor=#000000 ><IMG SRC="+__chart.baseimg+" WIDTH=1></TD>");
      __win.document.write("<TD Align=right >"+ __chart.data[i].nsize+"</TD>");
      if(__chart.valueLabelsOn) {
        __win.document.write("<TD WIDTH=1 bgcolor=#000000 ><IMG SRC="+__chart.baseimg+" WIDTH=1></TD>");
        __win.document.write("<td>&nbsp;"+__chart.data[i].num+"</TD>")
      }
    }

    __win.document.write("<TD WIDTH=1 bgcolor=#000000 ><IMG SRC="+__chart.baseimg+" WIDTH=1></TD>");
    __win.document.write("<TD Width=" + __chart.hsize + " Valign=center Align=left Height=" + (bh+4) + "  class=\"Bar"+MyClass+"\">");

// Show the bar here
    if(__chart.data[i].num > __chart.scale.length*__chart.scaledelta) { alert('Warning.  Chart Scale has fewer points than the value to be scaled.  Check ScaleAnchors.'); }
    var width = doRound((Math.abs(__chart.data[i].num)*__chart.scalesize)/__chart.scaledelta,0,'after');
    MyBaseImage ="<IMG Border=0 Src=http://www.hr-360.com/images/baseImage.gif Width=" + bh + " Height=" + (bh-2) + ">"
    if(width<1.0) width = 1;
    if( __chart.data[i].img ) MyImage ="<IMG Border=0 Src=" + __chart.data[i].img + " Width=" + width + " Height=" +__chart.barsize + ">"
    if( __chart.data[i].clr ) MyColor = "bgcolor=\"#" + __chart.data[i].clr + "\""; 
    if( __chart.data[i].clr ) MyHideColor = "color=\"#" + __chart.data[i].clr + "\""; 
    if( __chart.data[i].clr ) MyBoxStart = "<table border=1 cellpadding=0 cellspacing=0 height=\""+(bh)+"\" width=\"100%\" ><tr><TD>"; 
    if( __chart.data[i].clr ) MyBoxEnd = "</td></tr></table>"; 
    if( __chart.data[i].url ) { MyPreHref = "<A Href=\"" + __chart.data[i].url + "\">"; MyPostHref= "</A>"; }
    __win.document.write("<TABLE Height="+(bh)+" Border=" + border + " Cellpadding=0 Cellspacing=0><TR>");
    __win.document.write("<TD Align=right Width=" + scaledeltas + " >")
    if(__chart.BaseValuesOn && __chart.valueLabelsOn) {__win.document.write(__chart.data[i].num); }
    __win.document.write("</TD>");  // To offset the bars at zero

    if(__chart.BaseValuesOn && __chart.data[i].base) {
      var bar1; var bar2; var bar3;
      if(__chart.data[i].base < __chart.data[i].num) {
         // Display up to base, then base image, then remainder
        __win.document.write("<TD Align=left Width=" + width + " "+ MyColor +">");
        __win.document.write("<TABLE BORDER=1 CELLPADDING=0 CELLSPACING=0><TR><TD>");
        __win.document.write("<TABLE BORDER=0 CELLPADDING=0 CELLSPACING=0><TR><TD>");
        width = doRound((Math.abs(__chart.data[i].base)*__chart.scalesize)/__chart.scaledelta,0,'after'); if(width<1.0) width = 1;
        bar1="<TD Align=left Width=" + (width-bh/2) + " "+ MyColor +">&nbsp;</TD>"
        bar2="<TD Align=left Width=" + bh + " "+ MyColor +">"+MyBaseImage+"</TD>"
        width = doRound((Math.abs(__chart.data[i].num - __chart.data[i].base)*__chart.scalesize)/__chart.scaledelta,0,'after'); if(width<1.0) width = 1;
        bar3="<TD Align=left Width=" + (width-bh/2) + " "+ MyColor +">&nbsp;</TD></tr></table></td></tr></table></td>"
      } else if(__chart.data[i].base > __chart.data[i].num) {
         // Display num then blank space up to base then base image
        width = doRound((Math.abs(__chart.data[i].num)*__chart.scalesize)/__chart.scaledelta,0,'after'); if(width<1.0) width = 1;
        bar1="<TD Align=left Width=" + width + " "+ MyColor +">"+MyBoxStart+MyPreHref+MyImage+"<font "+MyHideColor+">.</FONT>"+MyPostHref+MyBoxEnd+"</TD>"
        width = doRound((Math.abs(__chart.data[i].base - __chart.data[i].num)*__chart.scalesize)/__chart.scaledelta,0,'after'); if(width<1.0) width = 1;
        bar2="<TD Align=left Width=" + width + " bgcolor=#FFFFFF >&nbsp;</TD>"
        bar3="<TD Align=left Width=" + bh + " bgcolor=#FFFFFF >"+MyBaseImage+"</TD>"
      } else {
         // Display num then base image
        width = doRound((Math.abs(__chart.data[i].num)*__chart.scalesize)/__chart.scaledelta,0,'after'); if(width<1.0) width = 1;
        bar1="<TD Align=left Width=" + width + " "+ MyColor +">"+MyBoxStart+MyPreHref+MyImage+MyPostHref+MyBoxEnd+"</TD>"
        width = bh;
        bar2="<TD Align=left Width=" + width + " " + MyColor + ">"+MyBaseImage+"</TD>"
        width = doRound((Math.abs(__chart.data[i].base - __chart.data[i].num)*__chart.scalesize)/__chart.scaledelta,0,'after'); if(width<1.0) width = 1;
        bar3="<TD Align=left Width=" + width + " bgcolor=#FFFFFF >&nbsp;</TD>"
      }
      __win.document.write(bar1+bar2+bar3);
    } else {
      bar="<TD Align=left Width=" + width + " "+ MyColor +">"+MyBoxStart+MyPreHref+MyImage+MyPostHref+MyBoxEnd+"</TD>"
      __win.document.write(bar);
    }
    if(__chart.valueLabelsOn && !__chart.BaseValuesOn) {
      if(!__chart.nValuesOn) __win.document.write("<td>&nbsp;"+doValueRound(__chart.data[i].num,__chart.DecimalPlaces)+"</TD>")
    }
    __win.document.write("</TR></TABLE>");
// End the bar
    __win.document.write("</TD></TR>");   // End This Row
  }

  __win.document.write("<TR>");
  if(__chart.vlabel) __win.document.write("<TD></TD>");
  LabelWidth=200;
  if(__chart.SizeFactor) LabelWidth*=__chart.SizeFactor;
  if(__chart.LabelWidth) LabelWidth=__chart.LabelWidth;
  __win.document.write("<TD><img src=http://www.hr-360.com/images/spacer.gif height=1 width="+LabelWidth+" border=0></td><TD></td>");

  if(__chart.nValuesOn) {
     __win.document.write("<TD></td><TD></td>");
     if(__chart.valueLabelsOn) __win.document.write("<TD></td><TD></td>");
  }

  __win.document.write("<TD Align=left>");

  __win.document.write("<TABLE Border=" + border + " Cellpadding=0 Cellspacing=0>");
  __win.document.write("<TR>");
  for(var i=0; i<__chart.scale.length; i++) {
    var scaledeltas = Math.round((__chart.scalesize-1)/2,0);
    __win.document.write( "<TD Valign=top Align=center Width=" + __chart.scalesize + ">" );
    __win.document.write( "<TABLE Border=" + border + " Cellpadding=0 Cellspacing=0><TR>" );
    __win.document.write( "<TD Width=" + scaledeltas + " Valign=top><IMG Src=http://www.hr-360.com/jsbc/base.gif width=" + scaledeltas + " Height=1></TD>" );
    __win.document.write( "<TD Width=1 bgcolor=#000000><IMG Src=http://www.hr-360.com/images/spacer.gif width=1 height=5></TD>" );
    __win.document.write( "<TD Witdh=" + scaledeltas + " Valign=top><IMG Src=http://www.hr-360.com/jsbc/base.gif width=" + scaledeltas + " Height=1></TD></TR></TABLE>" );
    __win.document.write( "</TD>" );
  }
  __win.document.write("</TR>");
  __win.document.write("<TR>");
  for(var i=0; i<__chart.scale.length; i++) {
    __win.document.write("<TD Valign=top Align=center Width=" + __chart.scalesize + "><FONT Size=2>" + ((__chart.ScaleTextOn==false)?__chart.scale[i]:__chart.ScaleTextValues[i]) + "</FONT></TD>");
  }
  __win.document.write("</TR>");

  if(__chart.hlabel) {
//    alert(__chart.scale.length);
    __win.document.write("<tr><td valign=center colspan="+((__chart.scale.length*1)+1)+"><TABLE Width=100% Border=0 Cellpadding=3 Cellspacing=0>");
    __win.document.write("<TR><TD Align=center>" + __chart.hlabel + "</TD></TR></TABLE></td></tr>");
  }
  __win.document.write("</TABLE>");
  __win.document.write("</TD>");
  border=OldBorder
}



function doFooter(__chart,__win) {
}

////////////////////////////////////////////////////////////////////////
//
// S O R T I N G    F U N C T I O N S
//
function doCompareLabelsAsc(a, b) {
  if ( a.label < b.label ) return -1;
  if ( a.label > b.label ) return 1;
  return 0;
}
function doCompareLabelsDsc(a, b) {
  if ( a.label < b.label ) return 1;
  if ( a.label > b.label ) return -1;
  return 0;
}
function doCompareValuesAsc(a, b) {
  if ( a.num*1 < b.num*1 ) return -1;
  if ( a.num*1 > b.num*1 ) return 1;
  return 0;
}
function doCompareValuesDsc(a, b) {
  if ( a.num*1 < b.num*1 ) return 1;
  if ( a.num*1 > b.num*1 ) return -1;
  return 0;
}
function doCompareGapAsc(a, b) {
  if ( a.gap < b.gap ) return -1;
  if ( a.gap > b.gap ) return 1;
  return 0;
}
function doCompareGapDsc(a, b) {
  if ( a.gap < b.gap ) return 1;
  if ( a.gap > b.gap ) return -1;
  return 0;
}
function doCompareNSizeAsc(a, b) {
  if ( a.nsize*1 < b.nsize*1 ) return -1;
  if ( a.nsize*1 > b.nsize*1 ) return 1;
  return 0;
}
function doCompareNSizeDsc(a, b) {
  if ( a.nsize*1 < b.nsize*1 ) return 1;
  if ( a.nsize*1 > b.nsize*1 ) return -1;
  return 0;
}

/////////////////////////////////////////////////////////////////////////////
//
//    B A S E V A L U E       F U N C T I O N S
//
function doBaseValuesOn(__chart) {
  __chart.BaseValuesOn=true;
}
function doSetBase(__chart, lbl, val) {
  for(var i=0; i<__chart.data.length; i++) {
    if(__chart.data[i].label.indexOf(lbl)==0) { 
       __chart.data[i].base=val; 
       __chart.data[i].gap=Math.abs(__chart.data[i].base - __chart.data[i].num); 
    }
  }
}





