// TODO: Add notes about where to send info and how much.

/**
 * Logic for First Weekend at Pinewoods Application. No data persistent data is
 * stored here.
 */
var Application = function () {

  /*
   *  The following will need to be changed each year
   */
  this.firstWeekendDate = { YEAR : 2009, MONTH : 9, DAY : 5 };
  this.applicationDeadline = { YEAR : 2009, MONTH : 7, DAY: 15 };
  this.balanceDeadline = { YEAR : 2009, MONTH : 8, DAY : 15 };
  
  // Fees for 2008 & 2009
  var feeInfo = {
    // Anyone under this age pays actual fee, not deposit.
    YOUNGEST_DEPOSIT_AGE : 4,
    DEPOSIT : 50,
    fees : [
      {minAge: 26, maxAge: 26, memberFee: 220, nonMemberFee: 240},
      {minAge: 16, maxAge: 25, memberFee: 180, nonMemberFee: 190},
      {minAge: 13, maxAge: 15, memberFee: 160, nonMemberFee: 170},
      {minAge:  7, maxAge: 12, memberFee:  130, nonMemberFee: 140},
      {minAge:  4, maxAge:  6, memberFee:  90, nonMemberFee:  100},
      {minAge:  2, maxAge:  3, memberFee:  50, nonMemberFee:  60},
      {minAge:  0, maxAge:  1, memberFee:  20, nonMemberFee:  30}
    ],

    /**
     * Look up fee informaton based on an age.
     *     * @param {Number} age
     *
     * @return object containing age range, member and non-member fees.
     * @type Object
     */
    getFees : function(age) {
      var i;
      var result = null;
      
      for (i = 0; i < feeInfo.fees.length && result === null; i++) {
        if (feeInfo.fees[i].minAge <= age && age <= feeInfo.fees[i].maxAge) {
          result = feeInfo.fees[i];
        }
      }
      return result;
    }
  };
  
  /*
   * Enumerations
   */
  this.Food = { OMNIVORE: "Omnivore", SPECIAL: "Special" };

  this.Age = { ADULT: 26 };

  // FOR DEBUGGING ONLY
  this.displayData = function() {
      alert(Object.toJSON(applicationData) + "\n\n" + Object.toJSON(savedApplicationData));
  };
  
  /**
   * Determine a camper's fee based on age and CDS membership status.
   * 
   * @param {Object} camper
   * 
   * @return {Number} fee owed by camper.
   */
  this.calculateFee = function(age, isMember) {
    var fee = 0;
    var feeEntry = null;
    var i = 0;
    if (-1 !== age) {
      feeEntry = feeInfo.getFees(age);
      if (isMember) {
        fee = feeEntry.memberFee;
      }
      else {
        fee = feeEntry.nonMemberFee;
      }
    }
    return fee;
  };
  
  /**
   * Calculate the deposit owed by a given camper.
   *
   * For younger campers it's the same as their fee. For older campers it's a
   * set value. Defined by the FeeInfo.DEPOSIT contant.
   * 
   * @param {Object} camper
   * 
   * @return amount of deposit owed by the camper.
   * @type Number
   */
  this.calculateDeposit = function(age, isMember) {
    var deposit = 0;
    if (age < feeInfo.YOUNGEST_DEPOSIT_AGE) {
      deposit = this.calculateFee(age, isMember);
    }
    else {
      deposit = feeInfo.DEPOSIT;
    }
    return deposit;
  };

  /**
   * Save the cookie for this application. The expiraton date is set for the
   * Sunday of First Weekend.
   */
  this.saveApplicationData = function() {
    delete savedApplicationData;
    savedApplicationData = application.cloneApplicationData(applicationData);
  };  

  /**
   * Deep clone of ApplicationData object.
   * 
   * @param source ApplicationData object.
   * 
   * @returns cloned ApplicationData object.
   */
  this.cloneApplicationData = function(source) {
      var target = new ApplicationData();
      var fieldName = "";
      for (fieldName in source) {
          if (fieldName === "campers") {
              for (var i = 0; i < source.campers.length; i++) {
                  target.campers[i] = new Camper();
                  for (camperField in source.campers[i]) {
                      target.campers[i][camperField] =
                          source.campers[i][camperField];
                  }
              }
          }
          else {
              target[fieldName] = source[fieldName];
          }
      }
      return target;
  }
  this.deleteChildren = function(id) {
      var node = $(id);
      var childNode;
      while (node.hasChildNodes()) {
          childNode = node.removeChild(node.firstChild);
          delete childNode;
      }
  };

  this.initialize = function() {
//    var applicationJson = cookieManager.get("LaborDayWeekendApplication");
    var camper;

    mainForm.initialize();
    camperForm.initialize();

    // TODO Remove
//    {
//        applicationData = new ApplicationData();
//        camper = {
//            firstName : "Michael",
//            lastName : "Resnick",
//            age : 18,
//            gender : "M",
//            member : true,
//            firstTime : false,
//            smoker : false,
//            food : application.Food.OMNIVORE,
//            foodNotes : "",
//            job : "Web Geek",
//            street : "15 Bellflower St.",
//            city : "Lexington",
//            state : "MA",
//            zip : "02421",
//            email : "mresnick@progress.com",
//            phone : "781-862-6681"
//        };
//        applicationData.campers[0] = camper;
//        applicationData.useEmail = true;
//        applicationData.housingNotes = "Together";
//        applicationData.monitorService = false;
//        applicationData.workshopOffer = "Rapper";
//        applicationData.instrumentOffer = "Voice";
//        applicationData.workshopRequest = "\"Waltz clog\"";
//        applicationData.dishwashing = true;
//        applicationData.travelingMonitor = true;
//        applicationData.arrival3_6 = true; 
//        applicationData.arrivalForDinner = false;
//        applicationData.arrivalAfterDinner = false;
//        applicationData.arrivalOther = false;
//        applicationData.otherArrivalTime = "";
//        applicationData.departBeforeDinner = "";
//        applicationData.offerRide = true;
//        applicationData.needRide = false;
//        applicationData.otherNotes = "misc";
//        savedApplicationData = application.cloneApplicationData(applicationData);
//    }
    if (null == savedApplicationData) {
      savedApplicationData = new ApplicationData();
      applicationData = application.cloneApplicationData(savedApplicationData);
      camper = new Camper();
      camper.age = this.Age.ADULT;
      camper.isContact = true;
      // TODO: If there's an attempt to casncel on the contact, they show up as camper 1 the next time, rather than as the contact.
      applicationData.campers[0] = camper;
      applicationData.currentCamperIndex = 0;
      $("camperForm").style.display = "";
      $("mainForm").style.display = "none";
      $("submitCancelButtons").style.display = "none";
      camperForm.load(camper, true);
//      $("firstName").focus();
    }
    else {
        applicationData =
            application.cloneApplicationData(savedApplicationData);
        mainForm.load();
        $("camperForm").style.display = "none";
        $("mainForm").style.display = "";
        $("submitCancelButtons").style.display = "";
    }
    $("confirmationForm").style.display="none";
    // TODO remove
//    application.finish();
  };

  this.addCamper = function() {
      var camper = new Camper();
      var camperList = applicationData.campers;
      applicationData.currentCamperIndex = camperList.length; 
      applicationData.campers[applicationData.currentCamperIndex] = camper;
      camperForm.load(camper, 0 === applicationData.currentCamperIndex);
      $("mainForm").style.display = "none";
      $("submitCancelButtons").style.display = "none";
      $("camperForm").style.display = "";
  };

  this.editCamper = function(index) {
      applicationData.currentCamperIndex = index;
      camperForm.load(applicationData.campers[index], 0 === index);
      $("mainForm").style.display = "none";
      $("submitCancelButtons").style.display = "none";
      $("camperForm").style.display = "";
  };
  
  this.deleteCamper = function(index) {
      delete applicationData.campers.splice(index, 1);
      application.saveApplicationData();
      mainForm.writeCamperTable();
  }
  
  this.cancelCamper = function() {
//      var applicationJson = cookieManager.get("LaborDayWeekendApplication");

//      applicationData = applicationJson.evalJSON();
      applicationData = application.cloneApplicationData(savedApplicationData);
      mainForm.load();
      $("camperForm").style.display = "none";
      $("submitCancelButtons").style.display = "";
      $("mainForm").style.display = "";
    };

    this.confirmationBack = function() {
      mainForm.load();
      $("confirmationForm").style.display = "none";
      $("submitCancelButtons").style.display = "";
      $("mainForm").style.display = "";
    };

    this.getCurrentCamper = function() {
    return applicationData.campers[applicationData.currentCamperIndex];
  };

  this.camperHasContactInfo = function(camper) {
      return camper.street.length !== 0 ||
       camper.city.length !== 0 ||
       camper.state.length !== 0 ||
       camper.zip.length !== 0 ||
       camper.phone.length !== 0 ||
       camper.email.length !== 0;
  };

  this.cancel = function() {
      delete applicationData;
      delete savedApplicationData;
      history.back();
  };
  
  this.escapeCsvString = function(value) {
      var retVal = "";
      if (0 !== value.length) {
          retVal = '"' + value.replace(/"/g, '""') + '"';
      }
      return retVal;
  };
  
  this.booleanCsvString = function(value) {
      return value ? '"Y"' : '';
  };
//  function serializeCamper(camper, isContact) {
//  };
  
  this.finish = function () {
      var a = $("depositTotal").firstChild.nodeValue;
      var b = a.substring(1);
      var c = parseInt(b);
      var depositTotal = parseInt($("depositTotal").firstChild.nodeValue.substring(1));
      var feeTotal = parseInt($("feeTotal").firstChild.nodeValue.substring(1));
      var balance = feeTotal - depositTotal;
      application.deleteChildren("confirmationDeposit");
      $("confirmationDeposit").appendChild(document.createTextNode($("depositTotal").firstChild.nodeValue));
//      $("confirmationDeposit").appendChild(document.createTextNode(depositTotal));
      application.deleteChildren("confirmationBalance");
      $("confirmationBalance").appendChild(document.createTextNode("$" + balance));
      application.deleteChildren("confirmationFee");
      $("confirmationFee").appendChild(document.createTextNode($("feeTotal").firstChild.nodeValue));
//      $("confirmationFee").appendChild(document.createTextNode(feeTotal));
      $("submitCancelButtons").style.display = "none";
      $("mainForm").style.display = "none";
      $("confirmationForm").style.display = "";
  };
  
  this.submit = function() {
      var retVal = mainForm.validateAndSaveForm();
      var contactString = savedApplicationData.campers[0].lastName;
      var header = ',"contact","first name","last name","age","gender",' +
          '"address","city","state","zip","phone","email","use email",' +
          '"member","first time","smoker","food","food notes","job pref",' +
          '"arrival","leave early","housing pref","trav","workshop offer",' +
          '"instrument","workshop req","scholarship req","ride","other",' +
          '"total fee","total deposit"';
      var csvString = header + "\n";
      var fieldList1 = ["gender", "street", "city", "state"];
      var fieldList2 = ["member", "firstTime", "smoker"];
      var fieldList3 = ["foodNotes", "job"];
      var isContact = true;
      var camper = null;
      var fieldName = null;
      var i;
      var j;
      var form = $("confirmationForm");
      var fromEmail = form.getInputs("hidden", "fromEmail")[0];
      var lastName = form.getInputs("hidden", "lastName")[0];
      var appData = form.getInputs("hidden", "applicationData")[0];
      var deposit = form.getInputs("hidden", "deposit")[0];
      var balance = form.getInputs("hidden", "balance")[0];
      var fee = form.getInputs("hidden", "fee")[0];
      var depositTotal = parseInt($("depositTotal").firstChild.nodeValue.substring(1));
      var feeTotal = parseInt($("feeTotal").firstChild.nodeValue.substring(1));
      var balanceTotal = feeTotal - depositTotal;
      
      if (retVal) {
          for (i = 0; i < savedApplicationData.campers.length; i++) {
              camper = savedApplicationData.campers[i];
              csvString += ',"' + contactString + (i + 1) + '"';
              csvString += ',' + application.escapeCsvString(camper.firstName);
              csvString += ',' + application.escapeCsvString(camper.lastName);
              csvString += ',"' + (camper.age === 18 ? 'A' : camper.age) + '"';
              for (j = 0; j < fieldList1.length; j++) {
                  fieldName = fieldList1[j];
                  csvString += ',' + application.escapeCsvString(camper[fieldName]);
              }
              csvString += ',';
              if (camper.zip.length !== 0) {
                  // The added apostrophe make Excel store this as a string.
                  csvString += "\"'" + camper.zip + '"';
              }
              csvString += ',' + application.escapeCsvString(camper.phone);
              csvString += ',' + application.escapeCsvString(camper.email);
              csvString += ',';
              if (isContact) {
                  csvString += application.booleanCsvString(savedApplicationData.useEmail)
              }
              for (j = 0; j < fieldList2.length; j++) {
                  fieldName = fieldList2[j];
                  csvString += ',' + application.booleanCsvString(camper[fieldName]);
              }
              csvString += ',"' + camper["food"].charAt(0) + '"';
              for (j = 0; j < fieldList3.length; j++) {
                  fieldName = fieldList3[j];
                  csvString += ',' + application.escapeCsvString(camper[fieldName]);
              }
              if (isContact) {
                  if (savedApplicationData.arrival3_6) {
                      csvString += ',"3 to 6"';
                  }
                  else if (savedApplicationData.arrivalForDinner) {
                      csvString += ',"dinner"';
                  }
                  else if (savedApplicationData.arrivalAfterDinner) {
                      csvString += ',"after dinner"';
                  }
                  else {
                      csvString += ',' + application.escapeCsvString(savedApplicationData.otherArrivalTime);
                  }
                  csvString += ',' + application.booleanCsvString(savedApplicationData.departBeforeDinner);
                  csvString += "," + application.escapeCsvString(savedApplicationData.housingNotes);
                  csvString += "," + application.booleanCsvString(savedApplicationData.monitorService);

                 csvString += ',' + application.escapeCsvString(savedApplicationData.workshopOffer);
                  csvString += ',' + application.escapeCsvString(savedApplicationData.instrumentOffer);
                  csvString += ',' + application.escapeCsvString(savedApplicationData.workshopRequest);
                  
                  csvString += ',';
                  if (savedApplicationData.dishwashing || savedApplicationData.travelingMonitor) {
                      csvString += '"' +
                      (savedApplicationData.dishwashing ? 'dw' : '') +
                      ((savedApplicationData.dishwashing && savedApplicationData.travelingMonitor) ? ' ' : '') +
                      (savedApplicationData.travelingMonitor ? 'tm' : '') +
                      '"';
                  }
                  csvString += ',';
                  if (savedApplicationData.offerRide) {
                      csvString += '"offer"';
                  }
                  else if (savedApplicationData.needRide) {
                      csvString += '"need"';
                  }
                  
                  csvString += ',' + application.escapeCsvString(savedApplicationData.otherNotes);
                  csvString += ',' + feeTotal;
                  csvString += ',' + depositTotal;
              }
              
              csvString += "\n";
              isContact = false;
          }
          fromEmail.value = applicationData.campers[0].email;
          lastName.value = applicationData.campers[0].lastName;
  
          deposit.value = depositTotal;
          balance.value = balanceTotal;
          fee.value = feeTotal;
          appData.value = csvString;
//          application.deleteChildren("results");
//          $("results").appendChild(document.createTextNode(csvString));
      }
      return retVal;
  };
  
  
};

var application = new Application();
