/**
 * Support functions for the BAS meldingen site
 */

/**
 * Alert an error message from an exception thrown by the server
 */
function alertException(exc)
{
   alert(exc.message);
}

/**
 * Add a trim function to the String class that removes whitespace from
 * beginning and end of the string
 */
String.prototype.trim = function() {
   return this.replace(/^\s+|\s+$/g, '');
};

/**
 * Check if a given value is in an array.
 * FIXME: trying to add this directly to the Array class results in an error
 * in one of the external javascript files used.
 */
function arrayContains(array, value)
{
   for (var i = 0; i < array.length; i++)
   {
      if (array[i] === value)
      {
         return true;
      }
   }
   return false;
}

/**
 * Build a date string in YYYYMMDD format from separate fields
 *
 * @param string day   The day of the date
 * @param string month The month of the date
 * @param string year  The year of the date
 * @return string with the full date
 */
function buildDateString(day, month, year)
{
   if (year < 70)
   {
      year = parseInt(year, 10) + 2000;
   }
   else if (year < 1900)
   {
      year = parseInt(year, 10) + 1900;
   }

   if (!month)
   {
      month = '00';
   }
   else if (month.length < 2)
   {
      month = '0' + month;
   }

   if (!day)
   {
      day = '00';
   }
   else if (day.length < 2)
   {
      day = '0' + day;
   }

   return year.toString() + month + day;
}

/**
 * Convert a Date object to a string in YYYY-MM-DD or YYYY-MM-DD HH:MI:SS
 *    format
 * @param Date date    The date to convert, or one of the strings 'now',
 *    'today', or 'tomorrow'.
 * @param bool addTime If true, add the time of the date to the string
 * @return string with the date in the requested format
 */
function dateToString(date, addTime)
{
   if (date === 'now' || date === 'today')
   {
      date = new Date();
   }
   else if (date === 'tomorrow')
   {
      date = new Date();
      date.setDate(date.getDate()+1);
   }

   var y = date.getFullYear();
   var m = date.getMonth() + 1;
   var d = date.getDate();

   if (m < 10)
   {
      m = '0' + m.toString();
   }
   if (d < 10)
   {
      d = '0' + d.toString();
   }
   var res = y.toString() + '-' + m + '-' + d;

   if (addTime)
   {
      var hour = date.getHours();
      var mins = date.getMinutes();
      var secs = date.getSeconds();

      if (hour < 10)
      {
         hour = '0' + hour.toString();
      }
      if (mins < 10)
      {
         mins = '0' + mins.toString();
      }
      if (secs < 10)
      {
         secs = '0' + secs.toString();
      }

      res += ' ' + hour + ':' + mins + ':' + secs;
   }

   return res;
}

/**
 * Convert a date string in YYYY-MM-DD or YYYY-MM-DD HH:MM:SS format
 * (as returned by MySQL) to the Dutch convention of DD-MM-YYYY. If the
 * (optional) parameter strip_sec is set and true, the date is assumed
 * to be in YYYY-MM-DD HH:MM:SS, and is converted to DD-MM-YYYY HH:MM
 * format. In other case, only the date part is converted.
 * @param string date The database date string to convert
 * @return string with converted date
 */
function formatDBDate(date, strip_sec)
{
   if (strip_sec)
   {
      return date.replace(/(\d{4})-(\d\d)-(\d\d) (\d\d):(\d\d):\d\d/,
         '$3-$2-$1&nbsp;$4:$5');
   }
   else
   {
      return date.replace(/(\d{4})-(\d\d)-(\d\d)/, '$3-$2-$1');
   }
}

/**
 * Check two date strings, returning true if the first date is smaller than
 * the second and false otherwise. The dates should be in YYYY-MM-DD or
 * YYYY-MM-DD HH:MI:SS format, or one of 'now', 'today' or 'tomorrow'
 * @param d1 The first date to compare
 * @param d2 The second date to compare
 * @return bool true if the d1 corresponds to an earlier date than d2,
 *   false otherwise
 */
function dateBefore(d1, d2, checkTime)
{
   var special = ['now', 'today', 'tomorrow'];

   if (!checkTime)
   {
      checkTime = false;
   }

   if (arrayContains(special, d1) || d1 instanceof Date)
   {
      d1 = dateToString(d1, checkTime);
   }
   if (arrayContains(special, d2) || d2 instanceof Date)
   {
      d2 = dateToString(d2, checkTime);
   }

   if (!checkTime)
   {
      d1 = d1.substr(0, 10);
      d2 = d2.substr(0, 10);
   }

   return d1 < d2;
}

/**
 * Convert a period identifier to a time string. Each period corresponds
 * to 1 15 minute interval, so 0 is 00:00-00:15, 1 is 00:15-00:30 etc.
 * @param int period The period identifier
 * @return string containing the interval start and end times
 */
function periodToTime(period)
{
   var minutes = period * 15;
   var h1 = Math.floor(minutes / 60);
   var m1 = minutes % 60;
   var h2 = h1;
   var m2 = m1+15;

   if (m2 >= 60)
   {
      h2++;
      m2 -= 60;
   }
   if (h1 < 10)
   {
      h1 = '0' + h1;
   }
   if (m1 < 10)
   {
      m1 = '0' + m1;
   }
   if (h2 < 10)
   {
      h2 = '0' + h2;
   }
   if (m2 < 10)
   {
      m2 = '0' + m2;
   }

   return h1+':'+m1 + ' - ' + h2+':'+m2;
}

/**
 * Upper case the first alpha character entered in a name field.
 * If more characters after the first alpha character are given,
 * do nothing, so that the possibility to enter names not starting with
 * a capital letter remains open. 
 * @param object field The input field in which the name is entered
 */
function upperCaseName(field)
{
   var str = field.value;
   var letter = /[A-Za-z\u00C0-\u027F]/;
   var pos = str.search(letter);
   if (pos == -1 || str.length > pos+1)
   {
      // No letter found, or there are characters after the first letter
      return;
   }
   str = str.substr(0, pos) + str.charAt(pos).toUpperCase()
      + str.substr(pos+1);
   field.value = str;
}

/**
 * Check if a provided surname looks valid, i.e. contains only letters,
 *    space, - or ', or the wild cards * and ?.
 *
 * @param string name The name to check
 * @return bool true if the name looks valid, false otherwise
 */
function isValidSurName(name)
{
   return (/^[A-Za-z\u00C0-\u027F \-\'*?]*$/).test(name);
}

/**
 * Format a (valid) phone number according to convention.
 *
 * @param string nr The phone number to format
 * @return string with the formatted number
 */
function formatPhoneNumber(nr)
{
   nr = nr.replace(/[^\d]/g, '');
   if (nr.substring(0, 2) == '06')
   {
      return nr.replace(/(..)(..)(..)(..)(..)/, '$1-$2 $3 $4 $5');
   }
   else if (/^0(1[035]|2[0346]|3[03568]|4[0356]|5[058]|7.)/.test (nr))
   {
      return nr.replace(/(...)(...)(..)(..)/, '($1) $2 $3 $4');
   }
   else
   {
      return nr.replace(/(....)(..)(..)(..)/, '($1) $2 $3 $4');
   }
}

/**
 * Check if a phone number is valid, where valid is defined as
 *    containing 10 digits and no alpha character.
 *
 * @param string nr The phone number to check
 * @return bool true if the number is valid, false otherwise
 */
function isValidPhoneNumber(nr)
{
   if (!/^[\x20-\x7f]*$/.test(nr) || /[A-Za-z]/.test(nr))
   {
      return false;
   }
   nr = nr.replace(/[^\d]/g, '');
   return nr.length == 10 && nr.charAt(0) == '0';
}

/**
 * Translate a sex enumeration value into the corrseponding (Dutch) label.
 * @param string sex The sex as stored in the database
 * @return string with the translated sex
 */
function translateSex(sex)
{
   if (sex == 'MALE')
   {
      return 'Man';
   }
   else if (sex == 'FEMALE')
   {
      return 'Vrouw';
   }
   else
   {
      return sex;
   }
}

/**
 * Convert a feedback preference enumeration value into the corresponding
 * (Dutch) label.
 * @param string the feedback preference as stored in the database
 * @return string with the translated preference value.
 */
function translateFeedbackPreference(pref)
{
   switch(pref)
   {
      case 'PHONE': return 'Telefoon';
      case 'EMAIL': return 'E-mail';
      case 'POST': return 'Papier';
      default: return pref;
   }
}

/**
 * Convert an array of role enumeration values into a comma separated string
 * of the corrsponding (Dutch) role names.
 * @param array roles The role enumeration values
 * @return string with translated role names
 */
function translateRoles(roles)
{
   var tr_roles = [];
   for (var i = 0; i < roles.length; i++)
   {
      switch(roles[i])
      {
         case 'CLIENT':
            tr_roles.push('Klant');
            break;
         case 'BAS':
            tr_roles.push('Bas');
            break;
         case 'AAS':
            tr_roles.push('Aas');
            break;
         case 'LVNL':
            tr_roles.push('Lvnl');
            break;
         case 'RIJK':
            tr_roles.push('Rijk');
            break;
         default:
            tr_roles.push(roles[i]);
      }
   }
   return tr_roles.join(',');
}

/**
 * Translate the value of a response quality label into readable Dutch
 * @param string quality The label to translate
 * @return string with the translation
 */
function translateResponseQuality(quality)
{
   switch (quality)
   {
   case 'OK':           return 'Voldoende';
   case 'INSUFFICIENT': return 'Onvoldoende';
   case 'RETURNED':     return 'Onvoldoende, retour';
   default:             return 'Onbekend';
   }
}


