/*!
  * Reqwest! A x-browser general purpose XHR connection manager
  * copyright Dustin Diaz 2011
  * https://github.com/ded/reqwest
  * license MIT
  */
!function (window) {

  // require valentine module
  var v = window.v;
  if (!v && (typeof require !== 'undefined')) {
    v = require('valentine');
  }

  var twoHundo = /^20\d$/,
      doc = document,
      byTag = 'getElementsByTagName',
      head = doc[byTag]('head')[0],
      xhr = ('XMLHttpRequest' in window) ?
        function () {
          return new XMLHttpRequest();
        } :
        function () {
          return new ActiveXObject('Microsoft.XMLHTTP');
        };

  var uniqid = 0;
  // data stored by the most recent JSONP callback
  var lastValue;

  function readyState(o, success, error) {
    return function () {
      if (o && o.readyState == 4) {
        if (twoHundo.test(o.status)) {
          success(o);
        } else {
          error(o);
        }
      }
    };
  }

  function setHeaders(http, o) {
    var headers = o.headers || {};
    headers.Accept = headers.Accept || 'text/javascript, text/html, application/xml, text/xml, */*';

    // breaks cross-origin requests with legacy browsers
    if (!o.crossOrigin) {
      headers['X-Requested-With'] = headers['X-Requested-With'] || 'XMLHttpRequest';
    }

    if (o.data) {
      headers['Content-type'] = headers['Content-type'] || 'application/x-www-form-urlencoded';
      for (var h in headers) {
        headers.hasOwnProperty(h) && http.setRequestHeader(h, headers[h], false);
      }
    }
  }

  function getCallbackName(o) {
    var callbackVar = o.jsonpCallback || "callback";
    if (o.url.slice(-(callbackVar.length + 2)) == (callbackVar + "=?")) {
      // Generate a guaranteed unique callback name
      var callbackName = "reqwest_" + uniqid++;

      // Replace the ? in the URL with the generated name
      o.url = o.url.substr(0, o.url.length - 1) + callbackName;
      return callbackName;
    } else {
      // Find the supplied callback name
      var regex = new RegExp(callbackVar + "=([\\w]+)");
      return o.url.match(regex)[1];
    }
  }

  // Store the data returned by the most recent callback
  function generalCallback(data) {
    lastValue = data;
  }

  function getRequest(o, fn, err) {
    if (o.type == 'jsonp') {
      var script = doc.createElement('script');

      // Add the global callback
      window[getCallbackName(o)] = generalCallback;

      // Setup our script element
      script.type = "text/javascript";
      script.src = o.url;
      script.async = true;

      var onload = function () {
        // Call the user callback with the last value stored
        // and clean up values and scripts.
        o.success && o.success(lastValue);
        lastValue = undefined;
        head.removeChild(script);
      };

      
      // onload for IE
      if (document.all) {
          script.onreadystatechange = function () {
            /^loaded|complete$/.test(script.readyState) && onload();
          };
      } else {
          script.onload = onload;
      }

      // Add the script to the DOM head
      head.appendChild(script);
    } else {
      var http = xhr();
      http.open(o.method || 'GET', typeof o == 'string' ? o : o.url, true);
      setHeaders(http, o);
      http.onreadystatechange = readyState(http, fn, err);
      o.before && o.before(http);
      http.send(o.data || null);
      return http;
    }
  }

  function Reqwest(o, fn) {
    this.o = o;
    this.fn = fn;
    init.apply(this, arguments);
  }

  function setType(url) {
    if (/\.json$/.test(url)) {
      return 'json';
    }
    if (/\.jsonp$/.test(url)) {
      return 'jsonp';
    }
    if (/\.js$/.test(url)) {
      return 'js';
    }
    if (/\.html?$/.test(url)) {
      return 'html';
    }
    if (/\.xml$/.test(url)) {
      return 'xml';
    }
    return 'js';
  }

  function init(o, fn) {
    this.url = typeof o == 'string' ? o : o.url;
    this.timeout = null;
    var type = o.type || setType(this.url), self = this;
    fn = fn || function () {};

    if (o.timeout) {
      this.timeout = setTimeout(function () {
        self.abort();
        error();
      }, o.timeout);
    }

    function complete(resp) {
      o.complete && o.complete(resp);
    }

    function success(resp) {
      o.timeout && clearTimeout(self.timeout) && (self.timeout = null);
      var r = resp.responseText;

      if (r) {
        switch (type) {
        case 'json':
          resp = window.JSON ? window.JSON.parse(r) : eval('(' + r + ')');
          break;
        case 'js':
          resp = eval(r);
          break;
        case 'html':
          resp = r;
          break;
        // default is the response from server
        }
      }

      fn(resp);
      o.success && o.success(resp);
      complete(resp);
    }

    function error(resp) {
      o.error && o.error(resp);
      complete(resp);
    }

    this.request = getRequest(o, success, error);
  }

  Reqwest.prototype = {
    abort: function () {
      this.request.abort();
    },

    retry: function () {
      init.call(this, this.o, this.fn);
    }
  };

  function reqwest(o, fn) {
    return new Reqwest(o, fn);
  }

  function enc(v) {
    return encodeURIComponent(v);
  }

  function serial(el) {
    var n = el.name;
    // don't serialize elements that are disabled or without a name
    if (el.disabled || !n) {
      return '';
    }
    n = enc(n);
    switch (el.tagName.toLowerCase()) {
    case 'input':
      switch (el.type) {
      // silly wabbit
      case 'reset':
      case 'button':
      case 'image':
      case 'file':
        return '';
      case 'checkbox':
      case 'radio':
        return el.checked ? n + '=' + (el.value ? enc(el.value) : true) + '&' : '';
      default: // text hidden password submit
        return n + '=' + (el.value ? enc(el.value) : '') + '&';
      }
      break;
    case 'textarea':
      return n + '=' + enc(el.value) + '&';
    case 'select':
      // @todo refactor beyond basic single selected value case
      return n + '=' + enc(el.options[el.selectedIndex].value) + '&';
    }
    return '';
  }

  reqwest.serialize = function (form) {
    var inputs = form[byTag]('input'),
        selects = form[byTag]('select'),
        texts = form[byTag]('textarea');
    return (v(inputs).chain().toArray().map(serial).value().join('') +
    v(selects).chain().toArray().map(serial).value().join('') +
    v(texts).chain().toArray().map(serial).value().join('')).replace(/&$/, '');
  };

  reqwest.serializeArray = function (f) {
    for (var pairs = this.serialize(f).split('&'), i = 0, l = pairs.length, r = [], o; i < l; i++) {
      pairs[i] && (o = pairs[i].split('=')) && r.push({name: o[0], value: o[1]});
    }
    return r;
  };

  var old = window.reqwest;
  reqwest.noConflict = function () {
    window.reqwest = old;
    return this;
  };

  // defined as extern for Closure Compilation
  // do not change to (dot) '.' syntax
  window['reqwest'] = reqwest;

}(this);

var joindin = function(){};

// TODO: lookup this URL from the config
joindin.urlBase_website = "http://joind.in/";
joindin.urlBase_api     = "http://api.joind.in/";

joindin.embedStyle      = true;
joindin.draw = function(talkId, node) {
	if (!node) {
		document.write('<div id="joindin-content-placeholder"></div>');
		node = document.getElementById("joindin-content-placeholder");
	} else if (typeof node == "string") {
		node = document.getElementById(node);
    }
    
	reqwest({
      url: joindin.urlBase_api + 'v2/talks/' + talkId + '?format=json&callback=?',
      type: 'jsonp',
      method: 'get',
      success: function (resp) {
          joindin.gotData(resp, node);
      },
      error: function (err) { 
          alert('ERROR');
      }
    });
    
}

joindin.gotData = function(data, node) {
	if (data.length < 1) {
		// No content returned, do nothing
		return;
	}
	data = data[0];
	var content = "";
	if (!joindin.gotData.embeddedStyles && joindin.embedStyle) {
		joindin.gotData.embeddedStyles = true;
		var headTag = document.getElementsByTagName('head')[0];
		var styleTag = document.createElement("link");
		styleTag.setAttribute("rel", "stylesheet");
		styleTag.setAttribute("href", joindin.urlBase_website + "/widget/widget.css");
		headTag.appendChild(styleTag);
	}

	content += "<div class='joindin-content-insert'>";

	var timeNow  = Date.UTC();
	var timeTalk = Date.parse(data.start_date);

	if (timeNow > timeTalk) {
		data.state = "future";
	} else if (data.comments_enabled) {
		data.state = "recent";
	} else {
		data.state = "past";
	}

	switch (data.state) {
		case 'future':
			content += '<div class="joindin-content-insert-future">';
			content += '<a href="' + data.website_uri + '">View on joind.in</a>';
			content += '</div>';
			break;
		case 'recent':
			content += '<div class="joindin-content-insert-recent">';
			if (data.average_rating != "") {
				content += '<p><img src="' + joindin.urlBase_website + 'inc/img/rating-' + data.average_rating + '.gif" width="75" /> (' + data.comment_count + ')</p>';
			}
			content += '<a href="' + data.website_uri + '">Comment on joind.in</a>';
			content += '</div>';
			break;
		case 'past':
			content += '<div class="joindin-content-insert-past">';
			if (data.average_rating != "") {
				content += '<p><img src="' + joindin.urlBase_website + 'inc/img/rating-' + data.average_rating + '.gif" width="75" /> (' + data.comment_count + ')</p>';
			}
			content += '<a href="' + data.website_uri + '">View on joind.in</a>';
			content += '</div>';
			break;
		default:
			// Unknown talk, do nothing
			break;
	}
	joindin.writeContent(content, node);
}

joindin.writeContent = function(content, node) {
	node.innerHTML = node.innerHTML + content;
}

