/*
 * extensions.js
 *
 */
// return the last member of an array
// e.g. [1,2,3].last() => 3
Array.prototype.last = function() {
  return this[this.length-1];
}

// compare the values of two arrays
// e.g. [1,2,3].compare([1,2,3]) => true
// also [1,2,3].compare([1,3,2]) => false
Array.prototype.compare = function(testArr) {
  if (this.length != testArr.length) return false;
  for (var i = 0; i < testArr.length; i++) {
    if (this[i].compare) {
      if (!this[i].compare(testArr[i])) return false;
    }
    if (this[i] !== testArr[i]) return false;
  }
  return true;
}

// capitalize string
// e.g. "hey You!" => "Hey you!"
String.prototype.capitalize = function() {
  return this.charAt(0).toUpperCase() + this.substring(1).toLowerCase();
}

// humanize string
// e.g. "password_confirmation" => "Password confirmation"
String.prototype.humanize = function() {
  return this.replace(/_/g, ' ').capitalize();
}

// tableize string
// e.g. "Password confirmation" => "password_confirmation"
String.prototype.tableize = function() {
  return this.toLowerCase().replace(/[\s]+/g, "_");
}

// used by Template.evaluate()
// e.g. "Some text\n".inspect() => "Some text\n"
String.prototype.inspect = function() {
  var special_chars = {
    '\b': '\\b',
    '\t': '\\t',
    '\n': '\\n',
    '\f': '\\f',
    '\r': '\\r',
    '\\': '\\\\'
  };

  var escape_text = function(match) {
    var character = special_chars[match];
    return character ? character : '\\u00' + match.charCodeAt().toPaddedString(2, 16);
  }

  return this.replace(/[\x00-\x1f\\]/g, escape_text);
}

String.prototype.strip_html = function() {
  var regexp = /<("[^"]*"|'[^']*'|[^'">])*>/gi;
  return this.replace(regexp, "");
}

// Implementation of the strftime method
// e.g. date = new Date(); date.strftime("%H:%M");
Date.prototype.strftime = function(format) {
  var MONTHNAMES = ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"];
  var DAYNAMES = ["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"];
  var ABBR_MONTHNAMES = ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"];
  var ABBR_DAYNAMES = ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"];
  var date = this;

  /*
  %a - The abbreviated weekday name (``Sun'')
  %A - The  full  weekday  name (``Sunday'')
  %b - The abbreviated month name (``Jan'')
  %B - The  full  month  name (``January'')
  TODO %c - The preferred local date and time representation
  %d - Day of the month (01..31)
  %H - Hour of the day, 24-hour clock (00..23)
  %I - Hour of the day, 12-hour clock (01..12)
  TODO %j - Day of the year (001..366)
  %m - Month of the year (01..12)
  %M - Minute of the hour (00..59)
  %p - Meridian indicator (``AM''  or  ``PM'')
  %S - Second of the minute (00..60)
  TODO %U - Week  number  of the current year, starting with the first Sunday as the first day of the first week (00..53)
  TODO %W - Week  number  of the current year, starting with the first Monday as the first day of the first week (00..53)
  %w - Day of the week (Sunday is 0, 0..6)
  TODO %x - Preferred representation for the date alone, no time
  TODO %X - Preferred representation for the time alone, no date
  %y - Year without a century (00..99)
  %Y - Year with century
  TODO %Z - Time zone name
  %% - Literal ``%'' character
  */

  var a = function() { return ABBR_DAYNAMES[date.getDay()]; };
  var A = function() { return DAYNAMES[date.getDay()]; };
  var b = function() { return ABBR_MONTHNAMES[date.getMonth()]; };
  var B = function() { return MONTHNAMES[date.getMonth()]; };
  // TODO %c - The preferred local date and time representation
  var d = function() { return date.getDate(); };
  var H = function() { return add_zero_if_necessary(date.getHours()); };
  var I = function() { return add_zero_if_necessary(date.getHours() > 0 && date.getHours() < 13 ? date.getHours() : Math.abs(date.getHours()-12)); };
  // TODO %j - Day of the year (001..366)
  var m = function() { return date.getMonth()+1; };
  var M = function() { return add_zero_if_necessary(date.getMinutes()); };
  var p = function() { return (date.getHours() > 11) ? "PM" : "AM"; };
  var S = function() { return add_zero_if_necessary(date.getSeconds()); };
  // TODO %U - Week  number  of the current year, starting with the first Sunday as the first day of the first week (00..53)
  // TODO %W - Week  number  of the current year, starting with the first Monday as the first day of the first week (00..53)
  var w = function() { return date.getDay(); };
  // TODO %x - Preferred representation for the date alone, no time
  // TODO %X - Preferred representation for the time alone, no date
  var y = function() { return date.getYear().toString().substr(1); };
  var Y = function() { return date.getFullYear(); };
  // TODO %Z - Time zone name

  var add_zero_if_necessary = function(number) { return number < 10 ? "0"+number : number; };

  var replace_value = function(str, match) {
    try { convertion = match == '%' ? match : eval(match+"()"); }
    catch(e) { convertion = null; }
    return convertion ? convertion : str;
  }

  return format.replace(/%([a-zA-Z%])/g, replace_value);
}

Date.from_iso = function(isoDate) {
  var matches = /^(\d{4})-(\d{2})-(\d{2})T(\d{2}):(\d{2}):(\d{2})([+|-]?\d{2}:\d{2})$/.exec(isoDate);
  var date = new Date(matches[1], matches[2]-1, matches[3], matches[4], matches[5], matches[6]);
  return date;
}
