/* 
   This script solves a system of two linear equations in 
   Standard Form and displays the steps for the 
   Substitution Method and the Linear Combination Method.

   Copyright (C) 2008-2009 by Allen W. Murphy
   GPL v2 (See below.)
*/

/* ****************************************************************** */
function solution(A, B, C, D, E, F) {

    /* Returns the solution to a linear system
       with two equations and two variables. */
       
    var x1 = (B*F-E*C)/(B*D-E*A);
    var y1 = (E*C*A-B*F*A)/(B*B*D-E*A*B) + C/B;
   
    var point = {x: x1, y: y1};
   
    return point;
}	


/* ****************************************************************** */
function lcm(A, D) {
	
	/* Returns the least common multiple for numbers A and D. */
	
	var minimum = Math.min(Math.abs(A), Math.abs(D));
	
	for (var i=minimum; i<=Math.abs(A)*Math.abs(D); i = i + minimum) {
		if (i % Math.abs(A) == 0 && i % Math.abs(D) == 0) {
			return i;
		}
	}
	
	return i;
}

/* ****************************************************************** */
function linearCombination(output, A, B, C, D, E, F, L) {

	var i = 1; //set the sign of the factor
	
	if (A*(L/A) == D*(L/D)) {
		i = -1;
	}
		
	/* Steps */
	output = output + '<span class="boldblue">Line up terms and get ' + 
		'opposites to eliminate x terms.</span><br />';
	output = output + '<span class="step_gray">(Multiply Equation #1 by ' +
		L/A + " and " + "Equation #2 by " + 1*i*L/D + ".)</span><br />";

	output = output + "(" + A + "x + " + B + "y = " + C + 
		")(" + L/A + ")<br />";
	output = output + "(" + D + "x + " + E + "y = " + F + 
		")(" + (1*i*L/D) + ")<br />";

	output = output + '<span class="step_gray">(The system now looks like ' +
		"this.)</span><br />";
	output = output + L + "x + " + (B*L/A) + "y = " + (C*L/A) + 
		"<br />";
	output = output + -1*L + "x + " + (1*i*E*L/D) + "y = " + 
		RndIt(1*i*F*L/D) + "<br />";
		
	output = output + '<br /><span class="boldblue">Add columns down.' +
		"</span><br />";
	output = output + (B*L/A + 1*i*E*L/D) + "y = " + 
		((C*L/A) + (1*i*F*L/D)) + "<br />";

	output = output + '<span class="step_gray">(Divide by ' +
		RndIt(B*L/A + 1*i*E*L/D) +".)</span><br />";

	var point = solution(A, B, C, D, E, F);
	output = output + '<span class="boldred">y = ' + RndIt(point.y) + '</span><br />';

	output = output + '<br /><span class="boldblue">Substitute the ' + 
		'y value back into Equation #1:</span><br />';
	output = output +  A + "x + " + B + "(" + RndIt(point.y) + ") = " + C + 
		"<br />";
	output = output + '<span class="step_gray">(Multiply.' + 
		')</span><br />';
	output = output +  A + "x + " + RndIt(B*point.y) + " = " + C + 
		"<br />";
	output = output + '<span class="step_gray">(Subtract ' + RndIt(B*point.y) +
		' from both sides.)</span><br />';
	output = output +  A + "x = " + RndIt(1*C + (-1*B*point.y)) + "<br />";
	output = output + '<span class="step_gray">(Divide both sides by ' +
		A + '.)</span><br />';
	output = output +  '<span class="boldred">x = ' + RndIt(point.x) + 
		"</span><br />";

	return output;
}

/* ****************************************************************** */
function solveForY(output, A, B, C) {

	/* Display steps for solving equation 1 for y */
	
	output = output + '<span class="boldblue">Solve Equation 1 for y:</span><br />';
	output = output + A + "x + " + B + "y = " + C + "<br />";
	output = output + '<span class="step_gray">(Subtract ' + A + 
		'x from both sides.)</span><br />';
	output = output + B + "y = " + C + " - (" + A + "x)<br />";
	output = output + '<span class="step_gray">(Divide by ' + B + 
		'.)</span><br />';
	output = output + "y = " + RndIt(-A/B) + "x + (" + RndIt(C/B) + ")<br />";

	return output;
}

/* ****************************************************************** */
function substituteForY(output, A, B, C, D, E, F){

	/* Substitute expression for y in equation. */

	output = output + '<br /><span class="boldblue">Substitute for y in ' + 
		'Equation 2:</span><br />';
	output = output + D + "x + " + E + "y = " + F + "<br />";
	output = output + '<span class="step_gray">(Substitute expression' + 
		' for y.)</span><br />';

	output = output + D + "x + " + E + "(" + RndIt(-A/B) + 
		"x + (" + RndIt(C/B) + ")" +") = " + F + "<br />";
	output = output + '<span class="step_gray">(Distribute ' + E +
		'.)</span><br />';
	output = output + D + "x + " + RndIt(-E*A/B) + "x + (" + 
		(E*C/B) + ") = " + F + "<br />";
	output = output + '<span class="step_gray">(Combine like terms.)' + 
		'</span><br />';
		
	var temp = RndIt(1*D + (-E*A/B));
	output = output + temp + "x + (" + RndIt(E*C/B) + ") = " + F + "<br />";
	output = output + '<span class="step_gray">(Subtract ' + RndIt(E*C/B) + 
		' from both sides.)</span><br />';

	output = output + temp + "x = " + RndIt(1*F-(E*C/B)) + "<br />";
	output = output + '<span class="step_gray">(Divide by ' + temp + 
		'.)</span><br />';

	var point = solution(A, B, C, D, E, F);
	output = output + '<span class="boldred">x = ' + RndIt(point.x) + '</span><br />';
	
	return output;
}

/* ****************************************************************** */
function substituteForX(output, A, B, C, D, E, F) {

	/* Substitute x value for variable. */

	output = output + '<br /><span class="boldblue">Substitute the ' + 
		'x value back in:</span><br />';
	
	var point = solution(A, B, C, D, E, F);

	output = output + "y = " + RndIt(-A/B) + "x + (" + RndIt(C/B) + ")<br />";
	output = output + '<span class="step_gray">(Substitute value' + 
		' for x.)</span><br />';

	output = output + "y = " + RndIt(-A/B) + "(" + RndIt(point.x) + ") + (" + 
		RndIt(C/B) + ")<br />";
	output = output + '<span class="step_gray">(Multiply.' + 
		')</span><br />';

	output = output + "y = " + RndIt((-A/B)*point.x) + " + (" + RndIt(C/B) + ")<br />";
	
	output = output + '<span class="step_gray">(Add.' + 
		')</span><br />';

	output = output + '<span class="boldred">y = ' + RndIt(point.y) + '</span><br />';
	
	return output;
}

/* ****************************************************************** */
function showSteps(output, A, B, C, D, E, F) {

	/* Substitution Method */
	output = output +"<b><u>Substitution Method</u></b><br />";
	output = output + '<span class="step_gray">(Numbers rounded to nearest thounsandth.' + 
		')</span><br /><br />';
	output = solveForY(output, A, B, C);
	output = substituteForY(output, A, B, C, D, E, F);
	output = substituteForX(output, A, B, C, D, E, F);
	
	/* Linear Combination Method */
	output = output +"<br /><br /><b><u>Linear " + 
		"Combination Method</u></b><br />";
	output = output + '<span class="step_gray">(Numbers rounded to nearest thounsandth.' + 
		')</span><br /><br />';
	output = linearCombination(output, A, B, C, D, E, F, lcm(A, D));
	
	/* Display output on web page. */
	document.getElementById("steps").innerHTML = output;

	/* Graphing Method */
	DrawLines(A, B, C, D, E, F);
	
}

/* ****************************************************************** */
function DrawLines(A, B, C, D, E, F) {

	var applet = document.ggbApplet;
	var pt = solution(A, B, C, D, E, F);

	var line1 = A + "x + " + B + "y = " + C;
	var line2 = D + "x + " + E + "y = " + F;

	/* Reset Geogebra Applet */
	applet.deleteObject("a");
	applet.deleteObject("b");
	applet.deleteObject("A");

	applet.evalCommand(line1);
	applet.setColor("a",255,0,0);
	applet.evalCommand(line2);
	applet.setColor("b",0,10,200);
	applet.evalCommand("A = (" + pt.x + "," + pt.y + ")"); 
}


/* ****************************************************************** */
function solveClicked() {

	/* Called when the "Solve" button is clicked. */
	
	var sol;
	var output = ""; // Initaize output string.
	
	var A = document.systemform.A.value;
	var B = document.systemform.B.value;
	var C = document.systemform.C.value;
	var D = document.systemform.D.value;
	var E = document.systemform.E.value;
	var F = document.systemform.F.value;

	if (B*D != E*A && B*B*D != E*A*B && B != 0) {
		
		sol = solution(A, B, C, D, E, F);
		
		if (isNaN(sol.x) || isNaN(sol.y)) {
			document.getElementById("result").innerHTML = "Coefficient Error!";
		}
		else {
			document.getElementById("result").innerHTML = "(" + 
				Math.round(sol.x * 100)/100 + ", " + 
				Math.round(sol.y * 100)/100 + ")";
		}
		
		showSteps(output, A, B, C, D, E, F);
	}
	else {
		document.getElementById("result").innerHTML = "No Solution";
	}
	
}

/* ****************************************************************** */
function RndIt(n) {
	return Math.round(n*1000)/1000;
}

/*
 This script is free software; you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
 the Free Software Foundation; either version 2 of the License, or
 (at your option) any later version.

 This script is distributed in the hope that it will be useful,
 but WITHOUT ANY WARRANTY; without even the implied warranty of
 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 GNU General Public License for more details.

 You should have received a copy of the GNU General Public License
 along with Foobar; if not, write to the Free Software
 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
*/


syntax highlighted by Code2HTML, v. 0.9.1