//
// Lower tail quantile for standard normal distribution function.
//
// This function returns an approximation of the inverse cumulative
// standard normal distribution function.  I.e., given P, it returns
// an approximation to the X satisfying P = Pr{Z <= X} where Z is a
// random variable from the standard normal distribution.
//
// The algorithm uses a minimax approximation by rational functions
// and the result has a relative error whose absolute value is less
// than 1.15e-9.
//
// Author:      Peter J. Acklam
// (Javascript version by Alankar Misra @ Digital Sutras (alankar@digitalsutras.com))
// Time-stamp:  2003-05-05 05:15:14
// E-mail:      pjacklam@online.no
// WWW URL:     http://home.online.no/~pjacklam
// An algorithm with a relative error less than 1.15á10-9 in the entire region.

function NORMSINV(p)
{
	// Coefficients in rational approximations
	var a = new Array ( -3.969683028665376e+01, 2.209460984245205e+02, -2.759285104469687e+02, 1.383577518672690e+02, -3.066479806614716e+01, 2.506628277459239e+00 );
	var b = new Array ( -5.447609879822406e+01, 1.615858368580409e+02, -1.556989798598866e+02, 6.680131188771972e+01, -1.328068155288572e+01 );
	var c = new Array ( -7.784894002430293e-03, -3.223964580411365e-01, -2.400758277161838e+00, -2.549732539343734e+00, 4.374664141464968e+00,  2.938163982698783e+00 );
	var d = new Array ( 7.784695709041462e-03, 3.224671290700398e-01, 2.445134137142996e+00, 3.754408661907416e+00 );
	
	// Define break-points.
	var plow  = 0.02425;
	var phigh = 1 - plow;

	// Rational approximation for lower region:
	if ( p < plow ) {
		var q  = Math.sqrt(-2*Math.log(p));
		return (((((c[0]*q+c[1])*q+c[2])*q+c[3])*q+c[4])*q+c[5]) / ((((d[0]*q+d[1])*q+d[2])*q+d[3])*q+1);
	}

    // Rational approximation for upper region:
    if ( phigh < p ) {
        var q  = Math.sqrt(-2*Math.log(1-p));
		return -(((((c[0]*q+c[1])*q+c[2])*q+c[3])*q+c[4])*q+c[5]) / ((((d[0]*q+d[1])*q+d[2])*q+d[3])*q+1);
	}

    // Rational approximation for central region:
	var q = p - 0.5;
	var r = q*q;
	return (((((a[0]*r+a[1])*r+a[2])*r+a[3])*r+a[4])*r+a[5])*q / (((((b[0]*r+b[1])*r+b[2])*r+b[3])*r+b[4])*r+1);
}

function calculateXbar() {

	var values = new Object();

	values.B4 = Number(document.inputForm.input_B4.value);
	values.B5 = Number(document.inputForm.input_B5.value);
	values.B6 = Number(document.inputForm.input_B6.value) / 100; 	// percentage
	values.B17 = Number(document.inputForm.input_B17.value);

	if (!isValidNumber(values.B4)) {
		showWarning("Please enter a number for population standard deviation.");
		document.inputForm.input_B4.focus();
		return false;
	}
	if (!isValidNumber(values.B5)) {
		showWarning("Please enter a number for sampling error.");
		document.inputForm.input_B5.focus();
		return false;
	}
	if (!isValidNumber(values.B6, 0, 1)) {
		showWarning("Please enter a percentage for confidence level.");
		document.inputForm.input_B6.focus();
		return false;
	}
	
	values.B9 = NORMSINV((1-values.B6)/2);	
	values.B10 = ((values.B9*values.B4)/values.B5) * ((values.B9*values.B4)/values.B5);	
	values.B13 = Math.ceil(values.B10);	
	values.B18 = (values.B10*values.B17)/(values.B10+values.B17-1);
	values.B19 = Math.ceil(values.B18);
		
	showResults(values);
	
	return false;

}

function calculateP() {

	var values = new Object();

	values.B4 = Number(document.inputForm.input_B4.value);
	values.B5 = Number(document.inputForm.input_B5.value);
	values.B6 = Number(document.inputForm.input_B6.value) / 100; 	// percentage
	values.B17 = Number(document.inputForm.input_B17.value);

	if (!isValidNumber(values.B4)) {
		showWarning("Please enter a number for population standard deviation.");
		document.inputForm.input_B4.focus();
		return false;
	}
	if (!isValidNumber(values.B5)) {
		showWarning("Please enter a number for sampling error.");
		document.inputForm.input_B5.focus();
		return false;
	}
	if (!isValidNumber(values.B6, 0, 1)) {
		showWarning("Please enter a percentage for confidence level.");
		document.inputForm.input_B6.focus();
		return false;
	}
	
	values.B9 = NORMSINV((1-values.B6)/2);
	values.B10 = (values.B9*values.B9*values.B4*(1-values.B4))/(values.B5*values.B5);	
	values.B13 = Math.ceil(values.B10);
	values.B18 = (values.B10*values.B17)/(values.B10+values.B17-1);
	values.B19 = Math.ceil(values.B18);
		
	showResults(values);
	
	return false;

}

function showResults(values) {
	for ( var i in values ) {
		if (document.getElementById("result_" + i)) {
			document.getElementById("result_" + i).innerHTML = values[i];
		}
	}
	document.getElementById("resultsColumn").style.display = "block";
}

function showWarning (str) {
	document.getElementById("warningText").innerHTML = str;
}

function isValidNumber(value, minValue, maxValue) {
	if (value != 0 && value == "") return false;
	if (value != Number(value)) return false;
	if (minValue != null) {
		if (value < minValue) return false;
	}
	if (maxValue != null) {
		if (value > maxValue) return false;
	}
	return true;
}

function calculateProcessSigma() {
	
	var values = new Object();
	
	values.totalDefects = Number(document.inputForm.input_defects.value);
	values.opportunities = Number(document.inputForm.input_opportunities.value);
	
	if (!isValidNumber(values.totalDefects)) {
		showWarning("Please enter a number for total defects.");
		document.inputForm.input_defects.focus();
		return false;
	}
	if (!isValidNumber(values.opportunities)) {
		showWarning("Please enter a number for opportunities.");
		document.inputForm.input_opportunities.focus();
		return false;
	}	
	
	// Defects Per Million Opportunities (DPMO) = ((Total Defects) / (Total Opportunities)) * 1,000,000
	values.DPMO = (values.totalDefects / values.opportunities) * 1000000;
	
	// Defects (%) = ((Total Defects) / (Total Opportunities)) * 100
	values.defects = Math.round((values.totalDefects / values.opportunities) * 100);	
	
	// Yield (%) = 100 - (Defects Percentage)	
	values.yield = 100 - values.defects;
	
	// process Sigma = NORMSINV(1-((Total Defects) / (Total Opportunities))) + 1.5	
	values.processSigma = NORMSINV(1-(values.totalDefects / values.opportunities)) + 1.5
	
	showResults(values);
	return false;
}


function showHelp(str) {
	var obj = new Object();
	document.getElementById("helpText").innerHTML = str;
	document.getElementById("helpText").style.display = "block";	
}

function hideHelp() {
	document.getElementById("helpText").innerHTML = "&nbsp;";
}