// This variable is the number of the 1st product for creating e.g. item1, vwquantity3, etc.
// This would normally be 0, but since we have the ink charge and setup fee, it's moved up
var el0 = 1;



// Helper function to grab the date string from RTML and parse it into a 2D array
// uses variable reunionHolidays, a string with format "1/1 7/4 12/25" or similar
var reunionDaysOff;
function parseHolidays() {
  reunionDaysOff = reunionHolidays.split(" ");
  for (var i=0; i<reunionDaysOff.length; i++) {
    reunionDaysOff[i] = reunionDaysOff[i].split("/");
    reunionDaysOff[i][0] = parseInt(reunionDaysOff[i][0]) - 1; //-1 because for some reason 0=JAN, 11=DEC
    reunionDaysOff[i][1] = parseInt(reunionDaysOff[i][1]);
  }
}


// Prevent form from submitting unless total shirts is >= screenprintingFormMinOrder (from RTML)
function requireMinimumOrderOnSubmit() {
  var frm = document.getElementById('reunion-form');
  frm.onsubmit=function(){
    // On submit of form, tally the number of shirts
    var shirtCount = parseInt(document.getElementById('total-count').innerHTML);
    if (shirtCount < screenprintingFormMinOrder) {
      alert("The minimum order is "+screenprintingFormMinOrder);
      return false;
    }else if(document.getElementById('reunion-terms-input') && !document.getElementById('reunion-terms-input').checked){
      alert('Please be sure to check the box acknowledging that you have reviewed the Production & Shipping Details');
      return false;
    } else {
      var unitPrice = updateOrderSummary(); // retrieves the base unit price (no options)
      removeBlankOptions(frm);
      saveConfigInCookie(frm);
      addValuesToQuantities(frm, unitPrice); // takes base unit price. Should add in options
      removePricesFromSelects();
      removePricesFromInputs()
      return true;
    }
  }
}

function saveConfigInCookie(frm) {
  var rInputs = frm.getElementsByTagName('input');
  var rSelects = frm.getElementsByTagName('select');
  var groups = findHighestGroupNum(rInputs);

  var cdata = groups;
  for (var i=0; i<rInputs.length; ++i) {
    var name = rInputs[i].name.replace('|', "").replace('^', "");
    var value = rInputs[i].value.replace('|', "").replace('^', "");
    cdata += '^' + name + '|' + value;
  }
  for (var i=0; i<rSelects.length; ++i) {
    var name = rSelects[i].name.replace('|', "").replace('^', "");
    var value = rSelects[i].value.replace('|', "").replace('^', "");
    cdata += '^' + name + '|' + value;
  }
  // alert('Saving: '+cdata);
  createCookie('reunion'+productId, cdata, 2);
}

function loadConfigInCookie() {
  var cdata = readCookie('reunion'+productId);
  // alert('Reading: '+cdata);
  if (!cdata || cdata=="") return;

  cdata = cdata.split('^');
  var groups = cdata[0];
  // alert('groups: '+groups);
  while (groups-- > 1) addRowToOrderTable();
  // alert('len: '+cdata.length);
  for (var i=1; i<cdata.length; ++i) {
    var cparts = cdata[i].split('|');
    if ((cparts.length==2) && (cparts[0]!="")) {
      // ERROR: hashtable lookup doesn't work in IE
      var thisInput;
      if (/MSIE (\d+\.\d+);/.test(navigator.userAgent)) { //test for MSIE x.x;
        thisInput = document.getElementById(cparts[0].replace(/ /g, ""));
      } else {
        thisInput = document.reunionForm[cparts[0]];
      }
      // alert(cparts[0]+' -> '+thisInput);
      if (thisInput) thisInput.value=cparts[1];
    }
  }
}


function addValuesToQuantities(frm, unitPrice) {
  var rInputs = frm.getElementsByTagName('input');
  // Change the value of all "size" inputs to include their price, using the unit price above
  // From the earlier loop, we know all values of size inputs will parse to an integer
  for (var i=0; i<rInputs.length; ++i) {
    var thisOptSizeLoc = rInputs[i].name.indexOf(' - size ');
    if (thisOptSizeLoc!=-1) {
      var oldVal = parseInt(rInputs[i].value);
      var cost;
      if (oldVal && oldVal > 0) {
        var optionUnitPrice = parseOptionUnitPrice(rInputs[i]);
        var sizeCost = extractCostFromString(rInputs[i].name);
        cost = oldVal*(unitPrice+optionUnitPrice+(sizeCost?sizeCost:0));
        rInputs[i].style.visibility = 'hidden';
        rInputs[i].value = oldVal + ' (+' + cost.toFixed(2) + ')';
      } else {
        rInputs[i].name="";
      }
    }
  }
}

// uses variable reunionDaysOff (from parseHolidays()), reunionDaysRequired (# of days they need to process)
// also automatically excludes weekends
function insertOrderDates() {
  var monthNames = ['JAN', 'FEB', 'MAR', 'APR', 'MAY', 'JUN', 'JUL', 'AUG', 'SEP', 'OCT', 'NOV', 'DEC'];
  var todayMonth = document.getElementById('today-month');
  var todayDay = document.getElementById('today-day');
  var receiveMonth = document.getElementById('receive-month');
  var receiveDay = document.getElementById('receive-day');
  var now = new Date();

  // print the current date into the 1st calendar page
  todayMonth.innerHTML = monthNames[now.getMonth()];
  todayDay.innerHTML = now.getDate();

  var later = new Date();
  var oneDay = 1000* 60 * 60 * 24; // number of milliseconds in a day

  // advance forward reunionDaysRequired number of days
  for (var j=0; j<reunionDaysRequired; j++) {
    later.setTime(later.getTime() + oneDay);
    var dayOfWeek = later.getDay();
    if ((dayOfWeek==0)||(dayOfWeek==6)) {j--; continue;} // exclude weekends

    // exclude very holiday in the variable reunionDaysOff
    for (var i=0; i<reunionDaysOff.length; i++) {
      if ( (later.getMonth()==reunionDaysOff[i][0])&&(later.getDate()==reunionDaysOff[i][1]) ) {
        j--;
        break;
      }
    }
  }

  // print this "later" date into the 2nd calendar page
  receiveMonth.innerHTML = monthNames[later.getMonth()];
  receiveDay.innerHTML = later.getDate();
}

// reveal the "youth" sizes boxes (when user click "show youth")
function reunionShowYouth(elem) {
  var parent = elem.parentNode.parentNode; // containing table cell
  var rows = parent.getElementsByTagName('tr'); // all the rows in the size table
  for (var i=0; i<rows.length; i++) {
    if (rows[i].className.indexOf('youth-row')!=-1) rows[i].style.display='';
  }
  elem.style.display='none';
}

// Add a new row for user to buy shirts with different options
// Happens when user click "add another shirt color"
// This function uses the RTML-set variable orderDetailsOptionName, which is the name
// of the option for order details

function findHighestGroupNum(rInputs) {
  var highestNum = el0;
  for (var i=0; i<rInputs.length; i++) {
    if (rInputs[i].name.indexOf('group ')>=0) {
      currentNum = parseInt(rInputs[i].name.substring(6));
      if (currentNum > highestNum) highestNum=currentNum;
    }
  }
  return highestNum;
}

function addRowToOrderTable() {
  var rTable = document.getElementById('reunion-order-table');
  var rSelects, rInputs = rTable.getElementsByTagName('input');
  var detailsParent = document.getElementById('order-details').parentNode;
  var newOrderDetails;
  var currentNum, highestNum;

  // find the highest number currently used as a product. Add one to get 1st unused number
  highestNum = findHighestGroupNum(rInputs);
  ++highestNum;


  // clone the 1st table row
  var firstRow = rTable.getElementsByTagName('tr')[0];
  var newRow = firstRow.cloneNode(true); // true = keep all attributes from original node

  // Make sure the youth sizes from row 1 are hidden
  var yRow = newRow.getElementsByTagName('tr');
  for (var i=0; i<yRow.length; i++) {
      if (yRow[i].className=="youth-row" && yRow[i].style.display!='none') {
	  var addLink = yRow[i].parentNode.getElementsByTagName('a')[0];
	  removeYouth(addLink);
	  break;
      }
  }

  // Add [REMOVE] link into the 1st table cell of the row
  var firstCell = newRow.getElementsByTagName('td')[0];
  firstCell.innerHTML = '<a href="javascript:void(0);" onclick="removeRow(this)">[Remove]</a>';


  // Change the #s in the names of inputs to be the sum of their current value and highestNum
  // Also, reset any quantity input values to null string
  rInputs = newRow.getElementsByTagName('input');
  for (var i=0; i<rInputs.length; i++) {
    rInputs[i].value="";
    currentNum = parseInt(rInputs[i].name.substring(6));
    //var newName = 'group '+highestNum+' - '+rInputs[i].name.substring(9 + highestNum.toString().length);
    var newName = 'group '+highestNum+' - '+rInputs[i].name.substring(10);
    //alert(rInputs[i].name.substring(9 + highestNum.toString().length) +"|"+highestNum.toString().length);
    rInputs[i].setAttribute('name', newName);
    //test if browser can find this elem via hashtable (IE can't). If not, use ID in addition
    if (!document.reunionForm[newName]) {
      // alert('could not find '+newName);
      rInputs[i].setAttribute('id', newName.replace(/ /g, ""))
    } else rInputs[i].setAttribute('id', "");
  }
  // change the #s in the names of the selects to be the sum of their current value and highestNum
  rSelects = newRow.getElementsByTagName('select');
  for (var i=0; i<rSelects.length; i++) {
    if (rSelects[i].name.indexOf('group ')>=0) {
      currentNum = parseInt(rSelects[i].name.substring(6));
      //var newName = 'group '+highestNum+' - '+rSelects[i].name.substring(9 + currentNum.toString().length);
      var newName = 'group '+highestNum+' - '+rSelects[i].name.substring(10);
      
      rSelects[i].setAttribute('name', newName);
      //test if browser can find this elem via hashtable (IE can't). If not, use ID in addition
      if (!document.reunionForm[newName]) {
        rSelects[i].setAttribute('id', newName.replace(/ /g, ""));
      } else rSelects[i].setAttribute('id', "");
      updateHiddenValues(rSelects[i]);
    }
  }
  //alert(rInputs[i].name.substring(6)+"|"+rInputs[i].name+"|"+rInputs[i].id);

  // append this row to the table in the DOM structure
  if (rTable.firstChild.tagName=='TBODY') {
    rTable.firstChild.appendChild(newRow);
  } else {
    rTable.appendChild(newRow);
  }

  // update order details to initialize the new order-details hidden input field
  updateHiddenValues(document.getElementById('order-details')); // initialize order details elems
}

// update the hidden inputs around the selector to match its value
function updateHiddenValues(elem) {
  /*var hInputs = elem.parentNode.getElementsByTagName('input');
  for (var i=0; i<hInputs.length; i++) {
    if (hInputs[i].type=='hidden') hInputs[i].value=elem.value;
  }*/
  updateOrderSummary();
}

// intialize the hidden inputs around each selector in the table
function initializeHiddenValues() {
  /*var origSelects = document.getElementById('reunion-order-table').getElementsByTagName('select');
  for (var i=0; i<origSelects.length; i++) {
    updateHiddenValues(origSelects[i]);
  }*/
  updateHiddenValues(document.getElementById('order-details')); // initialize order details elems
}

// Update the order summary using the data currently displayed on the reunion-order-table
// RTML Javascript creates the variables shirtColOptionNameinkColOptionName, & shirtSizeOptionName
// to be something like "Shirt Color", "Ink Color", and "Size", respectively
function updateOrderSummary() {
  var rTable = document.getElementById('reunion-order-table');
  var rSelects = rTable.getElementsByTagName('select');
  var rInputs =  rTable.getElementsByTagName('input');

  // Create arrays to store shirt color and ink color
  var availShirtCol = [];
  var availInkCol = [];
  var shirtSizeType = []; // array of size names e.g. S, M, S, M, XL. Index is the product #
  var shirtSizeCount = [];    // array of size counts e.g. 2, 5, 0, 1. Index is the product #\
  var distinctSizeType = []; // array of distinct size names e.g. S M L XL
  var distinctSizeCount = []; // array of count for those distinct sizes

  // For each selector, find the name of the property which is the value after
  // the "group ## - " section. Then update the hidden inputs around the selector
  
  for (var i=0, c = rSelects.length; i<c; i++) {
    var selectName = rSelects[i].name.substring(rSelects[i].name.indexOf('- ')+2);
    // if this is a shirt color selector & we haven't already saved this shirt color in the list...
    if ((selectName==shirtColOptionName)&&(location_of(rSelects[i].value, availShirtCol)==-1)) {
      // start looking for an order in this row. if any shirts in this row are ordered, add this
      // color to the list
      var quantInputs = rSelects[i].parentNode.parentNode.getElementsByTagName('input');
      for (var j=0; j<quantInputs.length; j++) {
        if (parseInt(quantInputs[j].value)>=1) {
          availShirtCol.push(rSelects[i].value);
          break;
        } else quantInputs[j].value="";
      }
    } else if ((selectName==inkColOptionName)&&(location_of(rSelects[i].value, availInkCol)==-1)) {
      var quantInputs = rSelects[i].parentNode.parentNode.getElementsByTagName('input');
      for (var j=0; j<quantInputs.length; j++) {
        if (parseInt(quantInputs[j].value)>=1) {
          availInkCol.push(rSelects[i].value);
          break;
        }
      }
    }
  }

  // Find and sum the different shirt-size choices and variables
  var groupCounter = [];
  var rowOptionCosts = [], totalOptionCosts = 0.00;
  for (var i=0; i<rInputs.length; i++) {
    var inputName = rInputs[i].name;
    // If this input is a quantity, mark it in the appropriate spot on the array
    if (inputName.indexOf(' - size ')>=0) {
      var currentValue = parseInt(rInputs[i].value);
      if (!(currentValue>=1)) currentValue=0;
      var currentGroup = parseInt(inputName.substring(6)) - 1; // after 'group '
      while (currentGroup >= groupCounter.length) {
        groupCounter.push(0);
        rowOptionCosts.push(parseOptionUnitPrice(rInputs[i])); // calc options cost on this row
      }
      groupCounter[currentGroup]++;
      var currentNum = groupCounter[currentGroup];

      // add up costs of options in selects (shirt color, ink color)
      totalOptionCosts += rowOptionCosts[currentGroup] * currentValue;
      // add up costs of this shirt size
      var thisSizeUnitCost = extractCostFromString(inputName);
      if (thisSizeUnitCost) {
        totalOptionCosts += thisSizeUnitCost * currentValue;
      }

      if (shirtSizeCount[currentNum-el0]>0) {
        shirtSizeCount[currentNum-el0] += currentValue;
      } else {
        shirtSizeCount[currentNum-el0] = currentValue;
      }
      shirtSizeType[currentNum-el0] = inputName.substring(inputName.indexOf(' - size ') + 8);

    }
  }

  // Sum the size choices by size type, create a new array with no duplicate size names
  var totalShirtCount = 0;
  for (var i=0; i<shirtSizeType.length; i++) {
    var size_location = location_of(shirtSizeType[i], distinctSizeType);
    if (!(size_location>=0)) {
      size_location = distinctSizeType.push(shirtSizeType[i]) - 1;
      distinctSizeCount[size_location] = 0;
    }
    distinctSizeCount[size_location] += shirtSizeCount[i];
  }

  // Calculate total number of shirts being ordered:
  var totalShirtCount=0;
  for (var i=0; i<distinctSizeCount.length; i++) {totalShirtCount+=distinctSizeCount[i];}

  // Calculate the per-unit shirt price (excluding options)
  var unitPrice = calcPerUnitShirtPrice(totalShirtCount);
  var adjustedUnitPrice = (totalShirtCount>0) ? (unitPrice + (totalOptionCosts / totalShirtCount)) : unitPrice;



  // Calculate Setup fee (freeSetupThreshold, setupFeeValue from RTML) & Update input vwquantity0
  var setupFee;
  if (totalShirtCount==0 || totalShirtCount>=freeSetupThreshold) {
    setupFee = 0;
    document.getElementById('setupFee').value='none';
  } else {
    setupFee = setupFeeValue;
    document.getElementById('setupFee').value='Yes (+'+mssSetupFee+')';
  }

  // Calculate Ink change fee (inkFeeValue from RTML) & Update input vwquantity1
  var numInkChanges = (availInkCol.length > 1) ? (availInkCol.length-1) : 0;
  var inkFee = numInkChanges * inkFeeValue;
  if (numInkChanges==0) {
    document.getElementById('inkChangeFee').value = 'none';
  } else {
    document.getElementById('inkChangeFee').value = 'Yes (+'+(mssInkFee*numInkChanges)+')';
  }

  // Calculate Sub-total:
  var subTotal = totalShirtCount * unitPrice + setupFee + inkFee + totalOptionCosts;

  // SHOW DATA
  // Use these arrays:
  // availShirtCol, availInkCol, distinctSizeType, distinctSizeCount
  // To fill the innerHTML of the elements with these IDs:
  // shirt-color, shirt-sizes, ink-color, unit-price, total-count, setup-fee, sub-total
  document.getElementById('shirt-color').innerHTML = availShirtCol.join(', ').replace(/\(\+[^\)]*\)/g, "");
  document.getElementById('ink-color').innerHTML = availInkCol.join(', ').replace(/\(\+[^\)]*\)/g, "");
  var sizeHTML="";
  for (var i=0; i<distinctSizeCount.length; i++) {
    if (distinctSizeCount[i] > 0) {
      sizeHTML += '<span>'+distinctSizeType[i].replace(/\( *\+ *\$?([\d.]+)\)/g, "");
      sizeHTML += ':&nbsp;<b>'+distinctSizeCount[i]+'</b></span> ';
    }
  }
  document.getElementById('shirt-sizes').innerHTML = sizeHTML;
  document.getElementById('unit-price').innerHTML = '$'+adjustedUnitPrice.toFixed(2);
  document.getElementById('total-count').innerHTML = totalShirtCount;
  document.getElementById('setup-fee').innerHTML = '$'+setupFee.toFixed(2);
  document.getElementById('ink-fee').innerHTML = '$'+inkFee.toFixed(2);
  document.getElementById('sub-total').innerHTML = '$'+subTotal.toFixed(2);

  return unitPrice; // returns base unit price
}

// function called by onSubmit that removes blank options to reduce crowding
function removeBlankOptions(theForm) {
  var inputs = theForm.getElementsByTagName('input');
  for (var i=0; i<inputs.length; ++i) {
    if (inputs[i].value=="") {
      inputs[i].removeAttribute('name');
    }
  }
}




// Simple helper function to check for existence in an array and return location
function location_of(needle, haystack) {
  for (var i=0; i<haystack.length; i++) if (needle==haystack[i]) return i;
  return -1;
}

// Helper function that calculates the per-unit price of
// items based on the # of items and the RTML price variable,
// stored as an array in reunionPrice (global)
function calcPerUnitShirtPrice(count) {
  for (var i=(reunionPrice.length-1); i>=2; i-=2) {
    if ((count >= reunionPrice[i-1])&&(reunionPrice[i-1]>0)) {
      return reunionPrice[i] / reunionPrice[i-1];
    }
  }
  return reunionPrice[0];
}

// Function to calculate the unit price changes in the options fields. Pass
// in the relevent quantity field and it will traverse the DOM to find
// all other select menus with prices attached. It parses those value to
// get the unit price using regular expressions
function parseOptionUnitPrice(inputElem) {
  var td = inputElem;
  while ( !(td.parentNode.tagName=='TR' && td.className.indexOf('shirt-size-col')!=-1) ) {
    td = td.parentNode;
    if (!td.parentNode) {return 0;}
  }
  var tr = td.parentNode;

  var selects = tr.getElementsByTagName('select');
  var total = 0.00;
  for (var i=0; i<selects.length; ++i) {
    optValue = selects[i].value;

    var unitChange = extractCostFromString(optValue);
    if (unitChange) {
      total += unitChange;
    }
  }
  return total;
}

// Given a string, "New Purse (+$1.50)", return 1.50, otherwise returns false
function extractCostFromString(val) {
  var myMatch = val.match(/\( *\+ *\$?[\d.]+\)/);
  if (!myMatch) return false;
  var cost = parseFloat(myMatch[0].replace(/\( *\+ *\$?([\d.]+)\)/, "$1"));
  return cost;
}

// Modifies all SELECT tags in the table to omit their price. This is necessary
// because otherwise we'd have to pay an extra $1.20 or whatever the unit cost is
function removePricesFromSelects() {
  var rTable = document.getElementById('reunion-order-table');
  var selects = rTable.getElementsByTagName('select');
  var oldValue, newValue;
  for (var i=0; i<selects.length; ++i) {
    oldValue = selects[i].value;
    newValue = oldValue.replace(/\( *\+ *\$?([\d.]+)\)/g, "");
    // alert(oldValue+' ==> '+newValue);
    if (oldValue != newValue) {
      selects[i].style.visibility = 'hidden';
      selects[i].options.length = 0;
      selects[i].options[0] = new Option(newValue, newValue, true, true);
    }
  }
}

// Removes the prices on the inputs for size.
function removePricesFromInputs() {
  var rTable = document.getElementById('reunion-order-table');
  var inputs = rTable.getElementsByTagName('input');
  var oldName, newName

  for (var i=0; i<inputs.length; ++i) {
    oldName = inputs[i].name;
    if (oldName=="") continue;
    newName = oldName.replace(/\( *\+ *\$?([\d.]+)\)/g, "");
    if (newName != oldName) {
      inputs[i].name = newName; // possibly problems in IE
    }
  }
}

function removeYouth(elem) {
    var thisTR = elem.parentNode.parentNode;
    var youthInputs = thisTR.getElementsByTagName('input');
    for (var i=0; i<youthInputs.length; ++i) {
	youthInputs[i].value="";
    }
    thisTR.style.display="none";
    do {
	thisTR = thisTR.previousSibling;
    } while (thisTR.tagName!="TR");
    thisTR.style.display="none";

    // Finally, re-show the "add youth" link
    var parentTable = thisTR.parentNode;
    while (parentTable.tagName!="TABLE") parentTable = parentTable.parentNode;
    var addLink = parentTable.nextSibling;
    while (addLink.tagName!="DIV") addLink = addLink.nextSibling;
    addLink = addLink.getElementsByTagName('a')[0];
    addLink.style.display="";

    updateOrderSummary();
}


function removeRow(elem) {
    var thisTR = elem.parentNode;
    while (thisTR.tagName!="TR") thisTR=thisTR.parentNode;
    thisTR.parentNode.removeChild(thisTR);

    updateOrderSummary();
}


// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
// Execute some stuff on page load
parseHolidays();
insertOrderDates();
loadConfigInCookie();
initializeHiddenValues();
requireMinimumOrderOnSubmit();



