function getObj(targetName) {
// gets a reference to targetName, browser independent
	if (document.all) {
		return document.all[targetName];
	} else if (document.getElementById) {
		return document.getElementById(targetName);
	}
}


function replace(string,text,by) {
// Replaces text with by in string
    var strLength = string.length, txtLength = text.length;
    if ((strLength == 0) || (txtLength == 0)) return string;

    var i = string.indexOf(text);
    if ((!i) && (text != string.substring(0,txtLength))) return string;
    if (i == -1) return string;

    var newstr = string.substring(0,i) + by;

    if (i+txtLength < strLength)
        newstr += replace(string.substring(i+txtLength,strLength),text,by);

    return newstr;
}


function checkdate(strDate) {
	//returns true if the date entered is valid, false if invalid
	//expects a date in mm/dd/yyyy or mm-dd-yyyy format
	//a 2-digit year will be converted according to the variables set below
	
	var reDateSplit = /\/|-/;	//dates may be split with either a / or a -
	var i;
	var r = false;				//the return value
	
	//the following variables are for handling valid year values
	var nDateThreshold = 83;	//if the two-digit year entereded is below this, we add nDateHighyear, else we add nDateLowyear
	var nDateHighyear = 2000;
	var nDateLowyear = 1900;
	var nDateMinyear = 1900;	//the lowest allowable year
	var nDateMaxyear = 3000;	//the highest allowable year
	//for example a year of "96" would not be below nDateThreshold, so we would add nDateLowyear to get 1996
	//a year of "95" would be below nDateThreshold, so we would add ndateHighyear to get 2095
	
	
	var aDatePieces = strDate.split(reDateSplit);
	if (aDatePieces.length == 3) {
		//we have 3 pieces of a date, continue processing
		if (aDatePieces[0].length < 3 && aDatePieces[1].length < 3) {
			//eliminate the cases where someone enters a date like 8/013/02 or something
			for (i=0; i<3; i++) {
				aDatePieces[i] = parseInt(aDatePieces[i], 10);	//turn each piece of the date into a base-10 integer (allows preceeding zeros)
			}
			if (aDatePieces[0] && aDatePieces[1]) {
				//month and day are above 0
				if (aDatePieces[0] <= 12 && ((aDatePieces[2] < 100) || (aDatePieces[2] > nDateMinyear && aDatePieces[2] < nDateMaxyear))) {
					//the month is between 1 and 12, AND...
					//the year is either a 2-digit year (0-99), or is a 4-digit year between nDateMinyear and nDateMaxyear
					switch (aDatePieces[0]) {
						case 1:
						case 3:
						case 5:
						case 7:
						case 8:
						case 10:
						case 12:
							r = (aDatePieces[1] < 32);
							break;
						case 4:
						case 6:
						case 9:
						case 11:
							r = (aDatePieces[1] < 31);
							break;
						default:
							//february, check for leap year
							if (aDatePieces[2] < 100) {
								//it's a 2-digit year (0-99), check the threshold
								if (aDatePieces[2] < nDateThreshold) {
									aDatePieces[2] += nDateHighyear;
								} else {
									aDatePieces[2] += nDateLowyear;
								}
							}
							if (((aDatePieces[2] % 4 == 0) && (aDatePieces[2] % 100 != 0)) || (aDatePieces[2] % 400 == 0)) {
								//it's a leap year, i.e.:
								//the year is divisible by 4 AND NOT divisible by 100, unless it's also divisible by 400
								r = (aDatePieces[1] < 30);
							} else {
								r = (aDatePieces[1] < 29);
							}
							break;
					}
				}
			}
		}
	}
	
	return r;
}


function decimalFormat(val) {
// returns a value formatted to two decimal places
	var v;
	val = parseFloat(val);
	if (isNaN(val)) return "0.00";
	val = parseInt(Math.round(val*100))/100.0;
	v = parseInt(Math.round(val*100));
	if (v%100==0) return val + ".00";
	if (v%10==0) return val + "0";
	return val;
}


function getNum(english) {
// turns the english word of a one-digit number into the actual number
	switch(english.toLowerCase()) {
		case "one":
			return 1;
			break;
		case "two":
			return 2;
			break;
		case "three":
			return 3;
			break;
		case "four":
			return 4;
			break;
		case "five":
			return 5;
			break;
		case "six":
			return 6;
			break;
		case "seven":
			return 7;
			break;
		case "eight":
			return 8;
			break;
		case "nine":
			return 9;
			break;
		case "ten":
			return 10;
			break;
		default:
			return 0;
			break;
	}
}


function getSize(suffix) {
// retrieves a single numeric representation of a size input field (which consists of an integer text field (or now a dropdown) and a fractional dropdown
	var o, v;
	v = 0;
	o = getObj("sizea"+suffix);
	if (o) {
		if (o.type) {
			if (o.type=="select-one") {
				if (!isNaN(parseInt(o.options[o.selectedIndex].value))) {
					v = parseInt(o.options[o.selectedIndex].value);
				}
			} else {
				v = 0;
				if (!isNaN(parseInt(o.value))) {
					v += parseInt(o.value);
					o.value = v;
				} else {
					o.value = "";
				}
			}
		}
	}
	o = getObj("sizeb"+suffix);
	if (o) {
		if (o.type) {
			if (o.type=="select-one") {
				if (o && !isNaN(parseFloat(o.options[o.selectedIndex].value))) {
					v += parseFloat(o.options[o.selectedIndex].value);
				}
			} else {
				if (!isNaN(parseInt(o.value))) {
					v += parseInt(o.value);
				}
			}
		}
	}
	return v;
}


function setSize(suffix, size) {
// given a suffix and a numeric size value, this function attempts to set the two parts of a size input (integer text and fractional dropdown)
	var i, o, a, b;
	a = parseInt(size);
	if (!isNaN(a)) {
		b = parseFloat(size-a);
		if (isNaN(b)) b = 0;
		o = getObj("sizea"+suffix);
		if (o && o.type) {
			if (o.type=="select-one") {
				for (i=0; i<o.options.length; i++) {
					o.options[i].selected = (parseInt(o.options[i].value)==a);
				}
			} else {
				o.value = a;
			}
		}
		o = getObj("sizeb"+suffix);
		if (o) {
			for (i=0; i<o.options.length; i++) {
				o.options[i].selected = (o.options[i].value==b);
			}
		}
	}
}


function eighthFormat(val) {
// outputs a decimal value as a fractional value
	var num, part;
	num = parseInt(val);
	val = parseFloat(val)
	if (!isNaN(num) && !isNaN(val)) {
		part = val - parseFloat(num);
		part = eighth(part*8.0);
		return "" + num + (part=="" ? "" : "-") + part;
	} else {
		return "0";
	}
}


function eighth(numerator) {
// given a numerator (assumed to be numerator/8), returns a reduced fraction
	numerator = parseInt(numerator);
	if (!isNaN(numerator)) {
		switch (numerator) {
			case 1:
				return "1/8";
				break;
			case 2:
				return "1/4";
				break;
			case 3:
				return "3/8";
				break;
			case 4:
				return "1/2";
				break;
			case 5:
				return "5/8";
				break;
			case 6:
				return "3/4";
				break;
			case 7:
				return "7/8";
				break;
			default:
				return "";
				break;
		}
	} else {
		return "";
	}
}

function sizeField(suffix, val, onchange) {
	// render a size field, which consists of two parts, the integer text part, and the fractional dropdown
	var val1, val2, r, v;
	r = "";
	val1 = parseInt(val);
	if (isNaN(val1)) val1 = 0;
	val2 = val-val1;
	r += "<input type=\"text\" name=\"sizea"+suffix+"\" id=\"sizea"+suffix+"\" value=\"" + (val1>0 ? val1 : "") + "\" size=\"3\"" + (onchange!="" ? " onchange=\""+onchange+"\"" : "") + " /> ";
	r += "<select name=\"sizeb"+suffix+"\" id=\"sizeb"+suffix+"\"" + (onchange!="" ? " onchange=\"" + onchange + "\"" : "") + ">";
	for (var i=0; i<8; i++) {
		v = parseFloat(i/8.0);
		r += "<option value=\"" + v + "\"" + (val2==v ? " selected=\"selected\"" : "") + ">" + eighth(i) + "</option>";
	}
	r += "</select>";
	return (r);
}

function dynamicToEnglish(val) {
	switch(val) {
		case "configwidth":
			return "[Width of the Config]";
			break;
		case "minmodelwidth":
			return "[Minimum Width of the Model]";
			break;
		case "maxmodelwidth":
			return "[Maximum Width of the Model]";
			break;
		default:
			return val;
			break;
	}
}

