var ie = false;
var mozilla = false;

if (document.all)
	ie = true;
else
	mozilla = true;
	
var chartData;
var chartLabels;
var seriesNames;
var chartTitle;
var chartWidth = 80;
var chartPrefix = "";
var chartPostfix = "";
var chartColors;
var mapWidth = 500;
var mapHeight = 420;
var showLegend = false;
var legendCols = 2;
var tableWidth;

// These variables should be changed outside of js to set w/h of curve image as well as the y-value/plot dot size
var lifecycleChartWidth = 0;
var lifecycleChartHeight = 0;
var lifecycleVirtualYMin = 0;
var lifecycleVirtualYMax = 0;
var lifecyclePlotDiameter = 0;

var lifecycleYValue = 0;

var newOffset = 2;

// These variables should be treated as constants i.e. not changed outside of the js
var normCurveVariance = 7.0;
var normCurveMean = 2.75;
var normCurveRoot = 6.63192; //Math.sqrt(2.0 * normCurveVariance * Math.PI);
var normCurveLeadingTerm = 0.150786; //1.0 / normCurveRoot;
var normCurveDenom = 14.0; //2.0 * normCurveVariance;

var lifecycleFuncXMin = -3.25;
var lifecycleFuncXMax = 4.0;
var lifecycleFuncYMin = 0.01;
var lifecycleFuncYMax = 0.16;
var lifecyclePeakX = 2.74772;
var lifecyclePeakY = 0.150786;

letterArray = new Array(2);
letterArray[0] = 'A';
letterArray[1] = 'B';
letterArray[2] = 'C';
letterArray[3] = 'D';
letterArray[4] = 'E';
letterArray[5] = 'F';
letterArray[6] = 'G';

// includes bubble size
function LifecycleChartBS(tool)
{
	for (i = 0; i < 7; i++) {
		var dotDiv = document.getElementById("PlotDot" + i + tool);
		var letter = document.getElementById("PlotDot" + i + tool + "_letter");
		if (dotDiv == null)
		{
			alert("LifecycleChart() : PlotDot div not defined!");
			return;
		}

		if (lifecyclePlotDiameter[i] == 24) {
			newOffset = 2;
		} else if (lifecyclePlotDiameter[i] == 36) {
			newOffset = 3;
		} else if (lifecyclePlotDiameter[i] == 48) {
			newOffset = 4;
		} else if (lifecyclePlotDiameter[i] == 60) {
			newOffset = 5;
		} else if (lifecyclePlotDiameter[i] == 72) {
			newOffset = 6;
		} else if (lifecyclePlotDiameter[i] == 84) {
			newOffset = 7;
		} else if (lifecyclePlotDiameter[i] == 96) {
			newOffset = 8;
		}

		var plotX = -lifecycleChartWidth;
		var plotY = lifecyclePlotDiameter[i] / newOffset;
		var dotOffset = lifecyclePlotDiameter[i] / 2;
			
		if (lifecycleYValue[i] > 100) lifecycleYValue[i] = 100;
	  	if (lifecycleYValue[i] < 0)
	  	{
		  	var transMult = -lifecycleYValue[i] / 100;
		    if (transMult > 1.0)
		        transMult = 1.0;
		    var endSpace = lifecycleFuncXMax - lifecyclePeakX;
		 
		    var chartX = lifecyclePeakX + (transMult * endSpace);
		    var chartY = LifecycleF(chartX);
		}
			else
		{
			var chartY = LifecycleYVirtualToChart(lifecycleYValue[i]);
	    	var chartX = LifecycleFInv(chartY);
		}
		
	    plotX += (LifecycleXChartToImage(chartX) - dotOffset);
	    plotY += (lifecycleChartHeight - LifecycleYChartToImage(chartY) - dotOffset);
	 
		dotDiv.style.left = letter.style.left = plotX;
		dotDiv.style.top = letter.style.top = plotY;

		if (lifecycleYValue[i] != 0) {
			dotDiv.innerHTML = '<img width="' + lifecyclePlotDiameter[i] + '" height="' + lifecyclePlotDiameter[i] + '" src="images/lifecycleDot' + lifecyclePlotDiameter[i] + '.gif">';
			letter.innerHTML = '<img width="12" height="12" src="images/' + letterArray[i] + '.gif" style="position: relative; left: ' + ((lifecyclePlotDiameter[i] / 2) - 6) + 'px; top: ' + ((lifecyclePlotDiameter[i] / 2) - 6) + 'px;">';
		}
	}
}

function LifecycleChart(tool)
{
	for (i = 0; i < 7; i++) {
		var dotDiv = document.getElementById("PlotDot" + i + tool);
		if (dotDiv == null)
		{
			alert("LifecycleChart() : PlotDot div not defined!");
			return;
		}
		
		var plotX = -lifecycleChartWidth;
		var plotY = lifecyclePlotDiameter / 4;
		var dotOffset = lifecyclePlotDiameter / 2;
		
			
		if (lifecycleYValue[i] > 100) lifecycleYValue[i] = 100;
	  	if (lifecycleYValue[i] < 0)
	  	{
		  	var transMult = -lifecycleYValue[i] / 100;
		    if (transMult > 1.0)
		        transMult = 1.0;
		    var endSpace = lifecycleFuncXMax - lifecyclePeakX;
		 
		    var chartX = lifecyclePeakX + (transMult * endSpace);
		    var chartY = LifecycleF(chartX);
		}
			else
		{
			var chartY = LifecycleYVirtualToChart(lifecycleYValue[i]);
	    	var chartX = LifecycleFInv(chartY);
		}
		
	    plotX += (LifecycleXChartToImage(chartX) - dotOffset);
	    plotY += (lifecycleChartHeight - LifecycleYChartToImage(chartY) - dotOffset);
	 
		dotDiv.style.left = plotX;
		dotDiv.style.top = plotY;
		if (lifecycleYValue[i] != 0) {
			dotDiv.innerHTML = '<img width="' + lifecyclePlotDiameter + '" height="' + lifecyclePlotDiameter + '" src="images/lifecycleDot' + i + tool + '.gif">';
		}
	}
}

function LifecycleF(x)
{
	return normCurveLeadingTerm * Math.exp((-(x - normCurveMean) * (x - normCurveMean)) / normCurveDenom);
}

function LifecycleFInv(y)
{
	if (y == 0) return lifecycleFuncXMin;
	else
  	return (-Math.sqrt((-normCurveDenom) * Math.log(normCurveRoot * y)) + normCurveMean);
}

function LifecycleXChartToImage(val)
{
	return (val - lifecycleFuncXMin) * (lifecycleChartWidth / (lifecycleFuncXMax - lifecycleFuncXMin));
}

function LifecycleXImageToChart(val)
{
    return (val * ((lifecycleFuncXMax - lifecycleFuncXMin) / lifecycleChartWidth)) + lifecycleFuncXMin;
}

function LifecycleYChartToImage(val)
{
    return (val - lifecycleFuncYMin) * (lifecycleChartHeight / (lifecycleFuncYMax - lifecycleFuncYMin));
}

function LifecycleYImageToChart(val)
{
    return (val * ((lifecycleFuncYMax - lifecycleFuncYMin) / lifecycleChartHeight)) + lifecycleFuncYMin;
}

function LifecycleYVirtualToChart(val)
{
    if (val > lifecycleVirtualYMax)
        val = lifecycleVirtualYMax;
    if (val < lifecycleVirtualYMin)
        val = lifecycleVirtualYMin;
    return (val + lifecycleVirtualYMin) * ((lifecyclePeakY - lifecycleFuncYMin) / (lifecycleVirtualYMax - lifecycleVirtualYMin)) + lifecycleFuncYMin;
}

/* These variables should be changed outside of js to set w/h of curve image as well as the y-value/plot dot size
var sCurveChartWidth = 0;
var sCurveChartHeight = 0;
var sCurveYValue = 0;
var sCurvePlotDiameter = 0;
var sCurveVirtualYMin = 0;
var sCurveVirtualYMax = 0; */

// These variables should be treated as constants i.e. not changed outside of the js
var sCurveFuncXMin = -5;
var sCurveFuncXMax = 5;
var sCurveFuncYMin = 0;
var sCurveFuncYMax = 1;

function SCurveChart(tool)
{
	var dotDiv = document.getElementById("PlotDot" + tool);
	if (dotDiv == null)
	{
		alert("SCurveChart() : PlotDot div not defined!");
		return;
	}
	
	var plotX = -sCurveChartWidth;
	var plotY = sCurvePlotDiameter;
	var dotOffset = sCurvePlotDiameter / 2;
	
	var chartY = SCurveYVirtualToChart(sCurveYValue);
 	var chartX = SCurveFInv(chartY);
	
	plotX += (SCurveXChartToImage(chartX) - dotOffset);
	plotY += (sCurveChartHeight - SCurveYChartToImage(chartY) - dotOffset);
	
	dotDiv.style.left = plotX;
	dotDiv.style.top = plotY;
	dotDiv.innerHTML = '<img width="' + sCurvePlotDiameter + '" height="' + sCurvePlotDiameter + '" src="images/pm_ch' + tool + '_dot.gif">';
}

function SCurveFInv(x)
{
	if (x == 0)
  	return sCurveFuncXMin;
  else
  	return -Math.log((1 / x) - 1);
}

function SCurveXChartToImage(val)
{
	return (val - sCurveFuncXMin) * (sCurveChartWidth / (sCurveFuncXMax - sCurveFuncXMin));
}

function SCurveXImageToChart(val)
{
    return (val * ((sCurveFuncXMax - sCurveFuncXMin) / sCurveChartWidth)) + sCurveFuncXMin;
}

function SCurveYChartToImage(val)
{
    return (val - sCurveFuncYMin) * (sCurveChartHeight / (sCurveFuncYMax - sCurveFuncYMin));
}

function SCurveYImageToChart(val)
{
    return (val * ((sCurveFuncYMax - sCurveFuncYMin) / sCurveChartHeight)) + sCurveFuncYMin;
}

function SCurveYVirtualToChart(val)
{
    if (val > sCurveVirtualYMax)
        val = sCurveVirtualYMax;
    if (val < sCurveVirtualYMin)
        val = sCurveVirtualYMin;
    return (val + sCurveVirtualYMin) * ((sCurveFuncYMax - sCurveFuncYMin) / (sCurveVirtualYMax - sCurveVirtualYMin)) + sCurveFuncYMin;
}

function ColumnChart()
{
	var html = "";
	
	var chartDiv = FindChartDiv();
	
	// debugging switches
	var trace = false;
	var draw = true;
	var showData = false;
	
	
	var dataLength = chartData.length;
	
	if (dataLength <= 0)
	{
		alert("ColumnChart(): No data array defined!");
		return;
	}
	if (chartLabels.length != dataLength)
	{
		alert("ColumnChart(): Labels array different size than data array!");
		return;
	}
	
	var colSpan = (dataLength * 2) + 1;
	var rangeInfo = CalculateRange(chartData, dataLength, false);	
	var cTop = rangeInfo[0];
	var cBottom = rangeInfo[1];
	var topRows = rangeInfo[3];
	var bottomRows = rangeInfo[4];
	var step = rangeInfo[2];
	
	// Some variables for drawing loop
	
	var bottomNext = false;
	var firstTime = true;
	var stopTime = 0;
	
	if (cBottom < 0)
		stopTime = (topRows + bottomRows);
	else
		stopTime = topRows;
	
	// Display debug info	
	if (trace)
	{		
		html += ("DataLength=" + dataLength + "<br>");
		html += ("top=" + cTop + "<br>");
		html += ("bottom=" + cBottom + "<br>");
		html += ("topRows=" + topRows + "<br>");
		html += ("bottomRows=" + bottomRows + "<br>");
		html += ("step=" + step + "<br>");
	}
	if (showData)
	{
		html += chartData.toString();
	}
	/////////// Draw the chart /////////////////////////////////
	if (draw)
	{
	// Draw the header and chart title
	html += '<table cellpadding="0" cellspacing="0" border="0" class="chartShell" style="width: ' + tableWidth + 'px;">';
	html += '<tr><td>';
	html += '<table class="graph" cellspacing="0" cellpadding="0" border="0" style="background-color : #FFF; width: ' + tableWidth + 'px;">';
	html += '<tr>';
	html += '<td colspan="' + colSpan + '" class="chartHead chartbg_01" style="padding : 6px;">' + chartTitle + '</td>';
	html += '</tr><tr>';
	html += '<td colspan="' + colSpan + '" class="chartbg_02" style="padding : 6px;"><img src="images/spacer.gif" width="1" height="1"></td>';
 	html += '</tr>';

	// Go down the chart one increment at a time 	
	for (var i = cTop, rows=0 ; rows <= stopTime ; i -= step, ++rows)
	{
		// Add postfix or prefix
		var yLabel = i.toString();
		if (chartPrefix != "")
		{
			if (i < 0)
			{
				yLabel = yLabel.replace('-',"");
				yLabel = "-" + chartPrefix + yLabel;
			} else {
				yLabel = chartPrefix + yLabel;
			}
		}
		if (chartPostfix != "")
		{
			yLabel = yLabel + chartPostfix;
		}
		
	 	html += '<tr>';
	 	html += ('<td align="right">' + yLabel + '</td><td class="labelY"><img src="images/tic_h.gif"></td>');
	 
	 	// Draw the top bars
	 	if ((i == cTop) && (cTop != 0))
	 	{
	 		for (var j = 0 ; j < dataLength ; ++j)
	 		{
	 				var stepsTaken = chartData[j] / step;
					var height = Math.ceil(stepsTaken * 40);			
		 			
		 			
		 			html += ('<td class="graphCel_top" rowspan="' + topRows + '">');
		     	html += ('<div class="top_bar">');
		     	
		     	if (stepsTaken > 0)
		     	{
		     		html += ('<div style="height : ' + height + 'px; width : ' + chartWidth + 'px; border-left : ' + chartWidth + 'px solid ' + chartColors[j] + ';"></div></div></td>'); 		
		     	}
		     	if (stepsTaken == 0)
		     	{
		     		html += ('<div class="bar_clear" style="height : 0px; width :' + chartWidth + 'px;"></div></div></td>'); 		
		     	}
		     	if (stepsTaken < 0)
		     	{
		     		html += ('&nbsp</div></td>');
		     	}
		
					if (j < dataLength - 1)     
		     		html += ('<td rowspan="' + topRows + '">&nbsp;</td>');
	   	}
	 	}
	 	
	 	// Draw the bottom bars
	 	if (bottomNext)
		{
			for (var j = 0 ; j < dataLength ; ++j)
			{
				var stepsTaken = -chartData[j] / step;	
	 			var height = Math.ceil(stepsTaken * 40);			
	 			
	 			html += ('<td class="graphCel_bottom" rowspan="' + bottomRows + '">');
	 			html += ('<div class="bottom_bar">');
	     	
	 			if (chartData[j] < 0)
	 			{
	 				html += ('<div style="height : ' + height + 'px; width : ' + chartWidth + 'px; border-left : ' + chartWidth +'px solid #E2C35E;"></div>');
					html += ('</div></td>');
	     	}
	     	if ((chartData[j] == 0) && (cTop == 0))
	     	{
	     		html += ('<div class="bar_clear" style="height : 0px; width : ' + chartWidth + 'px;"></div>');
	   	 	}
	     	if (chartData[j] > 0)
	     	{
	     		html += ('&nbsp</div></td>');
	     	}	
	     
	     	if (j < dataLength - 1)
	     		html += ('<td rowspan="' + bottomRows + '">&nbsp;</td>');
			}
			
			bottomNext = false;
		}
	
		// Draw X Axis
	 	if (i == 0)
	 	{
	 		bottomNext = true;
	 		for (var j = 0 ; j < dataLength ; ++j)
	 		{
	 			html += ('<td class="zeroAxis"><div class="zeroAxis">&nbsp;</div></td>');
		 		if (j < dataLength - 1)
	    		html += ('<td class="zeroAxisTic"><div class="zeroAxisTic"><img src="images/tic_v.gif"></div></td>');
	   	}
		}
				
		html += ('</tr>');
	}
	
	// Draw footer	
	html += '<tr>';
	for (var i = 0 ; i < dataLength ; ++i)
	{
		if (i == 0)
		{
			html += '<td colspan="2" class="heavy chartbg_04">&nbsp;</td>';
		} else {
			html += '<td class="heavy chartbg_04"></td>';
		}
	  html += '<td align="center" class="heavy chartbg_04">' + chartLabels[i] + '</td>';
	}
	html += '</tr></table></td></tr></table>';                
	}		// End drawing

	chartDiv.innerHTML = html;
}

function StackedChart()
{
	var html = "";
	
	var chartDiv = FindChartDiv();
	
	var trace = false;
	var draw = true;
	
	var dataLength = chartData.length;
	if (dataLength <= 0)
	{
		alert("StackedChart(): No data array defined!");
		return;
	}
	
	var numSeries = chartData[0].length;
	if (numSeries <= 0)
	{
		alert("StackedChart(): No series defined!");
		return;
	}
	for (var i = 0 ; i < dataLength ; ++i)
	{
		if (chartData[i].length != numSeries)
		{
			alert("StackedChart(): Number of series for each data point do not match!");
			return;
		}
	}
	if (showLegend && (seriesNames.length != numSeries) )
	{
		alert("StackedChart(): Number of series names does not match number of series!");
		return;
	}
	if (chartLabels.length != dataLength)
	{
		alert("StackedChart(): Labels array different size than data array!");
		return;
	}
	
	var colSpan = (dataLength * 2) + 1;
	
	// Calculate the range
	var rangeInfo = CalculateRange(chartData, dataLength, true);	
	var cTop = rangeInfo[0];
	var topRows = rangeInfo[3];
	var step = rangeInfo[2];
	
	// Generate series colors
	var styles = new Array(numSeries);
	for (var i = 0 ; i < numSeries ; ++i)
	{
		switch (i % 6)
		{
			case 0:
			{
				styles[i] = "border-left : " + chartWidth + "px solid #E2C35E;";
			} break;
			case 1:
			{
				styles[i] = "border-left : " + chartWidth + "px solid #FFE799;";
			} break;
			case 2:
			{
				styles[i] = "border-left : " + chartWidth + "px solid #AD9649;";
			} break;
			case 3:
			{
				styles[i] = "border-left : " + chartWidth + "px solid #877DC2;";
			} break;
			case 4:
			{
				styles[i] = "border-left : " + chartWidth + "px solid #5542C8;";
			} break;
			case 5:
			{
				styles[i] = "border-left : " + chartWidth + "px solid #30208C;";
			} break;
		}
	}
	
	// Some variables for drawing loop
	
	var firstTime = true;
	
	// Display debug info	
	if (trace)
	{		
		html += ("DataLength=" + dataLength + "<br>");
		html += ("numSeries=" + numSeries + "<br>");
		html += ("top=" + cTop + "<br>");
		html += ("topRows=" + topRows + "<br>");
		html += ("step=" + step + "<br>");
	}
	
	/////////// Draw the chart /////////////////////////////////
	if (draw)
	{
	// Draw the header and chart title
	html += '<table cellpadding="0" cellspacing="0" border="0" class="chartShell">';
	html += '<tr><td>';
	html += '<table class="graph" cellspacing="0" cellpadding="0" border="0" style="background-color : #FFF;">';
	html += '<tr>';
	html += '<td colspan="' + colSpan + '" class="chartHead chartbg_01" style="padding : 6px;">' + chartTitle + '</td>';
	html += '</tr><tr>';
	html += '<td colspan="' + colSpan + '" class="chartbg_02" style="padding : 6px;"><img src="images/spacer.gif" width="1" height="1"></td>';
 	html += '</tr>';
 	
 	for (var i = cTop, rows=0 ; rows <= topRows ; i -= step, ++rows)
	{
	 	html += '<tr>';
	 	
	 	// Add postfix or prefix
		var yLabel = i.toString();
		if (chartPrefix != "")
		{
			if (i < 0)
			{
				yLabel = yLabel.replace('-',"");
				yLabel = "-" + chartPrefix + yLabel;
			} else {
				yLabel = chartPrefix + yLabel;
			}
		}
		if (chartPostfix != "")
		{
			yLabel = yLabel + chartPostfix;
		}
		
	 	html += ('<td align="right">' + yLabel + '</td><td class="labelY"><img src="images/tic_h.gif"></td>');
	 
	 	// Draw the top bars
	 	if ((i == cTop) && (cTop != 0))
	 	{
	 		for (var j = 0 ; j < dataLength ; ++j)
	 		{
	 			html += ('<td class="graphCel_top" rowspan="' + topRows + '">');
		  	html += ('<div class="top_bar">');
		  
	 			for (var k = 0 ; k < numSeries ; ++k)
	 			{
	 				var stepsTaken = chartData[j][k] / step;
					var height = Math.ceil(stepsTaken * 40);			
		 			if (stepsTaken > 0)
		     	{
		     		var point = chartData[j][k];
		     		if (chartPrefix == "$")
		     			point = FormatMoney(point);
		     		if (chartPostfix == "%")
		     			point = FormatPercent(point);
		     		html += ('<div style="' + styles[k] + 'height : ' + height + 'px; width :' + chartWidth + 'px;">');
		     		html += '</div>';
		     	}
	 			}
	 			
	 			html += ('</div></td>');
		 			   	
		  	if (j < dataLength - 1)     
		     		html += ('<td rowspan="' + topRows + '">&nbsp;</td>');
	   	}
	 	}

		// Draw X Axis
	 	if (i == 0)
	 	{
	 		bottomNext = true;
	 		for (var j = 0 ; j < dataLength ; ++j)
	 		{
	 			html += ('<td class="zeroAxis"><div class="zeroAxis">&nbsp;</div></td>');
		 		if (j < dataLength - 1)
	    		html += ('<td class="zeroAxisTic"><div class="zeroAxisTic"><img src="images/tic_v.gif"></div></td>');
	   	}
		}
				
		html += ('</tr>');
	}
	
	// Draw footer	
	html += '<tr>';
	for (var i = 0 ; i < dataLength ; ++i)
	{
		if (i == 0)
		{
			html += '<td colspan="2" class="heavy chartbg_04">&nbsp;</td>';
		} else {
			html += '<td class="heavy chartbg_04"></td>';
		}
	  html += '<td align="center" class="heavy chartbg_04">' + chartLabels[i] + '</td>';
	}
	html += '</tr>';
	
	// Draw legend
	if (showLegend)
	{
		html += '<tr><td colspan="2">&nbsp;</td>';
		html += '<td colspan="' + ((dataLength * 2) - 1) + '" align="center" class="heavy" style="font-size : 16px;">LEGEND</td></tr>';
		
		for (var i = 0 ; i < numSeries ; ++i)
		{
			switch (i % 6)
			{
				case 0:
				{
					styles[i] = "legend_01";
				} break;
				case 1:
				{
					styles[i] = "legend_02";
				} break;
				case 2:
				{
					styles[i] = "legend_03";
				} break;
				case 3:
				{
					styles[i] = "legend_04";
				} break;
				case 4:
				{
					styles[i] = "legend_05";
				} break;
				case 5:
				{
					styles[i] = "legend_06";
				} break;
			}
		}
		
		var cutOff = Math.ceil(numSeries / legendCols);
		var span = Math.floor(((dataLength * 2) - 1) / legendCols);
		
		for (var i = 0 ; i < cutOff ; ++i)
		{
			html += '<tr>';
			html += '<td colspan="2">&nbsp;</td>';
			for (var j = 0 ; j < legendCols ; ++j)
			{
				if ( (i + (j * cutOff)) < numSeries)
				{
					html += ('<td align="center" colspan="' + span + '"><div class="' + styles[i + (j * cutOff)] + '">' + seriesNames[i + (j * cutOff)] + '</div></td>');
					if ( (j+1) < legendCols )
						html += '<td>&nbsp;</td>';
				}
				else
				{
					html += '<td colspan="' + span + '">&nbsp;</td>'
				}
			}
			/*
			if ( (i + cutOff) < numSeries )
			{
				html += ('<td align="center"><div  class="' + styles[i + cutOff] + '">' + seriesNames[i + cutOff] + '</div></td>');
			} else {
				html += '<td>&nbsp;</td>';
			}*/
			html += '</tr>';
		}
		
		html += '<tr><td colspan="' + ((dataLength * 2) + 1) + '">&nbsp;</td>';
	}
	
	html += '</table></td></tr></table>';                
	}		// End drawing

	chartDiv.innerHTML = html;
}

function PlotChart(tool, useOffset)
{
	var dontPlot = false;
	var xInc = mapWidth / 100;
	var yInc = mapHeight / 100;
	var dotOffset = 12;

	var dataLength = chartData.length;
	if (dataLength % 2)
	{
		alert("PlotChart() : At least 2 data points must be passed!");
		return;
	}
	
	var count = 0;
	var offsetX = 0;
	var offsetY = 0;
	
	for (i = 1; i <= dataLength / 2; i++) {
	
		var dotDiv = document.getElementById("PlotDot" + tool + i);
	
		if (dotDiv == null) {
			alert("PlotChart() : PlotDot div not defined! (Did you forget the cf_PlotMap tag?)");
			return;
		}
	
		if (chartData[count] < 0 || chartData[count] > 100 || chartData[count + 1] < 0 || chartData[count + 1] > 100) {
			dotDiv.innerHTML = "";
			return;
		}
	
		var plotX = -mapWidth;
		var plotY = 24;
		
		plotX += (Math.ceil(chartData[count] * xInc) - dotOffset);
		plotY += (mapHeight - Math.ceil(chartData[count + 1] * yInc) - dotOffset);
		
		if (useOffset == "x") {
			dotDiv.style.left = plotX - offsetX;
		} else {
			dotDiv.style.left = plotX;
		}
		if (useOffset == "y") {
			dotDiv.style.top = plotY + offsetY;
		} else {
			dotDiv.style.top = plotY;
		}
		
		if (tool == '11-3' && chartData[count] != 0 || chartData[count + 1] != 0) {
			dotDiv.innerHTML = '<img width="24" height="24" src="images/pm_ch' + tool + '_dot' + i + '.gif">';
		}

		count = count + 2;
		offsetX = offsetX + 24;
		offsetY = offsetY - 24;
	
	}
}

/***************************************************************************
*
*				UTILITY FUNCTIONS
*
****************************************************************************/

function FindPlotDiv()
{
	var divs = document.getElementsByTagName('div');
	for (var i = 0 ; i < divs.length ; ++i)
	{
		if (divs[i].className == "plotchart")
			return divs[i];
	}
}

function FindChartDiv()
{
	// Find the div tag we will use to draw chart
	var divs = document.getElementsByTagName('div');
	for (var i = 0 ; i < divs.length ; ++i)
	{
		if (divs[i].className == "chart")
		{
			return (divs[i]);
		}
	}
}

function CalculateRange(chartData, dataLength, stacked)
{
	var numIntervals = 10;	// Actual ticks=numIntervals+2
	
	var dataMin = 0;
	var dataMax = 0;
	var tmpTop = 0;
	var range = new Array(5);	// range[0] = top, range[1] = bottom, range[2] = step, 
														// range[3] = topRows, range[4] = bottomRows
	

	if (stacked)
	{
		numSeries = chartData[0].length;
		for (var i = 0 ; i < dataLength ; ++i)
		{
			var sum = 0;
			for (var j = 0 ; j < numSeries ; ++j)
				sum += chartData[i][j];
			if (sum > dataMax)
				dataMax = sum;
			if (sum < dataMin)
				dataMin = sum;
		}
	} else {
		for (var i = 0 ; i < dataLength ; ++i)
		{
			if (chartData[i] > dataMax)
				dataMax = chartData[i];
			if (chartData[i] < dataMin)
				dataMin = chartData[i];
		}
	}
	
	if (dataMax < 0)
		tmpTop = 0;
	else
		tmpTop = dataMax;
	if (dataMin < 0)
		range[1] = dataMin;
	else
		range[1] = 0;
		
	var gap = tmpTop - range[1];
	range[2] = Math.ceil(gap / numIntervals);
	
	range[0] = 0;
	range[3] = 0;
	if (tmpTop != 0)
	{
		while(range[0] < tmpTop)
		{
			range[0] += range[2];
			++range[3];
		}
		// Allow one extra row if we're all positive
		if (dataMin >= 0)
		{
			range[0] += range[2];
			++range[3];
		}
	}
		
	range[4] = numIntervals - range[3] + 1;
	
	return range;
}

function GetAbsX(elt) 
{ 
	return GetAbsPos(elt,"Left"); 
}

function GetAbsY(elt) 
{ 
	return GetAbsPos(elt,"Top"); 
}

function GetAbsPos(elt, property) 
{
 var iPos = 0;
 var lastOne = 0;
 
 while (elt != null) 
 {
 	lastOne = elt["offset" + property];	
 	iPos += lastOne;
  elt = elt.offsetParent;
 }
 
 if (mozilla)
 	iPos -= lastOne;
 	
 return iPos;
}