CmdUtils.CreateCommand({
  name: "time",
  takes: {location: noun_arb_text},
  author: { name: "Alec Thomas", email: "alec@swapoff.org"},
  license: "BSD",
  description: "Display the current time, optionally at a specified location.",
  help: "Display the time at a specified location, defaulting to the current. If editing, insert the time.",

  preview: function (pblock, location) {
    var time = new Date();

    /* TODO: Use http://www.hostip.info/use.html to get our current location. */
    if (!pblock.innerHTML)
      pblock.innerHTML = this.description;

    location = location.text.toLowerCase();
    if (!location.length)
      location = 'here';
    if (location.length > 1) {
      if (this._cache[location] === undefined) {
        var have_request = this._request;

        this._request = {location: location, time: time, pblock: pblock};

        if (!have_request) {
        var cmd = this;

          Utils.setTimeout(function() {cmd._handleTimeout();}, 500);
        }
      } else {
        // CmdUtils.log('Cache hit for ' + location);
        pblock.innerHTML = this._cache[location];
        this._request = null;
      }
    } else {
      this._request = null;
    }
  },

  // Cache of accesses
  _cache: new Array(),

  _request: null,

  _handleTimeout: function() {
    var now = new Date();
    if (now - this._request.time > 300) {
      var geo = this._lookupGeo(this._request.location);
      this._request.location = geo.location;
      var html;

      if (this._cache[geo.coords]) {
        // CmdUtils.log('GEO cache hit for ' + this._request.location);
        html = this._cache[geo.coords];
      } else {      
        var time = this._lookupTime(geo);
        html = this._renderTime(geo.country_code, time);
        this._cache[geo.coords] = html;
      }
      this._request.pblock.innerHTML = html;
      this._cache[this._request.location] = html;
      this._request = null;
    } else {
    var cmd = this;

      Utils.setTimeout(function() {cmd._handleTimeout();}, 500);
    }
  },

  _formatTime: function (time) {
    var offset = time.getTimezoneOffset() / 60 + '00';

    if (offset.slice(0, 1) == '-' && offset.length == 4)
      offset = '-0' + offset.slice(1);
    
    return time.getFullYear() + '-' + time.getMonth() + 1 + '-' + time.getDate()
           + ' ' + time.getHours() + ':' + time.getMinutes() + ':' + time.getSeconds()
           + ' ' + offset;
  },

  _lookupGeo: function (location) {
    if (location == 'here') {
    var geo = CmdUtils.getGeoLocation();

      location = geo.city + ', ' + geo.country;
    }

    var response = {location: location};

    jQuery.ajax({
      url: 'http://maps.google.com/maps/geo?q=' + location,
      dataType: 'json',
      async: false,
      success: function (geo) {
        if (geo.Status.code == 200) {
          placemark = geo.Placemark[0];
          response.country_code = placemark.AddressDetails.Country.CountryNameCode.toLowerCase();
          response.coords = placemark.Point.coordinates.splice(0, 2).reverse();
        }
      },
    });
    return response;
  },

  _lookupTime: function (geo) {
    var response = null;

    jQuery.ajax({
      url: 'http://www.earthtools.org/timezone/' + geo.coords.join('/'),
      dataType: 'xml',
      async: false,
      success: function (tzinfo) {
        response = jQuery('isotime:first', tzinfo).text();
      },
    });
    return response;
  },

  _renderTime: function (country_code, time) {
    return '<div style="height: 54px"><a href="http://www.hostip.info"><img style="float: left; border: none; vertical-align: middle; margin-right: 8px;" src="http://api.hostip.info/images/flags/' + country_code + '.gif"/></a> <strong>' + placemark.address + '</strong><br/>' + time + '</div>';
  },
});
