// Global variables
var inverse = new Array ();
var m = new Array ();
var c = new Array ();
var eq = new Array();
var mrow;
var op;


function enterEquations() {
	identityMatrix();
	var j;
	m[0] = new Array();
	m[1] = new Array();
	for (var i = 0; i < 4; i++) {
		j = parseInt(Math.floor(i/3));
		var e = $('x'+i).value;
		if (/\//.test(e)) {
			var d = e.split("/");
			e = parseFloat(d[0]/d[1]);
		} else {
			e = parseFloat(e);
		}		
		m[j][i%2] = e;
	}
	for (i = 0; i < 2; i++) {
		c[i] = new Array();
		var e = $('c'+i).value;
		if (/\//.test(e)) {
			var d = e.split("/");
			e = parseFloat(d[0]/d[1]);
		} else {
			e = parseFloat(e);
		}
		c[i][0] = e;
	}
	hide("instructions");
	hide("equations");
	show("operations");
	$('equations').reset();
	displayMatrix();	
	return;
}

// Generate a random system of equations with integer coefficients
function generateSystem() {
	identityMatrix();
	var selected = $("difficulty").selectedIndex;
	m[0] = new Array();
	m[1] = new Array();
	c[0] = new Array();
	c[1] = new Array();	
	if (selected==1) {
		m[0][0] = Math.floor(Math.random()*10)+1;
		m[0][1] = rs();
		m[1][0] = Math.floor(Math.random()*10)+1;
		m[1][1] = -1*m[0][1];
		c[0][0] = (Math.floor(Math.random()*10)+1);
		c[1][0] = (-1*c[0][0]+20*(m[0][0]+m[1][0]))%(m[0][0]+m[1][0])+(m[0][0]+m[1][0])*(Math.floor(Math.random()*10)+1);
	}
	
	if (selected==2) {
		m[0][0] = Math.floor(Math.random()*10)+1;
		m[0][1] = rs();
		m[1][0] = Math.floor(Math.random()*10)+1;
		m[1][1] = -1*m[0][1];
		c[0][0] = (Math.floor(Math.random()*10)+1);
		c[1][0] = (-1*c[0][0]+20*(m[0][0]+m[1][0]))%(m[0][0]+m[1][0])+(m[0][0]+m[1][0])*(Math.floor(Math.random()*10)+1);		
	}
	if (selected==3) {
		m[0][0] = Math.floor(Math.random()*10)+1;
		m[0][1] = Math.floor(Math.random()*10)+1;
		m[1][0] = Math.floor(Math.random()*10)+1;
		m[1][1] = Math.floor(Math.random()*10)+1;
		c[0][0] = Math.floor(Math.random()*10)+1;
		c[1][0] = (-1*c[0][0]+20*(m[0][0]+m[1][0]))%(m[0][0]+m[1][0])+(m[0][0]+m[1][0])*(Math.floor(Math.random()*10)+1);		
	}
	if (selected==4) {
		m[0][0] = rs()*Math.floor(Math.random()*10)+1;
		m[0][1] = rs()*Math.floor(Math.random()*10)+1;
		m[1][0] = rs()*Math.floor(Math.random()*10)+1;
		m[1][1] = rs()*Math.floor(Math.random()*10)+1;
		c[0][0] = rs()*Math.floor(Math.random()*10)+1;
		c[1][0] = rs()*Math.floor(Math.random()*10)+1;
	}
	
	hide("main");
	show("operations");
	displayMatrix();
	return;
}

function rs() {
	var r = Math.floor(Math.random()*2);
	if (!r) {
		r--;
	}
	return r;
}

// Pick an operation for this round.
function pickOperation(el) {
	op = el.selectedIndex;
	// multiply two rows
	if (op==1) {
		text("systems","Now select a row you want to have multiplied.");
		hide("operation");
		show("multiply");
	}
	// add the two equations
	if (op==2) {
		doOp(el);
	}
	// subtract the two equations
	if (op==3) {
		doOp(el);
	}
	return;
}

// Get the number to multiply the given row with.
function pickNumber(el) {
	mrow = el.selectedIndex;
	text("systems", "Enter a number you want to multiply by.  This number may be positive, negative, a decimal, or a fraction written in a/b form.");
	hide("multiply");
	show("number");
	show("mbutton");
	return;
}

// Do the operation with either the given row, or with the given pair of rows
function doOp(el) {
	if (op==1) {
		var n = $('number').value;
		if (/\//.test(n)) {
			var d = n.split("/");
			n = parseFloat(d[0]/d[1]);
		} else {
			n = parseFloat(n);
		}
		if (!n) {
			alert("You must enter a number!");
			return;
		}
		hide("number");
		hide("mbutton");
		hide("systems");
		var a = multRow(mrow-1,n);
		m = product(a,m);
		inverse = product(a,inverse);
		c = findSolution();
		displayMatrix();
	}
	if (op==2) {
		hide("operations");
		show("single");
		// Add equation 1 from equation 2
		eq[0] = m[0][0]+m[1][0];	
		eq[1] = m[0][1]+m[1][1];
		eq[2] = c[0][0]+c[1][0];
		// Check to see that a variable canceled out
		if ((!eq[0])||(!eq[1])) {
			// If the variable cancels out, return a simplier equation
			if (Math.abs(eq[1])!=eq[1]) {
				var sign = " - ";
			} else {
				var sign = " + ";
			}
			$("solution").innerHTML = "<br /><div style=\"display: block; width: 300px; height: 100px; text-align: center;\">"+ eq[0] + "x " + sign + eq[1] + "y " +  " = " + eq[2] + "</div>";
			return;
		}
	}
	if (op==3) {
		hide("operations");
		show("single");
		// Subtract equation 2 from equation 1
		eq[0] = m[0][0]-m[1][0];	
		eq[1] = m[0][1]-m[1][1];
		eq[2] = c[0][0]-c[1][0];
		// Check to see that a variable canceled out
		if ((!eq[0])||(!eq[1])) {
			// If the variable cancels out, return a simplier equation
			if (Math.abs(eq[1])!=eq[1]) {
				var sign = " - ";
			} else {
				var sign = " + ";
			}
			$("solution").innerHTML = "<br /><div style=\"display: block; width: 300px; height: 100px; text-align: center;\">"+ eq[0] + "x " + sign + eq[1] + "y " +  " = " + eq[2] + "</div>";
			return;
		}
	}
	text("systems", "Pick an operation, and either a row, or a pair of rows to use for the operation to see what the effect of your operation is.");
	show("systems");
	show("operation");
	$("operations").reset();
	identityMatrix();
	return;
}

function pickDivision(el) {
	if ((el.selectedIndex==1)||(el.selectedIndex==2)) {
		alert("That operation will not help in solving this equation");
		return;
	}
	if (el.selectedIndex==3) {
		text("singleeq", "Enter a number you want to divide by.  This number may be positive, negative, a decimal, or a fraction written in a/b form.");
		hide("division");
		show("lastvalue");
		show("lastcompute");
	}
	if (el.selectedIndex==4) {
		text("singleeq", "Enter a number you want to multiply by.  This number may be positive, negative, a decimal, or a fraction written in a/b form.");
		hide("division");
		show("lastvalue");
		show("lastcompute");
	}
	return;
}

// Multiply two matrices.
function product(left,right) {
	var answer = new Array();
	var sum = 0;
	for (var i = 0; i<2; i++) {
		answer[i] = new Array();
		for (var j = 0; j<2; j++) {
			for (var k =0; k<2;k++) {
				sum += left[i][k]*right[k][j];
			}
			answer[i][j] = sum;
			sum = 0;
		}		
	}
	return answer;	
}

// Construct a row multiplication matrix
function multRow (row, num) {
	var answer = new Array ();
	for (var m = 0; m<2; m++) {
		answer[m] = new Array ();
		for (var n = 0; n<2; n++) {
			if (m == n) {
				if (m == row) {
					answer[m][n]=num;
				
				} else {
					answer[m][n]=1;
				}
			} else {
				answer[m][n]=0;
			}
		}
	}	
	return answer;
}

// Construct a row addition (or subtraction) matrix
function addRow (row, col, num) {
	var answer = new Array ();
	for (var m = 0; m<2; m++) {
		answer[m] = new Array ();
		for (var n = 0; n<2; n++) {
			if (m == n) {
				answer[m][n] = 1;
			} else {
				answer[m][n] = 0;
			}
			if ((m==row)&&(n==col)) {
				answer[m][n] = num;
			}
		}
	}	
	return answer;
}

// Create an appropriate identity matrix to hold our Gaussian elimination.  Note that we call it the inverse, since it will eventually be the inverse matrix.
function identityMatrix() {
	for (var i = 0; i<2; i++){		
		inverse[i] = new Array();
		for (var j = 0; j<2;j++) {
			if (i==j) {
				inverse[i].push(1);
			} else {
				inverse[i].push(0);
			}
		}
	}
	return;
}

// Need special multiplication for finding the answer.
function findSolution() {
	var ans = new Array();	
	var sum = 0;	
	for (var i = 0; i<2; i++) {
		ans[i] = new Array();
		for (var k = 0; k<2; k++) {
			sum += inverse[i][k]*c[k];
		}
		ans[i][0] = sum;
		sum = 0;
	}	
	return ans;	
}

// Hide a given element
function hide(el) {
	$(el).style.display = "none";
	return;
}

// Show a given element
function show(el) {
	$(el).style.display = "block";
	return;
}

// Update the innerHTML for an element
function text(el, t) {
	$(el).innerHTML = t;
	return;
}

// helper function for DOM
function $(el) {
	return document.getElementById(el);
}

// Display a matrix as a table
function displayMatrix() {
	var signs = new Array();
	if (Math.abs(m[0][1])!=m[0][1]) {
		signs[0] = "-";
	} else {
		signs[0] = "+";
	}
	if (Math.abs(m[1][1])!=m[1][1]) {
		signs[1] = "-";
	} else {
		signs[1] = "+";
	}	
	var text = "<br /><div style=\"display: block; width: 300px; height: 100px; text-align: center;\"><table id=\"equation\"><tr><td>"+m[0][0]+"x</td><td>"+signs[0]+"</td><td>"+Math.abs(m[0][1])+"y</td><td> = </td><td>"+c[0][0]+"</td></tr><tr><td>"+m[1][0]+"x</td><td>"+signs[1]+"</td><td>"+Math.abs(m[1][1])+"y</td><td> = </td><td>"+c[1][0]+"</td></tr></table></div>"
	var solution = $('solution');
	solution.innerHTML = text + "<br />\n";
}

function clearForms() {
	$('equations').reset();
	$('operations').reset();
	$('main').reset();
	$('single').reset();
	return;	
}

window.onload = setTimeout('clearForms()', 500);
