var acceptableChars = /[0-9.]/;
var acceptableFirstChar = /[-0-9.]/;
var frstRowEmpty = true;
var scndRowEmpty = true;
var thrdRowEmpty = true;
var useDecimals = false;

function resetVariables()
{
  acceptableChars = /[0-9.]/;
  acceptableFirstChar = /[-0-9.]/;
  frstRowEmpty = true;
  scndRowEmpty = true;
  thrdRowEmpty = true;
  useDecimals = false;
}

function hideAll()
{  
  form0.style.display = "none";
  form1.style.display = "none";
  form2.style.display = "none";
  form3.style.display = "none";
  form4.style.display = "none";
  form5.style.display = "none";
  form6.style.display = "none";
}

function toggle(e) 
{ 
  hideAll();
  e.style.display = "";
}

function controlInput(txtBxId)
{
  var txtLength = txtBxId.value.length;
  var currentChar = txtBxId.value.charAt(txtLength-1);
  var priorStr = txtBxId.value.substring(0, txtLength-1); 

  if (txtLength == 1)
  {
    if (!acceptableFirstChar.test(currentChar))
      txtBxId.value = "";
  }
  else if (!acceptableChars.test(currentChar))
      txtBxId.value = priorStr;
  if (currentChar == ".")
  {
     acceptableChars = /[0-9]/;
     useDecimals = true;
  }
}

function checkBlanks(frm)
{
  if (!frm.box0.value && !frm.box1.value)
    frstRowEmpty = true;
  else if(frm.box0.value && !frm.box1.value)
  {
    frm.box1.value = Number(frm.box0.value) + 10;
    frstRowEmpty = false;
  }
  else if(!frm.box0.value && frm.box1.value)
  {
    frm.box0.value = Number(frm.box1.value) - 10;
    frstRowEmpty = false;
  }
  else
    frstRowEmpty = false;

  if (!frm.box2.value && !frm.box3.value)
    scndRowEmpty = true;
  else if (frm.box2.value && !frm.box3.value)
  {
    frm.box3.value = Number(frm.box2.value) + 10;
    scndRowEmpty = false;
  }
  else if (!frm.box2.value && frm.box3.value)
  {
    frm.box2.value = Number(frm.box3.value) - 10;
    scndRowEmpty = false;
  }
  else 
    scndRowEmpty = false;

  if (!frm.box4.value && !frm.box5.value)
    thrdRowEmpty = true;
  else if (frm.box4.value && !frm.box5.value)
  {
    frm.box5.value = Number(frm.box4.value) + 10;
    thrdRowEmpty = false;
  }
  else if (!frm.box4.value && frm.box5.value)  
  {
    frm.box4.value = Number(frm.box5.value) - 10;
    thrdRowEmpty = false;
  }	
  else
    thrdRowEmpty = false;

  if (frstRowEmpty && scndRowEmpty && thrdRowEmpty)
    return true;
  else return false;
}



function zeroInRange(frstValue, scndValue)
{
  if (0>=frstValue && 0<=scndValue)
    return true;
  else
    return false;
}

function  multiplicity(primeFactorArray)
{
   multiplicityArray = new Array();
   numberArray = new Array();
   var tempNumber = primeFactorArray[0];
   numbMultArray = new Array();
   var j=0;
   numberArray[0] = tempNumber;
   multiplicityArray[0] = 0;
   noOfFactors = primeFactorArray.length;	
   for (count=0; count<noOfFactors; count++)
   {
	if (tempNumber == factorArray[count])
		multiplicityArray[j]= multiplicityArray[j] + 1;
	else
	{
		j++;
		multiplicityArray[j] = 1;
		tempNumber = factorArray[count];
		numberArray[j] = tempNumber;
	}
   }
   for (count=0; count<multiplicityArray.length;count++)
   {
	numbMultArray[2*count] = numberArray[count];
        numbMultArray[2*count+1] = multiplicityArray[count];
   }  
   return numbMultArray;
} 

function primeFactors(posInteger)
{	
	var temp;
	if (posInteger<0)
		temp = -posInteger;
	else
		temp = posInteger;
	var divisor = 2;
	factorArray = new Array();
	var factorCount = 0;
	if (temp == 2)
		factorArray[factorCount] = temp;
	else
	{
	   do
	   {
		if (temp%divisor == 0)
		{
			temp = temp/divisor;
			factorArray[factorCount] = divisor;
			factorCount++;
		}
		else
			divisor++;	
	   } while (divisor<=Math.floor(temp/2))
	   factorArray[factorCount] = temp;
	}
	return factorArray;
}

function allFactors(posInteger)
{ 
   var temp;
   var numOfFactors = 1;
   primeFactorsArray = new Array();
   primeFactorsArray = primeFactors(posInteger);
	numbMult = new Array();
	numbMult = multiplicity(primeFactorsArray);  
	allFactorsArray = new Array();
	var numbOfDistPrimes = numbMult.length/2;
	placeValueArray = new Array(numbOfDistPrimes);
	var remainder;
	var factor;
	placeValueArray[numbOfDistPrimes-1]=1;
	for (var i=numbOfDistPrimes-1;i>0;i--)
	   placeValueArray[i-1] = (numbMult[2*i+1]+1)*placeValueArray[i];
	if (Math.abs(posInteger)>1)
	{
	  for (var i=0;i<numbOfDistPrimes;i++)  
	     numOfFactors = numOfFactors*(numbMult[2*i+1]+1); 
	  for (var i=0; i<numOfFactors; i++)
	  {
	     remainder = i;
	     factor = 1;
	     for (var j=0; j<numbOfDistPrimes; j++)
	     {
	     	temp = Math.floor(remainder/placeValueArray[j]);  
		remainder = remainder%placeValueArray[j];
		factor *= Math.pow(numbMult[2*j],temp); 
	     }
	     allFactorsArray[i] = factor;
	  }
	}
	else allFactorsArray[0] = 1;
	return allFactorsArray;
}


function numberSort(numberArray)
{ //sorts from smallest to largest
   arrayLength = numberArray.length;
   temp = new Array(arrayLength);
   temp = numberArray;
   var tempN;
   for (var j=arrayLength; j>1; j--)
   {
     for (var i=0; i<j-1; i++)
     {
       if (temp[i]>temp[i+1])  //swap the numbers
       {
	 tempN = temp[i];
	 temp[i]=numberArray[i+1];
	 temp[i+1] = tempN;
       }
     }
   }
   return temp;
}


function quotientArray(value0, value1, value2, value3)
{
  quotientArry = new Array();
  tempArray = new Array();
  var zeroInMultiplicand = zeroInRange(value0, value1);
  if (!zeroInMultiplicand)
  {
    tempArray[0] = value2/value1;
    tempArray[1] = value2/value0;
    tempArray[2] = value3/value1;
    tempArray[3] = value3/value0;
  }
  else if (value0 == 0 /*and value1 != 0*/)
  {
    tempArray[0] = 0;
    tempArray[1] = 1;
    tempArray[2] = value3;
    tempArray[3] = value2;
    tempArray[4] = value3/value1;
    tempArray[5] = value2/value1;
  }   
  else if (/*value0 != 0 and */value1 == 0)
  {
    tempArray[0] = 0;
    tempArray[1] = 1;
    tempArray[2] = value2;
    tempArray[3] = value3;
    tempArray[4] = value3/value0;
    tempArray[5] = value2/value0;
  }    
  else  
  {
    tempArray[0] = 0;
    tempArray[1] = value2;
    tempArray[2] = value3;
    tempArray[3] = -1*value2;
    tempArray[4] = -1*value3;
    tempArray[5] = value2/value0;
    tempArray[6] = value2/value1;
    tempArray[7] = value3/value0;
    tempArray[8] = value3/value1;
  }
  quotientArry = numberSort(tempArray);
  return quotientArry;
}


function productArray(value0, value1, value2, value3)
{ 
  productArry = new Array(4);
  tempArray = new Array(4);
  tempArray[0] = value0 * value2;
  tempArray[1] = value0 * value3;
  tempArray[2] = value1 * value2;
  tempArray[3] = value1 * value3;
  productArry = numberSort(tempArray);
  return productArry; 
}


function checkDivisibility(divisor, dividend)
{
  if (dividend%divisor == 0)
    return true;
  else 
    return false;
}


function fillDefaults(f, worksheetCase)
{ 
  prdArray = new Array(4);
  factorArray = new Array();
  var arrayLength;
  var c0;
  var c1;
  var c2;
  var c3;
  switch (worksheetCase)
  {
    case 'add':
      if (checkBlanks(f))
      {  //Everything is empty so fill in all boxes.
	f.box0.value = "0";
        f.box1.value = "10";
        f.box2.value = "0";
        f.box3.value = "10";
        f.box4.value = "0";
        f.box5.value = "20";
      }  //next, 2 rows are empty so fill in one more row with default values
      else if (frstRowEmpty && scndRowEmpty && !thrdRowEmpty)
      {
        f.box0.value = "0";
        f.box1.value = "10";
      }
      else if (frstRowEmpty && !scndRowEmpty && thrdRowEmpty)
      {
        f.box0.value = "0";
        f.box1.value = "10";
      }
      else if (!frstRowEmpty && scndRowEmpty && thrdRowEmpty)
      {
        f.box2.value = "0";
        f.box3.value = "10";
      }
      checkBlanks(f);  //one row is empty so fill it depending on values in other two rows.
      if (!frstRowEmpty && !scndRowEmpty)
      {
         f.box4.value = Number(f.box0.value) + Number(f.box2.value);
         f.box5.value = Number(f.box1.value) + Number(f.box3.value);
      }
      else if (!frstRowEmpty && !thrdRowEmpty)
      {
         f.box2.value = Number(f.box4.value) - Number(f.box0.value);
         f.box3.value = Number(f.box5.value) - Number(f.box1.value);
      }
      else if (!scndRowEmpty && !thrdRowEmpty)
      {
         f.box0.value = Number(f.box4.value) - Number(f.box2.value);
         f.box1.value = Number(f.box5.value) - Number(f.box3.value);
      }
      
      if (!f.yes.checked && !f.no.checked)
        f.yes.checked = true;
      break;

    case 'mult':
      if (checkBlanks(f))
      {
        f.box0.value = "0";
        f.box1.value = "10";
        f.box2.value = "0";
        f.box3.value = "10";
        f.box4.value = "0";
        f.box5.value = "100";
      }   //next, 2 rows are empty so fill in one more row with default values
      else if (frstRowEmpty && scndRowEmpty && !thrdRowEmpty)
      {
        f.box2.value = "1";
        factorArray = numberSort(allFactors(Number(f.box5.value)));
	arrayLength = factorArray.length;
        f.box3.value = factorArray[Math.ceil(arrayLength/2) - 1];
 	f.box0.value = "1";
	f.box1.value = factorArray[Math.ceil(arrayLength/2)];
      }
      else if (frstRowEmpty && !scndRowEmpty && thrdRowEmpty)
      {
        f.box0.value = "0";
        f.box1.value = "10";
      }
      else if (!frstRowEmpty && scndRowEmpty && thrdRowEmpty)
      {
        f.box2.value = "0";
        f.box3.value = "10";
      }
      checkBlanks(f);  //one row is empty so fill it depending on values in other two rows.
      if (!frstRowEmpty && !scndRowEmpty && thrdRowEmpty)
      { 
         prdArray = productArray(Number(f.box0.value), Number(f.box1.value), Number(f.box2.value), Number(f.box3.value)); 
         f.box4.value = prdArray[0].toString();
         f.box5.value = prdArray[3].toString();
      }
      else if (!frstRowEmpty && !thrdRowEmpty && scndRowEmpty)
      {
        if (checkDivisibility(Number(f.box0.value), Number(f.box4.value)))
          c0 = Number(f.box4.value)/Number(f.box0.value);
         else
          c0 = 1;
        if (checkDivisibility(Number(f.box0.value), Number(f.box5.value)))
          var c1 = Number(f.box5.value)/Number(f.box0.value);
         else
          c1 = 1;
        if (checkDivisibility(Number(f.box1.value), Number(f.box4.value)))
          var c2 = Number(f.box4.value)/Number(f.box1.value);
         else
          c2 = 1;
        if (checkDivisibility(Number(f.box1.value), Number(f.box5.value)))
          var c3 = Number(f.box5.value)/Number(f.box1.value);
         else
          c3 = 1;
        prdArray = numberSort([c0, c1, c2, c3]);
        f.box2.value = prdArray[0];
        f.box3.value = prdArray[3];
      }  
      else if (!scndRowEmpty && !thrdRowEmpty && frstRowEmpty)
      {
        if (checkDivisibility(Number(f.box2.value), Number(f.box4.value)))
          c0 = Number(f.box4.value)/Number(f.box2.value);
         else
          c0 = 1;
        if (checkDivisibility(Number(f.box2.value), Number(f.box5.value)))
          var c1 = Number(f.box5.value)/Number(f.box2.value);
         else
          c1 = 1;
        if (checkDivisibility(Number(f.box3.value), Number(f.box4.value)))
          var c2 = Number(f.box4.value)/Number(f.box3.value);
         else
          c2 = 1;
        if (checkDivisibility(Number(f.box3.value), Number(f.box5.value)))
          var c3 = Number(f.box5.value)/Number(f.box3.value);
         else
          c3 = 1;
        prdArray = numberSort([c0, c1, c2, c3]);
        f.box0.value = prdArray[0];
        f.box1.value = prdArray[3];
      } 
      if (!f.yes.checked && !f.no.checked)
        f.yes.checked = true;

      break;

    case 'subt':
      if (checkBlanks(f))
      {  //Everything is empty so fill in all boxes.
        f.box0.value = "0";
        f.box1.value = "20";
        f.box2.value = "0";
        f.box3.value = "10";
        f.box4.value = "0";
        f.box5.value = "10";
      }  //2 rows are empty so fill in one more row with default values
      else if (frstRowEmpty && scndRowEmpty && !thrdRowEmpty)
      {
        f.box2.value = "0";
        f.box3.value = "10";
      }
      else if (frstRowEmpty && !scndRowEmpty && thrdRowEmpty)
      {
        f.box4.value = "0";
        f.box5.value = "10";
      }
      else if (!frstRowEmpty && scndRowEmpty && thrdRowEmpty)
      {
        f.box2.value = "0";
        f.box3.value = "10";
      }
      checkBlanks(f);
      if (!frstRowEmpty && !scndRowEmpty && thrdRowEmpty)
      { 
         f.box4.value = Number(f.box0.value) - Number(f.box3.value);
         f.box5.value = Number(f.box1.value) - Number(f.box2.value);
      }
      else if (!frstRowEmpty && !thrdRowEmpty && scndRowEmpty)
      {
         f.box2.value = Number(f.box0.value) - Number(f.box4.value);
         f.box3.value = Number(f.box1.value) - Number(f.box5.value);
      }
      else if (!scndRowEmpty && !thrdRowEmpty && frstRowEmpty)
      {
         f.box0.value = Number(f.box4.value) + Number(f.box2.value);
         f.box1.value = Number(f.box5.value) + Number(f.box3.value);
      }
      if (!f.yes.checked && !f.no.checked)
        f.no.checked = true;
      break;
    case 'divide':
      if (checkBlanks(f))
      {
        f.box0.value = "0";
        f.box1.value = "100";
        f.box2.value = "1";
        f.box3.value = "10";
        f.box4.value = "0";
        f.box5.value = "10";
      }  
      else if (frstRowEmpty && scndRowEmpty && !thrdRowEmpty)
      {
        f.box2.value = "1";
        f.box3.value = "10";
      }
      else if (frstRowEmpty && !scndRowEmpty && thrdRowEmpty)
      {
        f.box4.value = "1";
        f.box5.value = "10";
      }
      else if (!frstRowEmpty && scndRowEmpty && thrdRowEmpty)
      {
        f.box2.value = "1";
        factorArray = numberSort(allFactors(Number(f.box1.value)));
	arrayLength = factorArray.length;
        f.box3.value = factorArray[Math.ceil(arrayLength/2) - 1];
 	f.box4.value = "1";
	f.box5.value = factorArray[Math.ceil(arrayLength/2)];
      }
      checkBlanks(f);  
      if (frstRowEmpty && !scndRowEmpty && !thrdRowEmpty)
      { 
         prdArray = productArray(Number(f.box4.value), Number(f.box5.value), Number(f.box2.value), Number(f.box3.value)); 
         f.box0.value = prdArray[0].toString();
         f.box1.value = prdArray[3].toString();
      }  
      else if (!frstRowEmpty && scndRowEmpty && !thrdRowEmpty)
      {
          if (Number(f.box1.value)%Number(f.box5.value) == 0)
	    f.box3.value = Number(f.box1.value)/Number(f.box5.value)
	  else f.box3.value = Math.ceil(Number(f.box1.value)/Number(f.box5.value));
	  if (Number(f.box0.value)%Number(f.box4.value) == 0)
	    f.box2.value = Number(f.box0.value)/Number(f.box4.value)
	  else f.box2.value = 1;
      }   
      else if (!frstRowEmpty && !scndRowEmpty && thrdRowEmpty)
      {
          if (Number(f.box1.value)%Number(f.box3.value) == 0)
	    f.box5.value = Number(f.box1.value)/Number(f.box3.value)
	  else f.box5.value = Math.ceil(Number(f.box1.value)/Number(f.box3.value));
	  if (Number(f.box0.value)%Number(f.box2.value) == 0)
	    f.box4.value = Number(f.box0.value)/Number(f.box2.value)
	  else f.box4.value = 1;	
      }    
      if (!f.yes.checked && !f.no.checked)
        f.no.checked = true;
      break;
    }  //end switch statement
  if (!f.numOfRows.value)
    f.numOfRows.value = "10";
  if (!f.numOfCols.value)
    f.numOfCols.value = "5";
  if (!f.portrait.checked && !f.landscape.checked)
    f.portrait.checked = true;
}



function subset(value0, value1, possValue0, possValue1, keyWord)
{
  if (value0>=possValue0 && value1<=possValue1)
    return true;
  else
  {
    alert ("Based on your other numbers, your " + keyWord + " values are not a subset of the possible values which range from " + possValue0 + " to " + possValue1 + ".");
    return false;
  }
}



function validateForm(form)
{ 
  var subsetOf;
  var lowerValue;
  var upperValue;
  var lowPossValue;
  var upperPossValue;
  prdArray = new Array(4);
  factorArray = new Array();
  var arrayLength;

  for (var i=0; i<form.elements.length; i++)
  { 
    if (form.elements[i].value == "")
    {
       alert("Please fill out the form completely or hit 'Defaults' before hitting submit.");
       return false;
    }
  }
  for (var i=1; i<4; i++)
  {
    if (Number(form.elements[2*i].value) > Number(form.elements[2*i+1].value))
    {
      alert("At least one of your minimums is larger than the corresponding maximum.");
      return false;
    }
  }
  switch (form.worksheetType.value)
  {
    case "addition":
    case "addSubtract":

      lowerValue = Number(form.box4.value);
      upperValue = Number(form.box5.value);
      lowPossValue = Number(form.box0.value)+Number(form.box2.value);
      upperPossValue = Number(form.box1.value)+Number(form.box3.value);
      subsetOf = subset(lowerValue, upperValue, lowPossValue, upperPossValue, 'Sum');
      if (!subsetOf)
        return false;

      lowerValue = Number(form.box0.value);
      upperValue = Number(form.box1.value);
      lowPossValue = Number(form.box4.value) - Number(form.box3.value);
      upperPossValue = Number(form.box5.value) - Number(form.box2.value);
      subsetOf = subset(lowerValue, upperValue, lowPossValue, upperPossValue, 'First Addend');
      if (!subsetOf)
        return false;

      lowerValue = Number(form.box2.value);
      upperValue = Number(form.box3.value);
      lowPossValue = Number(form.box4.value) - Number(form.box1.value);
      upperPossValue = Number(form.box5.value) - Number(form.box0.value);
      subsetOf = subset(lowerValue, upperValue, lowPossValue, upperPossValue, 'Second Addend');
      if (!subsetOf)
        return false;

      break;

    case "subtraction":

      lowerValue = Number(form.box0.value);
      upperValue = Number(form.box1.value);
      lowPossValue = Number(form.box4.value)+Number(form.box2.value);
      upperPossValue = Number(form.box5.value)+Number(form.box3.value);
      subsetOf = subset(lowerValue, upperValue, lowPossValue, upperPossValue, 'Minuend');
      if (!subsetOf)
        return false;

      lowerValue = Number(form.box4.value);
      upperValue = Number(form.box5.value);
      lowPossValue = Number(form.box0.value)-Number(form.box3.value);
      upperPossValue = Number(form.box1.value)-Number(form.box2.value);
      subsetOf = subset(lowerValue, upperValue, lowPossValue, upperPossValue, 'Difference');
      if (!subsetOf)
        return false;

      lowerValue = Number(form.box2.value);
      upperValue = Number(form.box3.value);
      lowPossValue = Number(form.box0.value)-Number(form.box5.value);
      upperPossValue = Number(form.box1.value)-Number(form.box4.value);
      subsetOf = subset(lowerValue, upperValue, lowPossValue, upperPossValue, 'Subtrahend');
      if (!subsetOf)
        return false;

      break;
    case "multiplication":
    case "multiplyDivide":
      prdArray = productArray(Number(form.box0.value), Number(form.box1.value), Number(form.box2.value), Number(form.box3.value));
      upperPossValue = prdArray[3];
      lowPossValue = prdArray[0];
      lowerValue = Number(form.box4.value);
      upperValue = Number(form.box5.value);
      subsetOf = subset(lowerValue, upperValue, lowPossValue, upperPossValue, 'Product');
      if (!subsetOf)
        return false;

      factorArray = quotientArray(Number(form.box0.value), Number(form.box1.value), Number(form.box4.value), Number(form.box5.value));
      arrayLength = factorArray.length;
      upperPossValue = factorArray[arrayLength-1];
      lowPossValue = factorArray[0];
      lowerValue = Number(form.box2.value);
      upperValue = Number(form.box3.value);
      subsetOf = subset(lowerValue, upperValue, lowPossValue, upperPossValue, 'Multiplier');
      if (!subsetOf)
        return false;

      factorArray = quotientArray(Number(form.box2.value), Number(form.box3.value), Number(form.box4.value), Number(form.box5.value));
      arrayLength = factorArray.length;
      upperPossValue = factorArray[arrayLength-1];
      lowPossValue = factorArray[0];
      lowerValue = Number(form.box0.value);
      upperValue = Number(form.box1.value);
      subsetOf = subset(lowerValue, upperValue, lowPossValue, upperPossValue, 'Multiplicand');
      if (!subsetOf)
        return false;
      break;
    case "division":
      prdArray = productArray(Number(form.box4.value), Number(form.box5.value), Number(form.box2.value), Number(form.box3.value));
      upperPossValue = prdArray[3];
      lowPossValue = prdArray[0];
      lowerValue = Number(form.box0.value);
      upperValue = Number(form.box1.value);
      subsetOf = subset(lowerValue, upperValue, lowPossValue, upperPossValue, 'Dividend');
      if (!subsetOf)
        return false;

      factorArray = quotientArray(Number(form.box2.value), Number(form.box3.value), Number(form.box0.value), Number(form.box1.value));
      arrayLength = factorArray.length;
      upperPossValue = factorArray[arrayLength-1];
      lowPossValue = factorArray[0];
      lowerValue = Number(form.box4.value);
      upperValue = Number(form.box5.value);
      subsetOf = subset(lowerValue, upperValue, lowPossValue, upperPossValue, 'Quotient');
      if (!subsetOf)
        return false;

      factorArray = quotientArray(Number(form.box4.value), Number(form.box5.value), Number(form.box0.value), Number(form.box1.value));
      arrayLength = factorArray.length;
      upperPossValue = factorArray[arrayLength-1];
      lowPossValue = factorArray[0];
      lowerValue = Number(form.box2.value);
      upperValue = Number(form.box3.value);
      subsetOf = subset(lowerValue, upperValue, lowPossValue, upperPossValue, 'Divisor');
      if (!subsetOf)
        return false;
      break;
  }
  return true;
}

function openpopup(popurl)
{
  winpops=window.open(popurl,"","width=320,height=240,top=300,left=300");
}
