// Copyright 2009 Google Inc. All Rights Reserved.

/**
 * @fileoverview Description of this file.
 * @author erichiggins@google.com (Eric Higgins)
 */

var goog = goog || {};

goog.ui = goog.ui || {};
goog.feeds = goog.feeds || {};
goog.vars = goog.vars || {};
goog.vars.feeds = goog.vars.feeds || {};
goog.vars.counter = goog.vars.counter || {};

goog.feeds.Spreadsheets = function(url) {
  if (url) {
    this.feedUri = url;
    this.init();
  }
};

goog.feeds.Spreadsheets.prototype =
{
  feedUri: '',
  feed: null,
  entries: [],
  result: null,
  error: null,
  params: {
    'alt': 'rss',
    'start-index': 1,
    'max-results': 100,
    'orderby': '',
    'reverse': 'false',
    'q': ''
  },
  cleanExpr: {
    'whitespace': /[\n\r\t\f\v\0]/g,
    'escapeDblQuote': /\u0022/g,
    'escapeValue': /, (\w+): /g,
    'escapeKey': /^(\w+): /g
  },

  init: function() {
    this.feed = new google.feeds.Feed(this.getUrl());
    this.feed.setNumEntries(this.params['max-results']);
  },

  getUrl: function() {
    var params = [];
    var url = this.feedUri + '?';

    for (var param in this.params) {
      params.push(param + '=' + escape(this.params[param]));
    }

    return url + params.join('&');
  },

  clean: function(content) {
    content = content.
        replace(this.cleanExpr.whitespace, '').
        replace(this.cleanExpr.escapeDblQuote, '\\"').
        replace(this.cleanExpr.escapeValue, '", "$1": "').
        replace(this.cleanExpr.escapeKey, '$1": "');
    return this.evalJSON(content);
  },

  evalJSON: function(content) {
    return eval('({"' + content + '"})');
  },

  load: function(result) {
    if (!result.error) {
      this.error = null;
      this.entries = [];
      for (var i = 0, len = result.feed.entries.length; i < len; i += 1) {
        var entry = result.feed.entries[i];
        this.entries[i] = this.clean(entry.content);
      }
    } else {
      this.error = result.error;
    }
  }
};

var cadie = function() {
  var init = function() {
    goog.vars.form = document.getElementById('cadie-form');
    var maps = {
      'javascript': '/od6/',
      'php': '/od8/',
      'python': '/od7/',
      'java': '/od4/',
      'c': '/od5/'
    };
    var languages = goog.vars.form.elements['language'].options;
    var url = 'http://spreadsheets.google.com/feeds/list/' +
        'py7xyB-w6v8IDNWEywmxKJA';

    for (var i = 0, len = languages.length; i < len; i +=1) {
      var lang = languages[i].value;
      goog.vars.counter[lang] = 0;
      goog.vars.feeds[lang] = new goog.feeds.
          Spreadsheets(url + maps[lang] + 'public/basic');
    }
    goog.vars.response = document.getElementById('cadie-response');
    goog.vars.cadie = document.getElementById('cadie');
    var submitHandler = function() {
      cadie.ask(this.elements['language'].options[this.elements['language'].
          selectedIndex].value, this.elements['q'].value);
      return false;
    };

    goog.vars.form.onsubmit = submitHandler;
    goog.vars.cadie.onclick = cadieHandler;
  };

  var cadieHandler = function() {
    var revert = function() {
      goog.vars.cadie.src = 'images/panda_128.png';
    };
    goog.vars.cadie.src = 'images/panda_angry_128.png';
    setTimeout(revert, 1500);
  };

  var load = function(result, lang) {
    goog.vars.feeds[lang].load(result);
    cadie.speak(lang);
  };

  var speak = function(lang) {
    var len = goog.vars.feeds[lang].entries.length;
    var num = goog.vars.counter[lang];
    if (goog.vars.counter[lang] < len - 1) {
      goog.vars.counter[lang] += 1;
    }
    var response = goog.vars.feeds[lang].entries[num].messages;

    if (typeof response === 'undefined') {
      response = goog.vars.feeds[lang].entries[len].messages;
    }
    goog.vars.response.innerHTML = response;
  };

  var ask = function(lang, query) {
    if (!query.length) {
      var response = 'I\'m not a mind reader...please type in a request.';
      goog.vars.response.innerHTML = response;
      return;
    }
    if (!goog.vars.feeds[lang].entries.length) {
      goog.vars.feeds[lang].init();
      goog.vars.feeds[lang].feed.load(function(result) {
        cadie.load(result, lang);
      });
    } else {
      cadie.speak(lang);
    }
  };

  return {
    'init': init,
    'ask': ask,
    'speak': speak,
    'load': load
  };
}();
