/***********************************************
BuildSketch
	This function controls the calculation and drawing of the sketch.
		Uses array arrXZ74SectStypSket init and populated in sktmnt.asp
		arrXZ74SectStypSket = xz74sect, xz74styp, xz74sket, sectionColor, list of xz74sket pattern matches, section Min/Max dimensions - last 2 array members added with BuildSketch()
	Params
		none
***********************************************/
function BuildSketch() {
	
//	alert ("sket: " + arrXZ74SectStypSket); // [SectNo][Styp][Sketch][color]
//	alert ("sket: " + arrXZ74SectStypSket.length);
	
	arrSectionCordinates=MultiDimensionalArray(arrXZ74SectStypSket.length,5); 
	arrStypCordTrack=MultiDimensionalArray(arrXZ74SectStypSket.length,2);

	// return if array arrXZ74SectStypSket is empty
	if (arrXZ74SectStypSket.length < 1) { 
		return;
	}
	
	// For each row of the array, get list of pattern matches and add to array
	for (var i = 0; i < arrXZ74SectStypSket.length; i++) { 
		var arrMatches = CheckSketchParms(arrXZ74SectStypSket[i][2]);
		arrXZ74SectStypSket[i][4] = arrMatches;
	}
	
	// Calculate the Sketch dimensions and track the starting x and y points.
	for (var i = 0; i < arrXZ74SectStypSket.length; i++) { // 1...
		arrSectionCordinates[i][0] = arrXZ74SectStypSket[i][0];
		arrSectionCordinates[i][1] = arrXZ74SectStypSket[i][1];
		var lastSectionMinMax = CalcSketchDimensions(arrXZ74SectStypSket[i][4], i);
		arrXZ74SectStypSket[i][5] = lastSectionMinMax;
	}
	
	total_x = Math.abs(Min_x) + Math.abs(Max_x);
	total_y = Math.abs(Min_y) + Math.abs(Max_y);
	
	// Determine scaler
	Scaler = CalcScaler();

	var shift_x = Min_x;
	var shift_y = Max_y;
	
	// adjust arrSectionCordinates to account for starting at top left instead of bottom
	for (var i = 0; i < arrSectionCordinates.length; i++) {
		shiftScaleArrayCordinates(arrSectionCordinates[i], shift_x, shift_y);
	}
	
	// determin the number of string for the sketch (lines and styp)
	var intStringCount = 0;
	intStringCount = arrXZ74SectStypSket.length; // nbr of stype

	
	// set color and fillPolygon
	for (var i = 0; i < arrSectionCordinates.length; i++) { // loop thru all sections
		eval(SketchCanvas.setColor(arrXZ74SectStypSket[i][3]));
		eval(SketchCanvas.fillPolygon(arrSectionCordinates[i][2], arrSectionCordinates[i][3])); // draw poly
		intStringCount = intStringCount + (arrSectionCordinates[i][2].length - 1);
	}
	
	// set color to black and draw lines (done so fill doesn't obscure section lines)
	intStringCount = arrXZ74SectStypSket.length; // nbr of stype
	eval(SketchCanvas.setColor("black"));
	for (var i = 0; i < arrSectionCordinates.length; i++) { // loop thru all sections
		eval(SketchCanvas.drawPolygon(arrSectionCordinates[i][2], arrSectionCordinates[i][3])); // draw poly
		intStringCount = intStringCount + (arrSectionCordinates[i][2].length - 1);
	}
	
	arrStringTrack=MultiDimensionalArray(intStringCount,3); // init array for storage of string points to prevent overlap
	var intStringIndex = 0; // track arrStringTrack index 
	
	var shift_styp_x=char_x/2; // shift right so don't over lay vert numbers
	var shift_styp_y=char_y/2; // shift up so don't overlay horz. numbers
	
	var styp_height;
	var styp_width;
	
	// draw line numbers
	for (var i = 0; i < arrSectionCordinates.length; i++) { // loop thru all sections
		eval(SketchCanvas.setFont("monospace","15px",Font.BOLD)); // Set font for DrawString()
		intStringIndex = DrawLength(i, intStringIndex); // draw length of line
		
	}
	
	for (var i = 0; i < arrSectionCordinates.length; i++) { // loop thru all sections
		
		// get lowest / right most xy cord of section to add styp 
		var y_drawStyp = arrSectionCordinates[i][3][0];
		var drawStypIndex = 0;
		for (j = 0; j < arrSectionCordinates[i][3].length; j++) {
			if (arrSectionCordinates[i][3][j] >= y_drawStyp) { // find lowest y
				if (arrSectionCordinates[i][2][j] <= arrSectionCordinates[i][2][drawStypIndex]) { // find left most x that is on lowest y line
					y_drawStyp = arrSectionCordinates[i][3][j];
					drawStypIndex = j;
				}
			}
		}
		
		// max and min of section (if too small, skip)
		styp_width = arrXZ74SectStypSket[i][5][1] - arrXZ74SectStypSket[i][5][0];
		styp_height = Math.abs(arrXZ74SectStypSket[i][5][2] - arrXZ74SectStypSket[i][5][3]);
		
		var strStyp = arrXZ74SectStypSket[i][1].substring(0, arrXZ74SectStypSket[i][1].length);
		var strStyp_trim = trimString(strStyp);
		var intStyp = strStyp_trim.length;
		
	// check for same sections 
		var x_drawStyp = arrSectionCordinates[i][2][drawStypIndex]; // styp left
		var y_drawStyp = arrSectionCordinates[i][3][drawStypIndex]; // styp bottom
		arrStypCordTrack[i][0] = x_drawStyp;
		arrStypCordTrack[i][1] = y_drawStyp;
		
		var stypString_x_left = shift_styp_x + x_drawStyp;
		var stypString_x_right = stypString_x_left + (styp_width_pad * intStyp);
		var stypString_y_top = (y_drawStyp - char_height_pad - shift_styp_y);
		var stypString_y_bottom = stypString_y_top + styp_height_pad -1;
		
		eval(SketchCanvas.setFont("monospace","10px",Font.BOLD)); // Set font for DrawString()
		
		var blnSkipStyp = false;
		for (j = 0; j < arrStypCordTrack.length; j++) {
			if (arrStypCordTrack[j][0] == "") {
				break;
			}
			if ((x_drawStyp == arrStypCordTrack[j][0]) && (y_drawStyp == arrStypCordTrack[j][1]) && (j != i )) {
//				alert ("same section - skipping \n arrStypCordTrack: " + arrStypCordTrack[i]);
				blnSkipStyp = true;
				break;
			}
		}
		
		if ((shift_styp_x + (intStyp * styp_width_pad)) >= (styp_width * Scaler)) { 
//				alert ("styp width overlap - skipping \n arrStypCordTrack: " + arrStypCordTrack[i]);
			blnSkipStyp = true;
		}
		if ((shift_styp_y + styp_height_pad) >= (styp_height * Scaler)) { 
//				alert ("styp height overlap - skipping \n arrStypCordTrack: " + arrStypCordTrack[i]);
			blnSkipStyp = true;
		}
		if ((shift_styp_y + styp_height_pad) >= (styp_height * Scaler)) { 
//				alert ("styp height overlap - skipping \n arrStypCordTrack: " + arrStypCordTrack[i]);
			blnSkipStyp = true;
		}
		
		// don't write styp if it will over lap length string
		for (j = 0; j < arrStringTrack.length; j++) {
			if (arrStringTrack[j][0] == "") {
//					alert ("empty arrStringTrack breaking");
				break;
			}
			if (
				((stypString_x_left > arrStringTrack[j][0]) && (stypString_x_left < arrStringTrack[j][1])) || 
				((stypString_x_right > arrStringTrack[j][0]) && (stypString_x_right < arrStringTrack[j][1]))
				) { // same horz
//				alert ("same horz:");
//				alert ("stypString_x_left: " + stypString_x_left + "\n stypString_x_right: " + stypString_x_right + "\n arrStringTrack[j][0]: " + arrStringTrack[j][0] + "\n arrStringTrack[j][1]: " + arrStringTrack[j][1]) 
				if (
					((stypString_y_top > arrStringTrack[j][2]) && (stypString_y_top < arrStringTrack[j][3])) || 
					((stypString_y_bottom > arrStringTrack[j][2]) && (stypString_y_bottom < arrStringTrack[j][3]))
					) { // same vert
//					alert ("skip styp");
					
//					alert ("stypString_x_left: " + stypString_x_left + "\n stypString_x_right: " + stypString_x_right + "\n arrStringTrack[j][0]: " + arrStringTrack[j][0] + "\n arrStringTrack[j][1]: " + arrStringTrack[j][1]) 
					
//					alert ("stypString_y_top: " + stypString_y_top + "\n stypString_y_bottom: " + stypString_y_bottom + "\n arrStringTrack[j][2]: " + arrStringTrack[j][2] + "\n arrStringTrack[j][3]: " + arrStringTrack[j][3]) 
					blnSkipStyp = true;
					break;
				}
			}
		}
		if (!blnSkipStyp) {
			DrawSketchText(strStyp, stypString_x_left, stypString_y_top);
		}
	}
	
	eval(SketchCanvas.paint()); 
}

/***********************************************
shiftScaleArrayCordinates
	This function shifts and scales the cords stored in arrSectionCordinates.  Determine where to start the sketch and scale sketch.  Needed because sketch drawn from top left.
	Params
		SectionArray - contains arrSectionCordinates array
		shift_x - starting point for x - pass 0 for no shift
		shift_y - starting point for y - pass 0 for no shift
***********************************************/
function shiftScaleArrayCordinates(SectionArray, shift_x, shift_y) {
	
	// shift and scale x cords
	for (var i = 0; i < SectionArray[2].length; i++) {
		SectionArray[2][i] = Math.floor((Math.abs(shift_x) + SectionArray[2][i]));
		SectionArray[2][i] = (SectionArray[2][i] * Scaler) + (SketchBorderPX/2);
	}
	
	// shift and scale y cords
	for (var i = 0; i < SectionArray[3].length; i++) {
		SectionArray[3][i] = (shift_y - SectionArray[3][i]);
		SectionArray[3][i] = Math.floor((SectionArray[3][i] * Scaler) + (SketchBorderPX / 2));
	}
}

/***********************************************
CheckSketchParms
	This function receives the string of xz74sket matches patterns: (SKP, BGN, COM,
		and U, D, R, L all followed by 1 or more numeric digits
	Params
		strSketch - name of the string which contains the xz74sket record
***********************************************/
function CheckSketchParms(strSketch) {
	
	var reSketchPattern = new RegExp ("(SKP|BGN|COM|U\\d+|D\\d+|R\\d+|L\\d+)", "gi");
	var SketchMatch = strSketch.match(reSketchPattern); // matches a word beginning with th, globally, and ignore case.
	return(SketchMatch); 
}

/***********************************************
CalcSketchDimensions
	This function receives the array of xz74sket and loops thru them to 
		calculate the dimensions of the Sketch
	Params
		arrSketch - name of the array which has the xz74sket found in match
		irow - name of the row number to track which row is currently processing
***********************************************/
function CalcSketchDimensions(arrSketch, irow) {

	arrXpoints = new Array(); 
	arrYpoints = new Array(); 
	arrCordDetails = new Array(); 
	
	var intCordDetailCount = 0;
	var blnSectionFirst = true;
	var blnSectCordFirst = true;
	blnSkip = false;
	var blnCalcSection = true;
	var icolumn = 0; // track cordinate column 
	
	Min_Section_x=0; 
	Max_Section_x=0; 
	Min_Section_y=0; 
	Max_Section_y=0;
	
	for (var i = 0; i < arrSketch.length; i++) {
		var prevMax_y = Max_y;
		var prevMax_Section_y = Max_Section_y;
		
		if (arrSketch[i] == "SKP") {
			blnCalcSection = false;
			blnSkip = true;
		} else if (arrSketch[i] == "BGN") {
			blnCalcSection = true;
			blnSkip = true;
		} else {
			if ((blnSectionFirst) && (!blnSkip) && (blnCalcSection)) { // first pass
				Min_Section_x=track_x; 
				Max_Section_x=track_x; 
				Min_Section_y=track_y; 
				Max_Section_y=track_y;
				blnSectionFirst = false;
			}
			
			blnSkip = false;
			
			if ((blnCalcSection) && (!blnSkip) && (blnSectCordFirst)) { // save beginning cordinates
				arrXpoints[icolumn] = track_x;
				arrYpoints[icolumn] = track_y;
				icolumn++; 
				blnSectCordFirst = false;
			}
				
			var strDirection = arrSketch[i].substring(0, 1);
			var strLength = arrSketch[i].substring(1, arrSketch[i].length);
			var intLength = parseInt(parseFloat(strLength));
			
			if (strDirection == 'U') { // add height
				track_y = track_y + intLength;
			}
			if (strDirection == 'D') { // sub height
				track_y = track_y - intLength;
			}
			if (strDirection == 'L') { // sub width
				track_x = track_x - intLength;
			}
			if (strDirection == 'R') { // add width
				track_x = track_x + intLength;
			}
			
			CalcSketchMaxMin(arrSketch[i]); // track max/min of x and y
			if ((blnCalcSection) && (!blnSkip)) {
				CalcSectionMaxMin(arrSketch[i]);
				SectionMaxMinArray(arrSketch[i], icolumn, strDirection);
				arrCordDetails[icolumn] = arrSketch[i];
				icolumn++; 
			}
		}
	}
	
	arrSectionCordinates[irow][2] = arrXpoints;
	arrSectionCordinates[irow][3] = arrYpoints;
	arrSectionCordinates[irow][4] = arrCordDetails;
	
	var arrSectionMinMax = new Array(Min_Section_x, Max_Section_x, Min_Section_y, Max_Section_y);
	return(arrSectionMinMax);
}


/***********************************************
CalcSketchMaxMin
	This function tracks the min and max of x and y of the sketch
	Params
		strSket - name of the text (one entry from the group xz74sket)
***********************************************/
function CalcSketchMaxMin(strSket) {
	if (track_x<Min_x) {
		Min_x = track_x;
	} 
	if (track_x>Max_x) {
		Max_x = track_x;
	}
	if (track_y<Min_y) {
		Min_y = track_y;
	} 
	if (track_y>Max_y) {
		Max_y = track_y;
	}
}

/***********************************************
CalcSectionMaxMin
	This function tracks the min and max of x and y of the section
	Params
		strSket - name of the text (one entry from the group xz74sket)
***********************************************/
function CalcSectionMaxMin(strSket) {
	if (track_x<Min_Section_x) {
		Min_Section_x = track_x;
	} 
	if (track_x>Max_Section_x) {
		Max_Section_x = track_x;
	}
	if (track_y<Min_Section_y) {
		Min_Section_y = track_y;
	} 
	if (track_y>Max_Section_y) {
		Max_Section_y = track_y;
	}
}

/***********************************************
SectionMaxMinArray
	This function stores the xy chords of the section
	Params
		strSket - name of the text (one entry from the group xz74sket)
		icolumn - column index to track which cordinate is currently processing
		strDirection - direction of the cord
***********************************************/
function SectionMaxMinArray(strSket, icolumn, strDirection) {
	arrXpoints[icolumn] = track_x;
	arrYpoints[icolumn] = track_y;
}

/***********************************************
CalcScaler
	This function calculates the Scaler value to draw the Sketch on the screen
	Params
		none
***********************************************/
function CalcScaler() {
	if (total_x > total_y) { // height greater than width
		Scaler = (SketchWidthPX - (SketchBorderPX*2))/total_x;
	} else {
		Scaler = (SketchHeightPX - (SketchBorderPX*2))/total_y;
	}
	return(Scaler);
}

/***********************************************
CheckSameSection
	This function determins if the curent section is the same as the previous section.  
	Params
		none
***********************************************/
function CheckSameSection(arrSectionMinMaxCur, arrSectionMinMaxPrev) {
	if ((arrSectionMinMaxCur[0] == arrSectionMinMaxPrev[0]) && (arrSectionMinMaxCur[1] == arrSectionMinMaxPrev[1]) && (arrSectionMinMaxCur[2] == arrSectionMinMaxPrev[2]) && (arrSectionMinMaxCur[3] == arrSectionMinMaxPrev[3])) {
		return (true);
	} else {
		return (false);
	}
}

/***********************************************
DrawSketchText
	This function stores each line segment into an array
	Params
		strText - name of the text (one entry from the group xz74sket)
***********************************************/
function DrawSketchText(strText, posString_x, posString_y) {
	
	if (blnSkip) {
		return;
	}
	eval(SketchCanvas.setColor("black"));
	eval(SketchCanvas.setFont("monospace","10px",Font.BOLD)); // Set font for DrawString()
	eval(SketchCanvas.drawString(strText, posString_x, posString_y));
}


/***********************************************
DrawLength
	This function prints the length of the lines on the sketch
	Params
		irow - track current row to process
		intStringIndex - track arrString index 
***********************************************/
function DrawLength(irow, intStringIndex) {

	var posString_x_left;
	var posString_y_top;
	var posString_x_right;
	var posString_y_bottom;
	var blnSkipString;
	
	for (i = 1; i < arrSectionCordinates[irow][4].length; i++) { // loop thru all cords of section
	
		// split cord direction/length
		var strDirection = arrSectionCordinates[irow][4][i].substring(0, 1);
		var strLength = arrSectionCordinates[irow][4][i].substring(1, arrSectionCordinates[irow][4][i].length);
		var intLength = strLength.length;
		
		blnSkipString = false;
		
		if ((strDirection == "U") || (strDirection == "D")) { // process vertical lines
		
			// get total length of line (scaled)
			if (arrSectionCordinates[irow][3][i-1] < arrSectionCordinates[irow][3][i]) {
				total_y = arrSectionCordinates[irow][3][i] - arrSectionCordinates[irow][3][i-1]
			} else {
				total_y = arrSectionCordinates[irow][3][i-1] - arrSectionCordinates[irow][3][i]
			}
			
			// determine center of the line
			var center_y = (arrSectionCordinates[irow][3][i] + arrSectionCordinates[irow][3][i-1])/2;
			
			// determine length of text string (how many pixles)
			string_y_length = (char_y * intLength) + char_height_pad;
			var offset_string_y_length = string_y_length/2;
			
			// store string dimensions
			posString_x_left = arrSectionCordinates[irow][2][i] - (char_x/2);
			posString_x_right = posString_x_left + char_x;
			posString_y_top = (center_y - offset_string_y_length) + 1;
			posString_y_bottom = posString_y_top + (char_height_pad * intLength); 
			
			for (j = 0; j < arrStringTrack.length; j++) {
				if (arrStringTrack[j][0] == "") {
					break;
				}
				if (
					((posString_x_left >= arrStringTrack[j][0]) && (posString_x_left <= arrStringTrack[j][1])) || 
					((posString_x_right >= arrStringTrack[j][0]) && (posString_x_right <= arrStringTrack[j][1]))
					) { // same horz
					if (
						((posString_y_top >= arrStringTrack[j][2]) && (posString_y_top <= arrStringTrack[j][3])) || 
						((posString_y_bottom >= arrStringTrack[j][2]) && (posString_y_bottom <= arrStringTrack[j][3]))
						) { // same vert
						blnSkipString = true;
						break;
					}
				}
			}
			// if the length of the line is larger than the length of the text string, drawString and string doesn't overlap other strings
			if ((string_y_length < total_y) && (!blnSkipString)) {
				var posString_y_top_track = (center_y - offset_string_y_length);
				
				for (j=0; j< intLength; j++) {
					var place_char = strLength.substring(j, j + 1);
					
					eval(SketchCanvas.setColor("black"));
					eval(SketchCanvas.drawString(place_char, posString_x_left, posString_y_top_track));
					posString_y_top_track = posString_y_top_track + char_y + 2;
				}
				
				// store x1, y1, x2, y2 cords of string (rectangle)
				arrStringTrack[intStringIndex][0] = posString_x_left; 
				arrStringTrack[intStringIndex][1] = posString_x_right; 
				arrStringTrack[intStringIndex][2] = posString_y_top; 
				arrStringTrack[intStringIndex][3] = posString_y_bottom; 
				intStringIndex++;
			}
		}
		
		if ((strDirection == "R") || (strDirection == "L")) { // process horzontal lines
			
			// determine total length of line (scaled)
			if (arrSectionCordinates[irow][2][i-1] < arrSectionCordinates[irow][2][i]) {
				total_x = arrSectionCordinates[irow][2][i] - arrSectionCordinates[irow][2][i-1]
			} else {
				total_x = arrSectionCordinates[irow][2][i-1] - arrSectionCordinates[irow][2][i]
			}
			
			// determine center of the line
			var center_x = (arrSectionCordinates[irow][2][i-1] + arrSectionCordinates[irow][2][i])/2;
			
			// determine the length of the text string 
			string_x_length = (char_x * intLength) + char_width_pad;
			offset_string_x_length = string_x_length/2;
			
			// store string dimensions
			posString_x_left = (center_x - offset_string_x_length);
			posString_x_right = posString_x_left + (char_x * intLength);
			posString_y_top = (arrSectionCordinates[irow][3][i] - (char_y)) + 1;
			posString_y_bottom = posString_y_top + char_height_pad; 
			
			for (j = 0; j < arrStringTrack.length; j++) {
				if (arrStringTrack[j][0] == "") {
					break;
				}
				if (
					((posString_x_left >= arrStringTrack[j][0]) && (posString_x_left <= arrStringTrack[j][1])) || 
					((posString_x_right >= arrStringTrack[j][0]) && (posString_x_right <= arrStringTrack[j][1]))
					) { // same horz
					if (
						((posString_y_top >= arrStringTrack[j][2]) && (posString_y_top <= arrStringTrack[j][3])) || 
						((posString_y_bottom >= arrStringTrack[j][2]) && (posString_y_bottom <= arrStringTrack[j][3]))
						) { // same vert
						blnSkipString = true;
						break;
					}
				}
			}
			
			// if the length of the line is larger than the length of the text string, drawString and string doesn't overlap other strings
			if ((string_x_length < total_x) && (!blnSkipString)) {
				eval(SketchCanvas.setColor("black"));
				eval(SketchCanvas.drawString(strLength, posString_x_left, posString_y_top));
				
				// store x1, y1, x2, y2 cords of string (rectangle)
				arrStringTrack[intStringIndex][0] = posString_x_left; 
				arrStringTrack[intStringIndex][1] = posString_x_right; 
				arrStringTrack[intStringIndex][2] = posString_y_top; 
				arrStringTrack[intStringIndex][3] = posString_y_bottom; 
				intStringIndex++;
			}
		}
	}
	
	return(intStringIndex);
}

/***********************************************
trimString
	This function removes trailing spaces from a string
	Params
		str - string to trim
***********************************************/

function trimString (str) {
	str = this != window? this : str;
	return str.replace(/^\s+/g, '').replace(/\s+$/g, '');
}