// copyright 2010 Laura Shaffer Mills// circumference/diameter -- treat as constantsvar gkMeasureCirc =		0;var gkMeasureDia =		1;// country -- treat as constantsvar gkCountryAustraliaIrelandUK =	0;var gkCountryCanadaUS =				1;var gkCountryChinaJapan =			2;var gkCountryEurope =				3;var gkCountryGermanyRussia =		4;var gkCountrySwitzerland =			5;// array by country code for letter sizing (not numbers)var gkAllowLetterSize = [true, false, false, false, false, false]var gkStrTooSmall = "too small to calculate";var gkStrTooLarge = "too large to calculate";// keep original size and units so math stays more accurate// final ring size (Fn)var gFnOrigCircOrDia = 0;			// circumferencevar gFnOrigUnits = 0;				// mmvar gFnOrigDistance = 0;var gFnOrigCountry = 1;				// US/Canada// ring circumference (Cr)var gCrOrigCountry = 1;				// US/Canadavar gCrOrigSize = 0;var gCrOrigUnits = 0;				// mmvar gCrCircumference;// metal clay ring size (Mc)var gMcOrigCountry = 1;				// US/Canadavar gMcRingSize = 0;				// number for ring size (not letter)var gMcMetalClay = 0;// set up "onload" to initializewindow.onload = function() {	var imageC = new Image();	var imageD = new Image();	var imageW = new Image();	var imageT = new Image();	// preload rollover images	imageC.src = "images/ringmeasureC.gif";	imageD.src = "images/ringmeasureD.gif";	imageW.src = "images/ringmeasureW.gif";	imageT.src = "images/ringmeasureT.gif";	// disable "Enter" key for submitting form	document.onKeyPress = ignoreEnterKey;	// set up ring image rollovers	document.getElementById("ringpictC").onmouseover = function(evt)		{ changeRingPict("ringpictC",evt); };	document.getElementById("ringpictC").onmouseout = function(evt)		{ changeRingPict("off",evt); };	document.getElementById("ringpictD").onmouseover = function(evt)		{ changeRingPict("ringpictD",evt); };	document.getElementById("ringpictD").onmouseout = function(evt)		{ changeRingPict("off",evt); };	document.getElementById("ringpictW").onmouseover = function(evt)		{ changeRingPict("ringpictW",evt); };	document.getElementById("ringpictW").onmouseout = function(evt)		{ changeRingPict("off",evt); };	document.getElementById("ringpictT").onmouseover = function(evt)		{ changeRingPict("ringpictT",evt); };	document.getElementById("ringpictT").onmouseout = function(evt)		{ changeRingPict("off",evt); };	// set up functions for final ring size	document.getElementById("inRingCircOrDia1").onchange = changeOriginalUnits;	// circ/dia	document.getElementById("inRingUnits1").onchange = changeOriginalUnits;	// mm/in	document.getElementById("inFingerDistance1").onchange = newOriginalNum;	// size number	// inFingerDistance1Validation	document.getElementById("inCountry1").onchange = calcFinalRingSize;	// country	// outRingSize1	// set up functions for ring circumference	//	(verification of final ring size, or find metal clay mandrel size)	document.getElementById("inCountry2").onchange = changeCountryCircumference;	// country	document.getElementById("inRingSize2").onchange = newOriginalNumCircumference;	// ring size	// inRingSize2Validation	document.getElementById("inRingUnits2").onchange = changeFinalUnitsCircumference;	// mm/in	// outRingCirc2	// set up functions for metal clay ring size (varies by type of clay)	document.getElementById("inCountry3").onchange = changeMetalClayCountry;	// country	document.getElementById("inRingSize3").onchange = newMetalClayRingSizeIn;	// ring size	document.getElementById("inClayTypeRing3").onchange = changeMetalClayType;	// clay type (for shrinkage)	initializeConversions();	makeShrinkageArray();	fillDropdownClayTypes("inClayTypeRing3");}			// window.onload()// calculate the diameter/circumference from the ring sizefunction calcFinalCircumference(ringValue) {	var circumferenceMM = -1;	if (ringValue)		circumferenceMM = convertRingSize2CircMM(ringValue, gCrOrigCountry);	if ( (!isNaN(circumferenceMM)) && (circumferenceMM > 0) ) {		// convert to correct units		gCrCircumference = convertByUnit(circumferenceMM, gkUnitMillimeters, gCrOrigUnits);	// in gCrOrigUnits		// round to nearest 1/10		replaceNodeText("outRingCirc2",createDimensionString(gCrCircumference, gCrOrigUnits));	}	else		replaceNodeText("outRingCirc2","unknown");}			// calcFinalCircumference()// calculate the ring sizesfunction calcFinalRingSize() {	var finalSizeRing = "unknown";	var circumferenceMM = -1;	gFnOrigCountry = parseInt( document.getElementById("inCountry1").value );	circumferenceMM = convertByUnit(gFnOrigDistance, gFnOrigUnits, gkUnitMillimeters);	if (gkMeasureDia == gFnOrigCircOrDia)	// change diameter to circumference?		circumferenceMM *= Math.PI;	if (circumferenceMM > 0)		finalSizeRing = getSize(gFnOrigCountry,circumferenceMM);	// put answer on page	replaceNodeText("outRingSize1",finalSizeRing);}			// calcFinalRingSize()/*// calculate metal clay ring size, with shrinkagefunction calcMetalClayRingSize() {	var newRingSize = 0;	gMcOrigCountry = parseInt( document.getElementById("inCountry3").value );	gMcMetalClay = parseInt( document.getElementById("inClayTypeRing3").value );	if (gMcRingSize > 0) {		// valid ring size?		var circumferenceMM = -1;		var newCircMM = -1;		// change ring size to circumference		circumferenceMM = convertRingSize2CircMM(gMcRingSize, gMcOrigCountry);		// apply shrinkage to circumference		newCircMM = circumferenceMM / (1 - gkaShrink[gMcMetalClay]);		// find ring size for this circumference		newRingSize = getSize(gMcOrigCountry,newCircMM);	}// ### if have string answer (instead of number), this won't print it	if (newRingSize > 0)	// put on page		replaceNodeText("outClayRingSize3",newRingSize);	else		replaceNodeText("outClayRingSize3","");}			// calcMetalClayRingSize()*/// calculate metal clay ring size, with shrinkagefunction calcMetalClayRingSize() {	var newRingSize = 0;	gMcOrigCountry = parseInt( document.getElementById("inCountry3").value );	gMcMetalClay = parseInt( document.getElementById("inClayTypeRing3").value );	if (gMcRingSize > 0) {		// valid ring size?		var circumferenceMM = -1;		var newCircMM = -1;		var newCircMMMin = -1;		var newCircMMMax = -1;		var rangeString = "";		// change ring size to circumference		circumferenceMM = convertRingSize2CircMM(gMcRingSize, gMcOrigCountry);		// AVERAGE - apply shrinkage to circumference		newCircMM = gkaoShrink[gMcMetalClay].avgFromClay(circumferenceMM);		// find ring size for this circumference		newRingSize = getSize(gMcOrigCountry,newCircMM);		if (gkaoShrink[gMcMetalClay].range) {		// also find min and max			// apply shrinkage to circumference			newCircMMMin = gkaoShrink[gMcMetalClay].minFromClay(circumferenceMM);			newCircMMMax = gkaoShrink[gMcMetalClay].maxFromClay(circumferenceMM);			rangeString = " (" + getSize(gMcOrigCountry,newCircMMMin) + " - " + 				getSize(gMcOrigCountry,newCircMMMax) + ")";		}	}	if (newRingSize != 0)	// put on page		replaceNodeText("outClayRingSize3",newRingSize + rangeString);	else		replaceNodeText("outClayRingSize3","");}			// calcMetalClayRingSize()// country has changed, so check number again and recalculate answerfunction changeCountryCircumference() {	var ringValue = document.getElementById("inRingSize2").value;	gCrOrigCountry = document.getElementById("inCountry2").value;	if ( validateOriginalRingSize(ringValue) )	// may not be valid value for this country		calcFinalCircumference(gCrOrigSize);}			// changeCountryCircumference()// recalculate answer for changed unitsfunction changeFinalUnitsCircumference() {	var circumference;	var newUnits = document.getElementById("inRingUnits2").value;	circumference = convertByUnit(gCrCircumference, gCrOrigUnits, newUnits);	replaceNodeText("outRingCirc2",createDimensionString(circumference, newUnits));}			// changeFinalUnitsCircumference()// change country for metal clayfunction changeMetalClayCountry() {	calcMetalClayRingSize();}			// changeMetalClayCountry()// change metal clay type (shrinkage)function changeMetalClayType() {	calcMetalClayRingSize();}			// changeMetalClayType()// change the original value to new units// still keep the value and units *originally* entered, to keep math more consistentfunction changeOriginalUnits() {	var newOrigSize = 0;	var newMeasure = document.getElementById("inRingCircOrDia1").value;	var newUnits = document.getElementById("inRingUnits1").value;	if (gFnOrigUnits  == newUnits) {			// units as originally entered		newOrigSize = gFnOrigDistance;	}	else {		// the "original" units have changed, so recalculate "original" size value		// use gFnOrigDistance for calculation; find newOrigSize in newUnits		newOrigSize = convertByUnit(gFnOrigDistance, gFnOrigUnits, newUnits);	}	// if changed circumference/diameter, must recalculate size or change number	if (gFnOrigCircOrDia  != newMeasure) {			// circumference/diameter changed		gFnOrigCircOrDia = newMeasure;		calcFinalRingSize();		// recalculate answer	}	document.getElementById("inFingerDistance1").value = newOrigSize.toFixed(2);}			// changeOriginalUnits()// change ring picture as neededfunction changeRingPict(pictVersion,evt) {	evt = (evt) ? evt : window.event;	// some browsers won't pass event	switch (pictVersion) {		case "off":			document.getElementById("ringdim").src = "images/ringmeasure.gif";			break;		case "ringpictC":			document.getElementById("ringdim").src = "images/ringmeasureC.gif"			break;		case "ringpictD":			document.getElementById("ringdim").src = "images/ringmeasureD.gif"			break;		case "ringpictW":			document.getElementById("ringdim").src = "images/ringmeasureW.gif"			break;		case "ringpictT":			document.getElementById("ringdim").src = "images/ringmeasureT.gif"			break;		// otherwise, don't change picture	}}			// changeRingPict()// find circumference in mm from ring size and countryfunction convertRingSize2CircMM(ringSize, country) {	var circumferenceMM = -1;	// ring circumference to return// need to validate ring size (not negative, for instance) before call this ###	if (ringSize >= 0) {		switch (parseInt(country,10)) {			case gkCountryAustraliaIrelandUK:				circumferenceMM = (ringSize-1) * 1.25 + 37.5;	// ringSize "A" = 1				break;			case gkCountryCanadaUS:				circumferenceMM = (1.43 + parseFloat(ringSize) * 0.102) * 25.4;				break;			case gkCountryChinaJapan:				circumferenceMM = Math.PI * ( 13 + (parseFloat(ringSize) - 1) / 3 );				break;			case gkCountryEurope:				circumferenceMM = parseFloat(ringSize);				break;			case gkCountryGermanyRussia:				circumferenceMM = parseFloat(ringSize) * Math.PI;				break;			case gkCountrySwitzerland:				circumferenceMM = parseFloat(ringSize) + 39;				break;		}	}	return(circumferenceMM);}			// convertRingSize2CircMM()// convert size to new units and circumference/diameterfunction convertUnits(inSize, inUnits, inMeasureType, outUnits, outMeasureType) {	var newSize = 0;	// change inUnits to outUnits	if (inUnits == outUnits) {		newSize = inSize;	}	else		newSize = convertByUnit(inSize, inUnits, outUnits);	// change inMeasureType to outMeasureType	if (inMeasureType != outMeasureType) {		if (gkMeasureCirc == inMeasureType) {	// convert from cirumference to diameter			newSize = newSize / Math.PI;		}		else {									// convert from diameter to circumference			newSize = Math.PI * newSize;		}	}	return(newSize);}			// convertUnits()// make string for diameter or circumference valuefunction createDimensionString(size, units) {	var myString = "";	var temp;	var whole;					// whole number part	var numerator;	var denominator = 16;	switch (parseInt(units)) {		case gkUnitMillimeters:			// if units are in mm, use decimal (round to 0.1mm)			temp = Math.round(size * 10) / 10;		// to 1/10			myString = "" + temp;		// convert to string			break;		case gkUnitInches:			// if units are in inches, round and use 1/16 in.			whole = Math.floor(size);		// integer part			temp = size - whole;	// decimal part			numerator = Math.round(temp * denominator);		// number of 1/16ths			if (numerator == denominator) {		// rounds to next whole number				whole++;				numerator = 0;			}			while ( (numerator > 0) && ( 0 == (numerator % 2) ) ) {		// divisible by 2?				numerator /= 2;				denominator /= 2;			}			myString = "" + whole;		// convert to string -- integer part			if (numerator > 0) {				myString = myString + " " + numerator + "/" + denominator;			}			break;	}	return(myString);}			// createDimensionString()// validate that the value (circumference or diameter) is a number; if not, reset to zerofunction getEntryValues(value) {	// when user changes number for size, reset units to current value	gFnOrigCircOrDia = document.getElementById("inRingCircOrDia1").value;	gFnOrigUnits = document.getElementById("inRingUnits1").value;	gFnOrigDistance = validatePosNumber(value, "inFingerDistance1Validation", "Enter a number.");}			// getEntryValues()// find size from circumference (rounds size)function getSize(country,circumferenceMM) {	var ringSize = 0;	// ring size to return	var diameterMM = circumferenceMM / Math.PI;	var temp;	switch (country) {		case gkCountryAustraliaIrelandUK:	// start A at 37.5; 1.25mm each			var letterSize = "";			var plusNumber = "";			var numberPart;				// starts at zero; convert to letter later			var decimalPart;			// 0, 1, 2, 3, 4 for quarters			if (circumferenceMM >= 37.5) {				temp = ( (circumferenceMM - 37.5) / 1.25 );				numberPart = Math.floor(temp);				decimalPart = Math.round( (temp - numberPart) * 4 );	// nearest 1/4 size				if (4 == decimalPart)				{						// must round up					numberPart++;					decimalPart = 0;				}				if ( numberPart > 25 )		// past "Z"				{				// after Z 1/2: goes to Z + 1, Z + 1 1/2, etc.					var extra = numberPart - 25;					numberPart -= extra;					plusNumber = " + " + extra + " ";					//ringSize = gkStrTooLarge;				}				letterSize = numberPart + "A".charCodeAt(0);	// convert to letter code				switch (decimalPart) {					case 1:						ringSize = String.fromCharCode(letterSize) + plusNumber + " 1/4";						break;					case 2:						ringSize = String.fromCharCode(letterSize) + plusNumber + " 1/2";						break;					case 3:						ringSize = String.fromCharCode(letterSize) + plusNumber + " 3/4";						break;					case 4:			// shouldn't get here						// fall through					default:		// no decimal part						ringSize = String.fromCharCode(letterSize) + plusNumber;						break;				}			}			else				ringSize = gkStrTooSmall;			break;		case gkCountryCanadaUS:	// size 0 at 1.43in circ; goes by 1/10 inch (but OLD inch is 1.02)			var circumferenceIn = circumferenceMM / 25.4;			if (circumferenceIn >= 1.43) {				temp = (circumferenceIn - 1.43) / 0.102;				ringSize = Math.round(temp * 4) / 4;	// round to nearest 1/4 size			}			else				ringSize = gkStrTooSmall;			break;		case gkCountryChinaJapan:	// start size 1 at 13mm dia; add 1/3mm dia			if (diameterMM >= 13) {				temp = 1 + ( (diameterMM - 13) * 3 );				ringSize = Math.round(temp * 4) / 4;	// round to nearest 1/4 size			}			else				ringSize = gkStrTooSmall;			break;		case gkCountryEurope:		// circ in mm			ringSize = Math.round(circumferenceMM * 4) / 4;	// round to nearest 1/4 size			break;		case gkCountryGermanyRussia:	// straight mm dia			ringSize = Math.round(diameterMM * 4) / 4;	// round to nearest 1/4 size			break;		case gkCountrySwitzerland:	// 40mm size 1; straight circ in mm			if (circumferenceMM >= 40) {				var temp = circumferenceMM - 40 + 1;	// subtract 40mm				ringSize = Math.round(temp * 4) / 4;	// round to nearest 1/4 size			}			else				ringSize = gkStrTooSmall;			break;	}	return(ringSize);}			// getSize()function newMetalClayRingSizeIn() {	var ringValue = document.getElementById("inRingSize3").value;	// see if ring size valid for this country	if ( true == validateFinalRingSize(ringValue) )		calcMetalClayRingSize();			// calculate answer}			// newMetalClayRingSizeIn()// verify inputfunction newOriginalNum() {	getEntryValues(this.value);	calcFinalRingSize();}			// newOriginalNum()// verify inputfunction newOriginalNumCircumference() {	var ringValue = document.getElementById("inRingSize2").value;	validateOriginalRingSize(ringValue);	// may not be valid value for this country	calcFinalCircumference(gCrOrigSize);}			// newOriginalNumCircumference()// validate that the final size is a number or character size; if not, reset to zerofunction validateFinalRingSize(value) {	var goodNum = false;	var country = document.getElementById("inCountry3").value;	gMcRingSize = -1;	// this must allow a character for the size, depending on country	if (gkAllowLetterSize[country]) {		// check if it is letter		gMcRingSize = validateLetterSize(value, "inRingSize3Validation",			"Enter a letter, letter.number, or Z + number.");	}	else {		// must be number		gMcRingSize = validatePosNumber(value, "inRingSize3Validation",			"Enter a number.");//		if (gMcRingSize < 0) {		// check min. values by country? ###//			replaceNodeText("inRingSize3Validation","Number too small.");//		}	}	if (gMcRingSize >= 0)		goodNum = true;	// ### put country and units into globals as well?	return(goodNum);}			// validateFinalRingSize()// check that have letter, or letter "dot" number for ring size// returns a number for the ring size (even if started with letter)function validateLetterSize(value, errorStrID, errorStr) {	var ringSize = -1;	var regExpPatt1 = /^[A-Z]\.?(\d+)?$/i;		// single letter; opt. decimal, opt. number(s)	var regExpPatt2 = /^Z\+?(\d+)?\.?(\d+)?$/i;	// single "Z"; opt. plus, opt. number(s), opt. decimal, opt. number(s)// + 1 or more// * 0 or more// ? 0 or 1// | or// ^ $ beginning end// \. period// \s whitespace// \d digit	value = value.toUpperCase();		// change case	value = value.replace(/\s/g,"");	// remove whitespace	if ( (value.search(regExpPatt1) >= 0) || (value.search(regExpPatt2) >= 0) ) {	// letter or letter/number		// convert to number where A = 1		ringSize = value.charCodeAt(0) - "A".charCodeAt(0) + 1;		// letter part (uppercase)		if (value.length > 2) {		// must have letter, decimal, number; or letter, plus, number			// and add decimal part back, if exists			ringSize += parseFloat(value.substring(1));	// from decimal at position 1		}		if (errorStrID)			replaceNodeText(errorStrID,"");	// no error message	}	else {							// only have number -- not right		if (errorStrID)			replaceNodeText(errorStrID,errorStr);		// error message	}	return(ringSize);}			// validateLetterSize()// validate that the original size is a number or character size; if not, reset to zerofunction validateOriginalRingSize(value) {	var goodNum = false;	var country = document.getElementById("inCountry2").value;	// this must allow a character for the size, depending on country	gCrOrigUnits = document.getElementById("inRingUnits2").value;	if (gkAllowLetterSize[country]) {		// check if it is letter		gCrOrigSize = validateLetterSize(value, "inRingSize2Validation",			"Enter a letter, letter.number, or Z + number.");	}	else {		// must be number		gCrOrigSize = validatePosNumber(value, "inRingSize2Validation",			"Enter a number.");//		if (gCrOrigSize < 0) {		// check min. values by country? ###//			replaceNodeText("inRingSize2Validation","Number too small.");//		}	}	if (gCrOrigSize >= 0)		goodNum = true;	// ### put country and units into globals as well?	return(goodNum);}			// validateOriginalRingSize()
