if (typeof Narabete == 'undefined') {
  var Narabete = {};
}
if (typeof Narabete.Callbacks == 'undefined') {
  Narabete.Callbacks = [];
}
if (typeof Narabete.Widget == 'undefined') {
  Narabete.Widget = function() {
    function prepare(params) {
      if (typeof params == 'undefined') {
        params = {};
      }
      if (typeof params.tableId == 'undefined') {
        return null;
      }
      if (typeof params.rows == 'undefined') {
        return null;
      }
      if (typeof params.cols == 'undefined') {
        return null;
      }
      if (typeof params.useOwnCSS == 'undefined') {
        params.useOwnCSS = false;
      }
      if (typeof params.url == 'undefined') {
        params.url = 'http://test.narabete.com/';
      }
      return params;
    }

    function load(params) {
      if (!params.useOwnCSS) {
        loadCSS(params);
      }
      params.id = Narabete.Callbacks.length;
      createDiv(params);
      Narabete.Callbacks.push(createTable(params));
      loadJSONP(createRequest(params));
    }

    function createRequest(params) {
      return function() {
        var request = params.url + 'jsonp/table/' + [
          params.tableId,
          'Narabete.Callbacks['+params.id+']'
          ].join('/');
        var script = $E('script', { defer: 'defer', type: 'text/javascript', charset: 'utf-8', src: request });
        document.getElementsByTagName('head')[0].appendChild(script);
      }
    }

    function createDiv(params, container) {
      var div = $E('div', {
        id: 'narabete-widget-table-'+params.id,
        className: 'narabete-widget'
        }, []);

      var tmp = $E('div', null);
      tmp.appendChild(div);
      document.write(tmp.innerHTML);
    }

    function filter(data, keys) {
      var sortedData = [];
      for (var i = 0, l = keys.length; i < l; i++) {
        for (var j = 0, m = data.length; j < m; j++) {
          var id = data[j].id;
          if (data[j].length) {
            id = data[j][0].id;
          }
          if (keys[i] == id) {
            sortedData.push(data[j]);
            break;
          }
        }
      }
      return sortedData;
    }

    function createTable(params) {
      return function(json) {
        var columns = json.data.shift();
        columns = filter(columns, params.cols);
        var table = $E('table', null, [
          $E('caption', null, [
            $E('a', {href: json.table.url}, [json.table.name]),
            ' by ',
            $E('a', {href: json.url}, [json.name])]),
          $E('thead', null, [
            $E('tr', null, function() {
              var arr = [$E('th', null)];
              for (var i = 0, l = columns.length; i < l; i++) {
                arr.push($E('th', null, [columns[i].name]));
              }
              return arr;
           }())
          ]),
          $E('tbody', null, function() {
            var arr = [];
            var rows = json.data;
            rows = filter(rows, params.rows);
            for (var i = 0, l = rows.length; i < l; i++) {
              arr.push($E('tr', null, function(index) {
                var arr2 = [];
                var row = rows[index].shift();
                arr2.push($E('th', null, [row.name]));
                for (var j = 0, m = columns.length; j < m; j++) {
                  var element = null;
                  if (rows[index][j].intValue > 0) {
                    element = $E('td', {className: 'yea'}, [rows[index][j].value]);
                  } else if (rows[index][j].intValue < 0) {
                    element = $E('td', {className: 'nay'}, [rows[index][j].value]);
                  } else {
                    element = $E('td', null, [rows[index][j].value]);
                  }
                  arr2.push(element);
                }
                return arr2;
              }(i)));
            }
            return arr;
          }())
        ]);
        document.getElementById('narabete-widget-table-'+params.id).appendChild(table);
      };
    }

    function loadJSONP(func) {
      var ua = navigator.userAgent.toUpperCase();
      if (window.opera || ua.indexOf('FIREFOX') >= 0) {
        var e = 'DOMContentLoaded';
        var listener = function() {
          return func.call();
        }
        if (window.addEventListener) {
          window.addEventListener(e, listener, false);
        } else if (window.attachEvent) {
          window.attachEvent(e, listener);
        }
      } else if ((ua.indexOf('MSIE') >= 0 || ua.toLowerCase().indexOf('webkit') >= 0)) {
        var i = 0;
        (function() {
          if (i++ > 10000) return func.call();
          try {
            if (document.readyState != 'loaded' && document.readyState != 'complete') {
              document.documentElement.doScroll('left');
            }
          } catch(error) {
            return setTimeout(arguments.callee, 13);
          }
          func.call();
        })();
      } else {
        func.call();
      }
    }

    function loadCSS(params) {
      var url = params.url + 'css/widget.css';
      var link = $E('link', { rel: 'stylesheet', type: 'text/css', href: url });
      document.getElementsByTagName('head')[0].appendChild(link);
    }

    function $E(tagName, attributes, children) {
      var element = document.createElement(tagName);
      for (var a in attributes) {
        if (a == 'style') {
          for (prop in attributes[a]) {
            elememnt.style[prop] = attributes[a][prop];
          }
        } else {
          element[a] = attributes[a];
        }
      }
      if (typeof children == 'undefined') {
        children = [];
      }

      for (var i = 0, l = children.length; i < l; i++) {
        var child = children[i];
        if (typeof child == 'string' || typeof child == 'number') {
          child = document.createTextNode(child);
        }
        if (!child) {
          continue;
        }
        element.appendChild(child);
      }
      return element;
    }

    return {
      init: function(params) {
        params = prepare(params);

        if (params == null) {
          alert("Sorry, the passed parameters are wrong, please check if they are right.");
          return;
        }
        load(params);
      }
    }
  }();
}

