// Globals
var X = 0;
var x = 0;
var y = 0;
var h = 0;
var xh = 0;
var hx = 0;
var t = 0;
var th = 0;
var ht = 0;
var a = 0;
var b = 0;
var quoteMark = unescape( '%22' );
var singlequoteMark = unescape( '%27' );

// *** Error Handler ******
function myErrorTrap(message,url,linenumber) {
this.parent.bottom.window.location = "wrong.html";
return (true);
} // end of on error
// ********************

function writeHeading(theTitle) {
var theText = '<center><table width = 90%><tr><td nowrap class = myButtons width = 80 align = center>' + theTitle + '</td><td nowrap><img src = ' + quoteMark + 'elts/buttonbg.gif' + quoteMark + ' width = 100% height = 4></td></tr></table></center>'
document.writeln(theText);
}

function drawLine() {
var theText = '<center><table width = 90%><tr><td><img src = ' + quoteMark + 'elts/buttonbg.gif' + quoteMark + ' width = 100% height = 4></td></tr></table></center>'
document.writeln(theText);
}

function sesame(url,hsize,vsize){ 
// Default size is 550 x 400
        var tb="toolbar=0,directories=0,status=0,menubar=0"
        tb+=",scrollbars=1,resizable=1,"
    var tbend="width="+hsize+",height="+vsize;
    if(tbend.indexOf("<undefined>")!=-1){tbend="width=550,height=400"}
        tb+=tbend
        Win_1 = window.open("","win1",tb);
        Win_1 = window.open(url,"win1",tb);
	Win_1.focus();
    }


function stripSpaces (InString)  {
	OutString=""; 
	if (InString == "") return (OutString);
	for (Count=0; Count < InString.length; Count++)  {
		TempChar=InString.substring (Count, Count+1);
		if (TempChar!=" ")
			OutString=OutString+TempChar;
	}
	return (OutString);
}

function stripChar (InString,symbol)  {
	OutString="";
	for (Count=0; Count < InString.length; Count++)  {
		TempChar=InString.substring (Count, Count+1);
		if (TempChar!=symbol)
			OutString=OutString+TempChar;
	}
	return (OutString);
}

function replaceChar (InString,oldSymbol,newSymbol)  {
	OutString="";
	for (Count=0; Count < InString.length; Count++)  {
		TempChar=InString.substring (Count, Count+1);
		if (TempChar!=oldSymbol)
			OutString=OutString+TempChar
		else OutString=OutString+newSymbol;
	}
	return (OutString);
}

function makeArray (NumElements, Fill)  {
	var Count;
	this.length = NumElements;
	for (Count = 1; Count <= NumElements; Count++)  {
		this[Count] = Fill;
	}
	return (this);
}

function checkString(InString,subString,backtrack)
// check for subString
// if backtrack = false, returns -1 if not found, and left-most location in string if found
// if backtrack = true, returns -1 if not found, and right-most location in string if found
// note that location is to the left of the substring in both cases
{
var found = -1;
var theString = InString;
var Length = theString.length;
var symbLength = subString.length;
for (var i = Length- symbLength; i >-1; i--)
	{	
	TempChar=theString.substring (i, i+ symbLength);
	if (TempChar == subString) 
			{
			found = i;
			if (backtrack) i = -1
			}
	} // i
return(found);
} // check

function replaceSubstring (InString,oldSubstring,newSubstring)  {
	OutString="";
	var sublength = oldSubstring.length;
	for (Count=0; Count < InString.length; Count++)  {
		TempStr=InString.substring (Count, Count+sublength);
		TempChar=InString.substring (Count, Count+1);
		if (TempStr!= oldSubstring)
			OutString=OutString+TempChar
		else 
			{
			OutString=OutString+ newSubstring;
			Count +=sublength-1
			}

	}
	return (OutString);
} 

function parser (InString, Sep)  {
	NumSeps=1;
	for (Count=1; Count < InString.length; Count++)  {
		if (InString.charAt(Count)==Sep)
			NumSeps++;
	}
	parse = new makeArray (NumSeps+4, "");		// my adjustments
	Start=0; Count=1; ParseMark=0;
	LoopCtrl=1;
	while (LoopCtrl==1)  {
		ParseMark = InString.indexOf(Sep, ParseMark);
		TestMark=ParseMark+0;
		if ((TestMark==0) || (TestMark==-1)){
			parse[Count]= InString.substring (Start, InString.length);
			LoopCtrl=0;
			break;
		}
		parse[Count] = InString.substring (Start, ParseMark);
		Start=ParseMark+1;
		ParseMark=Start;
		Count++;
	}
	parse[0]=Count;
	return (parse);
}

function winopen(){
// opens a window in the bottom frame
	var str = winopen.arguments[0];
	var loc = winopen.arguments[1];
	if (navigator.appName == "Microsoft Internet Explorer") this.parent.bottom.window.location = str;
	else window.open(str,loc);
} // winopen

function looksLikeANumber(theString) {
// returns true if theString looks like it can be evaluated
var result = true;
var length = theString.length;
var x = ""
var y = "1234567890-+/*. "
var yLength = y.length;
for (var i = 0; i <= length; i++)
	{ 
	x = theString.charAt(i);
		result = false;
		for (var j = 0; j <= yLength; j++) 
			{
			if (x == y.charAt(j)) {result = true; break}
			} // j
	if (result == false) return(false);
	} // i
return(result);
} // looks like a number

function shiftRight(theNumber, k) {
	if (k == 0) return (theNumber)
	else
		{
		var k2 = 1;
		var num = k;
		if (num < 0) num = -num;
		for (var i = 1; i <= num; i++)
			{
			k2 = k2*10
			}
		}
	if (k>0) 
		{return(k2*theNumber)}
	else 
		{return(theNumber/k2)}
	}

function roundSigDig(theNumber, numDigits) {
	with (Math)
		{
		if (theNumber == 0) return(0);
		else if(abs(theNumber) < 0.000000000001) return(0);
// WARNING: ignores numbers less than 10^(-12)
		else
			{
			var k = floor(log(abs(theNumber))/log(10))-numDigits+1
			var k2 = shiftRight(round(shiftRight(abs(theNumber),-k)),k)
			if (theNumber > 0) return(k2);
			else return(-k2)
			} // end else
		}
} // roundSigDig

function roundDec(theNumber, numPlaces) {
with (Math)
	{
	var x =shiftRight(round(shiftRight(theNumber,numPlaces)),-numPlaces);
	return x;
	} // with math
} // roundDec


// ********* FUNCTION PARSER ***********
function myEval(theString)
{
theString = replaceSubstring (theString,"cos","Math.cos");
theString = replaceSubstring (theString,"sin","Math.sin");
theString = replaceSubstring (theString,")(",")*(");
theString = replaceSubstring (theString,")ln",")*ln");
theString = replaceSubstring (theString,"sqrt","Math.sqrt");
theString = replaceChar (theString,"[","(");
theString = replaceChar (theString,"]",")");
theString = replaceChar (theString,"{","(");
theString = replaceChar (theString,"}",")");

return(eval(myParse(theString)));
	
}

// The above function requires all the following routines
function breakApart(InString) {
	// ******* Input: any string such as aaa*bbb or (aa*aa)*bbb
	// *** This Routine Retuns two pieces
	// *** bbb starts at the left-most operation *, /,  - or +
	// *** if it sees a paren, it stops after closure.

	theString = InString;
	var Length = theString.length;
	var outArray = new Array();
	outArray[1] = theString;
	outArray[2] = "";
	var parenCount = 0;
	var parenWatch = false;
	var looking = true;
	
	
	if (theString.substring (0,1) == "(")
		{
		parenCount++;
		parenWatch = true;
		looking = false;
		}
	// Look for operators
	
	for (Count=1; Count < Length; Count++)  
		{
		TempChar=theString.substring (Count, Count+1);
		if (TempChar == "(") 
			{parenCount ++;}
		else if (TempChar == ")") {parenCount = parenCount-1};

		if ((parenCount == 0) && (parenWatch == true))
			 {
			parenWatch = false;
			outArray[1] = theString.substring (0, Count+1);
			outArray[2] = theString.substring (Count+1, Length);
			}

		if (looking == true)
			{
		if ( ( (TempChar == "*") || (TempChar == "/") || (TempChar == "-")  ) || ( (TempChar == "+") || (TempChar == ')' )  )  )
				{ 
				
					{
					// alert(Count);
					looking = false;
					outArray[1] = theString.substring (0, Count);
					outArray[2] = theString.substring (Count, Length);
					// alert (outArray[1]);
					// alert(outArray[2]);
					} // end if hit one
				} 

			} // end if looking

		} // end of loop


	return (outArray);

} // end of breakApart

function isNumberChar (InString)  {
	if(InString.length!=1) 
		return (false);
	RefString="1234567890)";
	if (RefString.indexOf (InString, 0)==-1) 
		return (false);
	return (true);
}

function isCharHere (InString, RefString)  {
	if(InString.length!=1) 
		return (false);
	if (RefString.indexOf (InString, 0)==-1) 
		return (false);
	return (true);
}

function putProduct(InString) {
OutString="";
for (var Count=0; Count < InString.length; Count++)  {
		var TempChar=InString.substring (Count, Count+1);
		if (!isCharHere(TempChar,"xXeslcapdDuUhHtTmM(") || (Count == 0) )
			{OutString=OutString+TempChar}
		else 
			{
			var prevChar = InString.charAt(Count-1);
			if ( (isNumberChar(prevChar)) || (prevChar == x) )
				{OutString=OutString+"*"+TempChar}
			else OutString=OutString+TempChar
			}
	}
	return (OutString);
}


function reverse (InString)  {
	OutString="";
	var Length = InString.length;
	for (Count=Length; Count > -1; Count--)  {
		TempChar=InString.substring (Count, Count+1);
		if (TempChar == "(") {TempChar = ")"}
		else if  (TempChar == ")") {TempChar = "("}
		OutString=OutString+TempChar;
		}
	return (OutString);
	}

function powFix2(InString) {
	// ****Replaces one "^" by "pow"

	theString = InString;
	var Length = theString.length;
	outString = theString; 
		// in case nothing happens
	
		// Look for wedge
	var looking = true;
	for (Count=0; Count < Length; Count++)  
		{
		if (looking)
			{
			TempChar=theString.substring (Count, Count+1);
			if (TempChar == "^")
				{
				looking = false;
				rightStr = theString.substring (Count+1,Length);
				leftStr = theString.substring (0,Count);
				// deal with right-hand string
				Aray = breakApart(rightStr);
				Arg2 = Aray[1];
				rightRest = Aray[2];
			
				backString = reverse(leftStr);
				Aray = breakApart(backString);
				Arg1 = reverse(Aray[1]);
				leftRest = reverse(Aray[2]);
				outString = leftRest+"Math.pow("+Arg1+","+Arg2+")"+rightRest;
				
				} // end hif hit a wedge

			} // end of looking for a wedge
		} // end of loop

// ****** testing *******
// document.Extra.diagnostics.value += outString + cr;
// ***** end testing *****

return (outString);

} // end of powFix2

function powCheck(InString) {
	// ****checks for ^
	
	theString = InString;
	var Length = theString.length;
	
	// Look for wedge
	var found = false;
	for (Count=0; Count < Length; Count++)  
		{
		TempChar=theString.substring (Count, Count+1);
		if (TempChar == "^")
			{
			found = true;
			} // end if hit a wedge
		} // end of looking for a wedge
	return(found);


} // end of powCheck

function myParse(expression)
{
		var theString = stripSpaces(expression);		
		with (Math)
			{
		// now convert formatting from GC formatting		
		theString = putProduct(theString);
		theString = replaceSubstring(theString,"log","(1/Math.log(10))*Math.log");
		theString = replaceSubstring(theString,"ln","Math.log");
		theString = replaceSubstring(theString,"abs","Math.abs");
			while (powCheck(theString))
				{
				theString = powFix2(theString);
				// alert (theString);
				}
		theString = replaceChar(theString,"X","x");
			} // with Math
	return(theString);
} // myParse
// ******** END FUNCTION PARSER **************


// Bottom Window handlers

var theScriptString = '<STYLE TYPE=' + quoteMark + 'text/css' + quoteMark + '>BODY, LAYER, P, DIV, TABLE, TR, TD, TH {font-size: 12px; font-family: times; color: 000000;margin-top: 0pt}</STYLE>';

function writeBottomWrong(theMessage) {
var theString = "";
if (theMessage == "") theString = '<HTML>' + theScriptString + '<BODY bgcolor = "FFFFFA" text ="050005" LINK="FFFFFA" VLINK="FFFFFA"><img src = "../tutelts/goldborder.gif" width = 8 height = 100% align = right hspace = 0><center><img src = "elts/wrong.gif">';
else theString = '<HTML>' + theScriptString + '<BODY bgcolor = "FFFFFA" text ="050005" LINK="FFFFFA" VLINK="FFFFFA"><img src = "../tutelts/goldborder.gif" width = 8 height = 100% align = right hspace = 0><center><table><tr><td align = center><img src = "elts/smallx.gif"><br><table><tr><td>'
theString += theMessage ;
theString += '</td></tr></table></center>';
this.parent.bottom.document.write(theString);
this.parent.bottom.document.close();
} // writeBottomWrong

function writeBottomCorrect() {
var theString = '<HTML>' + theScriptString + '<BODY bgcolor = "FFFFFA" text ="050005" LINK="FFFFFA" VLINK="FFFFFA"><img src = "../tutelts/goldborder.gif" width = 8 height = 100% align = right hspace = 0><center><img src = "elts/check.gif"></center>'
this.parent.bottom.document.write(theString);
this.parent.bottom.document.close();
} // writeBottomCorrect

function writeBottomSmile(theMessage,x) {
// x = 1 gives one smile (with a space or text as the message)
// x = 2 gives another
// x = 3 gives a third
var theString = "";
if (theMessage == "") theString = '<HTML>' + theScriptString + '<BODY bgcolor = "FFFFFA" text ="050005" LINK="FFFFFA" VLINK="FFFFFA"><img src = "../tutelts/goldborder.gif" width = 8 height = 100% align = right hspace = 0><center><img src = "elts/bigsmiley.gif">';
else if (x == 2) theString = '<HTML>' + theScriptString + '<BODY bgcolor = "FFFFFA" text ="050005" LINK="FFFFFA" VLINK="FFFFFA"><img src = "../tutelts/goldborder.gif" width = 8 height = 100% align = right hspace = 0><center><img src = "elts/smiley2.gif"><br><table><tr><td>';
else if (x == 3) theString = '<HTML>' + theScriptString + '<BODY bgcolor = "FFFFFA" text ="050005" LINK="FFFFFA" VLINK="FFFFFA"><img src = "../tutelts/goldborder.gif" width = 8 height = 100% align = right hspace = 0><center><img src = "elts/smileyMex.gif"><br><table><tr><td>';
else theString = '<HTML>' + theScriptString + '<BODY bgcolor = "FFFFFA" text ="050005" LINK="FFFFFA" VLINK="FFFFFA"><img src = "../tutelts/goldborder.gif" width = 8 height = 100% align = right hspace = 0><center><img src = "elts/smiley.gif"><br><table><tr><td>'
theString += theMessage ;
theString += '</td></tr></table></center>';
this.parent.bottom.document.write(theString);
this.parent.bottom.document.close();
} // writeBottomWrong

function writeBottomMmmh(theMessage) {
var theString = '<HTML>' + theScriptString + '<BODY bgcolor = "FFFFFA" text ="050005" LINK="FFFFFA" VLINK="FFFFFA"><img src = "../tutelts/goldborder.gif" width = 8 height = 100% align = right hspace = 0><center><table><tr><td align = center><img src = "elts/mmh.gif"><br>'
theString += theMessage ;
theString += '</td></tr></table></center>';
this.parent.bottom.document.write(theString);
this.parent.bottom.document.close();
} // writeBottomMessage

function writeBottomMessage(theMessage) {
var theString = '<HTML>' + theScriptString + '<BODY bgcolor = "FFFFFA" text ="050005" LINK="FFFFFA" VLINK="FFFFFA"><img src = "../tutelts/goldborder.gif" width = 8 height = 100% align = right hspace = 0><center><table><tr><td>'
theString += theMessage ;
theString += '</td></tr></table></center>';
this.parent.bottom.document.write(theString);
this.parent.bottom.document.close();
} // writeBottomMessage

function writeBottomYell(theMessage) {
var theString = '<HTML>' + theScriptString + '<BODY bgcolor = "FFFFFA" text ="050005" LINK="FFFFFA" VLINK="FFFFFA"><img src = "../tutelts/goldborder.gif" width = 8 height = 100% align = right hspace = 0><center><table><tr><td align = center><img src = "elts/yell.gif"><br>'
theString += theMessage ;
theString += '</td></tr></table></center>';
this.parent.bottom.document.write(theString);
this.parent.bottom.document.close();
} // writeBottomMessage

function writeBottomYell2(theMessage) {
var theString = '<HTML>' + theScriptString + '<BODY bgcolor = "FFFFFA" text ="050005" LINK="FFFFFA" VLINK="FFFFFA"><img src = "../tutelts/goldborder.gif" width = 8 height = 100% align = right hspace = 0><center><table><tr><td align = center><img src = "elts/yell2.gif"><br>'
theString += theMessage ;
theString += '</td></tr></table></center>';
this.parent.bottom.document.write(theString);
this.parent.bottom.document.close();
} // writeBottomMessage

function putBottomDocument(theUrl) {
this.parent.bottom.document.location = theUrl;
} // putBottomDocument


// ********* Answer checking routines *********
// the following two routines are can be used in both tutorials and 
// review exercises to do answer checking and "peeking"
// handles both strings and numerical values.

// These routines use one or two other string utilities in this file
// example of html code that uses this:
// 
// <form name = "Form1">
//  <input type=text size=35 value="" name="Q1a">
// <input type="button" value = "Check" onClick = 
// "if (checkAnswer('Form1','Q1a',3,3.1419)) winopen('correct.html','bottom'); 
// else winopen('wrong.html','bottom') ">
// <input type="button" value = "Peek" onClick="togglePeek('Form1','Q1a', '3.1419')">
//

function checkAnswer(formName,fieldName,Option,correctAnswer) {
// returns true if the answer is correct, else returns false
// Option1 compares the string (spaces stripped) with the desired string
// Option 2 compares a modified string: changes X to x, Y to y, Z to z, 
// and removes * before comparing
// Option 3 evaluates the string 
// Option 4 checks to see if the string is blank & returns true if blank
// Option 5 here is for 5 decimal places accuraqcy

var theCommand = ""; 
var theString = "";
var a1 = eval("theString = stripSpaces(document."+ formName + "." + fieldName + ".value"+")" );
if (theString != "") {
if (Option == 1)
	{
	var act1 = eval("theString = stripSpaces(document."+ formName + "." + fieldName + ".value"+")" );
	if (theString == correctAnswer) return (true);
	else return (false);
	} // Option 1
else if (Option == 2)
	{
	var act1 = eval("theString = stripSpaces(document."+ formName + "." + fieldName + ".value"+")" );
	theString = replaceChar (theString,"X","x");
	theString = replaceChar (theString,"Y","y");
	theString = replaceChar (theString,"Z","z");
	theString = replaceChar (theString,"A","a");
	theString = replaceChar (theString,"B","b");
	theString = replaceChar (theString,"C","c");
	theString = stripChar(theString,"*");
	if (theString == correctAnswer) return (true);
	else return (false);
	} // Option 2
else if (Option == 3)
	{
	var act1 = eval("theString = document."+ formName + "." + fieldName + ".value" );
	// check to see if the string looks is ok for eval
	if (looksLikeANumber(theString)) 
		{
		var x = eval(theString);
		var err = Math.abs(x - correctAnswer);
		if (err < 0.00005) return (true);
		else return (false);
		}
	else return (false);
	return(false);
	} // Option 3

	else if (Option == 5)
	{
	var act1 = eval("theString = document."+ formName + "." + fieldName + ".value" );
	// check to see if the string looks is ok for eval
	if (looksLikeANumber(theString)) 
		{
		var x = eval(theString);
		var err = Math.abs(x - correctAnswer);
		if (err < 0.000005) return (true);
		else return (false);
		}
	else return (false);
	return(false);
	} // Option 5

} // endif non-empty
else if (Option == 4) return(true); // in case of empty string
}


function checkAnswerandValue(formName,fieldName,correctAnswer,minLength, maxLength, assig1,assig2,assig3, assig4) {
// use this to check for simplified expressions
// evaluates the input string in the specified form 
// & returns 1 if the answer is correct (agrees with correctAnswer)
// to within 0.00005 and is the right length otherwise set "maxerror" = whatever
// as one of the assignments
// returns 2 if the answer is right but string too long (unsimplified)
// returns 3 if answer is right but string too short 
// returns 0 if the answer is blank 
// else returns 6;
// it evalutes the input string at sthe specified values 
// Each assigi has the form "x=2" or "h=2.3" 
// minLength & maxLength are the permissable ranges of an input string
// maxTolerance is the largest possible error
// NOTE: requires GLOBAL variables x, h, or whatever is assigned

var theString = "";
var maxerror = 0.00005; 	
var a1 = eval("theString = stripSpaces(document."+ formName + "." + fieldName + ".value"+")" );
theString = theString.toLowerCase();
if (assig1 != "") var b1 = eval(assig1);  // set the values equal to numbers
if (assig2 != "") var b2 = eval(assig2);
if (assig3 != "") var b3 = eval(assig3);
if (assig4 != "") var b4 = eval(assig4);

if (theString == "") return(0);

else {
	theString = stripChar (theString, "$");		// for dollar signs
	theString = stripChar (theString, ",");		// for longer numbers
	theString = theString.toLowerCase();
	var val = myEval (theString);
	var correctVal = myEval(correctAnswer);
	var err = Math.abs(val - correctVal);
	if (err < maxerror)
		{
		if (theString.length > maxLength) return(2);
		else if  (theString.length < minLength) return(3);
		else return(1);
		}
	else return (6);
	} // endif non-empty
} // end checkAnswerandValue



function togglePeek(formName,fieldName,expression) {
// displays the given expression in formName.fieldname if not already visible
// if already visible, it hides it

var theCommand = "";
var theString = "if (document." + formName + "." + fieldName + ".value != '" + expression + "') document." + formName + "." + fieldName + ".value = '" + expression + "';  else document." + formName + "." + fieldName + ".value = '';"
// alert(theString)
var act1 = eval(theString);
return(true);
}

function togglePeek2(formName,fieldName,expression,fieldName2,expression2) {
// displays the given expression in two fields within a aform formName.fieldname if not already visible
// if already visible, it hides it
var theCommand = "";
// var theString = "if (document." + formName + "." + fieldName + ".value != '') document." + formName + "." + fieldName + ".value = ''; else document." + formName + "." + fieldName + ".value = '" + expression + "';"
var theString = "if ( (document." + formName + "." + fieldName + ".value != '" + expression + "') ||  (document." + formName + "." + fieldName2 + ".value != '" + expression2 + "') ) {document." + formName + "." + fieldName + ".value = '" + expression + "'; document." + formName + "." + fieldName2 + ".value = '" + expression2 + "' }   else {document." + formName + "." + fieldName + ".value = ''; document." + formName + "." + fieldName2 + ".value = '';} "
// alert(theString)
var act1 = eval(theString);
return(true);
}



// ************** end of answer handling routines *************

