//
// Contains validation routines for dates and times.
//


//function to verify dates are within bounds of 
//other dates.
//
// p_start <= start < end <= p_end
//
//@param start 
//@param end 
//@param p_start - parent start date or lower bound
//@param p_end - parent end date or upper bound
//
//@return string representing error or null if ok
function checkDates(start, end, p_start, p_end){
  var retv = null;
  if ((start == "") || (end == "") || (p_start == "") || (p_end == "")){
    return retv;
  }
  if (compDate(start, p_start) < 0){
    retv = "Estimated Start Date is less than parent Estimated Start Date.";
  }
  else if (compDate(start, p_end) > 0){
    retv = "Estimated Start Date is greater than parent Estimated End Date.";
  }
  else if (compDate(end, p_start) <= 0){
    retv = "Estimated End Date is less than or equal to parent Estimated Start Date.";
  }
  else if (compDate(end, p_end) > 0){
    retv = "Estimated End Date is greater than parent Estimated End Date.";
  }
  else if (compDate(start, end) >= 0){
    retv = "Estimated Start Date is greater than or equal to Estimated End Date."; 
  }
  return retv;
}

  // Compares two dates to see if the first date is larger (1), smaller (-1), and equal (0) 
  // to the second date. This will assume that both dates are valid (though it will return a 
  // -2 if either date is not valid).
  //
  // @param firstDate the date (as a string in the format: mm/dd/yyyy) to compare against the second date.
  // @param secondDate the date (as a string in the format: mm/dd/yyyy) to compare against the first date.
  //
  // @return 1 if the first is larger than the second, -1 if the first is smaller than
  // the second, and 0 if they are equal. It will return -2 if either date is not valid.
  function compDate(firstDate, secondDate)
  {
    var firstAsObj = validateDate(firstDate, false);
    var secondAsObj = validateDate(secondDate, false);
    var result = -2; // -2 = One of the dates is invalid.
    if (firstAsObj != null && secondAsObj != null)
    {
      var firstAsNum = firstAsObj.getTime();
      var secondAsNum = secondAsObj.getTime();
      
      if (firstAsNum > secondAsNum)
      {
        result = 1;
      }
      else if (firstAsNum < secondAsNum)
      {
        result = -1;
      }
      else
      {
        result = 0;
      }
    }
    return result;
  }

  // Validates if the two dates are in order; that is, the end date
  // follows or is equal to the start date.
  //
  // @param startDate the starting date (as a string in the format: mm/dd/yyyy).
  // @param endDate the ending date (as a string in the format: mm/dd/yyyy).
  // @return null if the dates are in order, otherwise a message stating that
  //   they are out of order.  NOTE: *If one or more of the dates are invalid,
  //   then the dates are considered in order*.
  function isInDateOrder(startDate,endDate) {
    var result = compDate(startDate,endDate);
    if (result==-1 || result==0) return null;
    if (result==-2) return null;
    return "Start date comes after end date.";
  }
  
  // Validates if the field contains a valid date (of the format MM/dd/yyyy).
  // If it is a null value or empty string, it is considered valid.
  //
  // @param value the value to be considered as a date.
  //
  // @return null if it is a date, otherwise an error message describing the problem.
  function isDate(value)
  {
    return validateDate(value, true);
  }

  
  // Validates if the field contains a valid date (of the format MM/dd/yyyy).
  // If it is a null value or empty string, it is considered valid.
  //
  // @param value the value to be considered as a date.
  // @param returnMsgOnly if true, it will return the error message (if invalid) or
  //   null if valid. Otherwise, it will return the date if valid or null if invalid.
  //
  // @return depending on the returnMsgOnly parameter (see it for possibilities).
  function validateDate(value, returnMsgOnly)
  {
    var result = null;
    var assignedDate = false;
    if (value != null && trim(value) != "")
    {
      var pos = value.indexOf("/");
      if (pos > -1)
      {
        var month = value.substring(0, pos);
        if (month != null && month > 0 && month < 13)
        {
          var lastpos = pos++ + 1;
          pos = value.indexOf("/", pos);
          if (pos > -1)
          {
            var day = value.substring(lastpos, pos);
            if (day != null && day > 0 && day < 32)
            {
              if (pos+1 < value.length)
              {
                var year = value.substring(pos+1);
                if (year != null && year.length == 4)
                {
                  if (year > 0 && year < 10000)
                  {
                    var verifyDate = new Date();
                    verifyDate.setDate(1); // Every month has one day, so make sure that the
                                           // day will be valid for any month specified in any year.
                    verifyDate.setYear(year);
                    verifyDate.setMonth(month-1); // 0=Jan, 1=Feb, etc...
                    verifyDate.setDate(day);
                    verifyDate.setHours(0, 0, 0, 0); // Set the time to midnight.
                    
                    // The date object will roll into the next month if the
                    // number of days exceeds that allowed in the month. So,
                    // if the month is not the same, it has rolled into the next
                    // month. Have to add one back on to the month to off set 
                    // subtracting one above.
                    if (verifyDate.getMonth()+1 != month)
                    {
                      result = "The number of days selected for the month in the year specified is not valid.";
                    }
                    else if (!returnMsgOnly)
                    {
                      result = verifyDate;
                      assignedDate = true;
                    }
                  }
                  else
                  {
                    result = "The year is either negative or greater than 10,000.";
                  }
                }
                else if (year.length != 4)
                {
                  result = "Date is not of the format MM/DD/YYYY (the year is not four digits).";
                }

              } 
              else
              {
                result = "Date is not of the format MM/DD/YYYY (the year is missing).";
              }
            }
            else
            {
              result = "The day is not between 1 and 31 or does not exist.";
            }
          }
          else
          {
            result = "Date is not of the format MM/DD/YYYY (only one slash is present).";
          }
        }
        else
        {
          result = "The month is not between 1 and 12 or does not exist.";
        }
      }      
      else
      {
        result = "Date is not of the format MM/DD/YYYY (slashes are not present).";
      }
    }
    
    // If it is not supposed to return the message only (i.e. it should return the date)
    // and the date was not assigned, set the result to null (as it currently has an error
    // message in it).
    if (!returnMsgOnly && !assignedDate)
    {
      result = null;
    }
    return result;
  }

  // Validates if the field contains a valid time (of the format 24HH:MI).
  // If it is a null value or empty string, it is considered valid.
  //
  // @param value the value to be considered as a time.
  //
  // @return null if it is a time, otherwise an error message describing the problem.
  function isTime(value)
  {
    var result = null;
    if (value != null && trim(value) != "")
    {
      var pos = value.indexOf(":");
      if (pos > -1)
      {
        var hour = value.substring(0, pos);
        if (hour != null && hour.length > 0 && hour > -1 && hour < 24)
        {
          var minute = value.substring(pos+1);
          if (minute != null && minute.length > 0 && minute > -1 && minute < 60)
          {
            result = null;
          }
          else
          {
            result = "The minute was not specified or is not between 0 and 59.";
          }         
        }        
        else
        {
          result = "The hour was not specifed or is not between 0 and 23.";
        }
      }
      else
      {
        result = "Time is not of the format HH:MI (missing the colon).";
      }
    }

    return result;
  }

  // Validates if the field contains a valid date and time (of the format MM/dd/yyyy 24HH:MI).
  // If it is a null value or empty string, it is considered valid.
  //
  // @param value the value to be considered as a date and time.
  //
  // @return null if it is a date and time, otherwise an error message.
  function isDateTime(value)
  {
    var result = null;
    if (value != null && trim(value) != "")
    {
      var pos = value.indexOf(" ");
      if (pos > -1)
      {
        var date = value.substring(0, pos);
        if (pos+1 < value.length)
        {
          var time = value.substring(pos+1);
          var dateResult = isDate(date);
          var timeResult = isTime(time);
          if (dateResult != null)
          {   
            result = dateResult;
          }
          if (timeResult != null)
          {
            if (result != null)
            {
              result = " " + timeResult;
            }
            else
            {
              result = timeResult;
            }
          }
        }
      }
      else
      {
        result = "DateTime is not of the correct format (MM/DD/YYYY HH:MI).";
      }
    }

    return result;
  }


