// Generated by CoffeeScript 1.4.0
(function() {
  var TabManager, clickms, lastTouchDown, touchHandler, _escape;

  window.WEB_SOCKET_SWF_LOCATION = '/static/main/WebSocketMain.swf';

  window.Stream = (function() {

    function Stream() {}

    Stream.prototype.start = function() {
      this.socket = ajentiConnectSocket('/stream');
      this.socket.on('connect', function() {
        return $('#connection-error').hide();
      });
      this.socket.on('auth-error', function() {
        console.log('Authentication lost!');
        return location.reload();
      });
      this.socket.on('disconnect', function() {
        return $('#connection-error').show();
      });
      this.socket.on('init', function(data) {
        data = JSON.parse(data);
        console.group('Welcome to Ajenti');
        console.log('version', data.version);
        console.log('running on', data.platform);
        $('title').text(data.hostname);
        return console.groupEnd();
      });
      this.socket.on('ui', function(ui) {
        console.group('Received update');
        console.log('Transfer size', ui.length);
        ui = RawDeflate.inflate(RawDeflate.Base64.decode(ui));
        console.log('Payload size', ui.length);
        ui = JSON.parse(ui);
        console.log('JSON data:', ui);
        UI.clear();
        profiler.start('UI inflating');
        ui = UI.inflate(ui);
        profiler.stop();
        profiler.start('UI replacement');
        UI.replace(ui);
        profiler.stop();
        console.log('Total elements:', UI._total_elements);
        console.groupEnd();
        return Loading.hide();
      });
      this.socket.on('ack', function() {
        return Loading.hide();
      });
      this.socket.on('update-request', function() {
        UI.checkForUpdates();
        UI.sendUpdates(true);
        return Loading.show();
      });
      this.socket.on('crash', function(data) {
        data = JSON.parse(data);
        console.log('CRASH:', data);
        return ajentiCrash(data);
      });
      this.socket.on('security-error', function() {
        console.log('SECURITY ERROR');
        return ajentiSecurityError();
      });
      this.socket.on('notify', function(data) {
        data = JSON.parse(data);
        return Notificator.notify(data.type, data.text);
      });
      this.socket.on('url', function(data) {
        data = JSON.parse(data);
        return Tabs.addTab(data.url, data.title);
      });
      this.socket.on('debug', function(data) {
        var d;
        data = JSON.parse(data);
        console.group('Profiling');
        for (d in data.profiles) {
          console.log(d, data.profiles[d]);
        }
        return console.groupEnd();
      });
      return $('#connection-error').hide();
    };

    Stream.prototype.send = function(message) {
      console.log('Sending updates', message);
      this.socket.send(JSON.stringify(message));
      return Loading.show();
    };

    Stream.prototype.emit_ui_update = function(updates) {
      return this.send({
        type: 'ui_update',
        content: updates
      });
    };

    return Stream;

  })();

  window.UIManager = (function() {

    function UIManager(stream) {
      this.stream = stream;
      this.ui = null;
      this.pendingUpdates = [];
      this.updaterTimeout = null;
    }

    UIManager.prototype.inflate = function(json) {
      var child, children, cls, typeid, _fn, _i, _len, _ref,
        _this = this;
      children = [];
      this._total_elements += 1;
      if (json.visible === true) {
        _ref = json.children;
        _fn = function(child) {
          return children.push(_this.inflate(child));
        };
        for (_i = 0, _len = _ref.length; _i < _len; _i++) {
          child = _ref[_i];
          _fn(child);
        }
      }
      typeid = json.typeid.replace(':', '__');
      cls = Controls[typeid];
      if (!cls) {
        cls = Controls["default"];
      }
      return new cls(this, json, children);
    };

    UIManager.prototype.clear = function() {
      this._total_elements = 0;
      if (this.ui) {
        this.ui.broadcast('destruct');
      }
      $('.root *').unbind();
      $.cleanData($('.root *'));
      $('.root *').safeRemove();
      return delete this.ui;
    };

    UIManager.prototype.replace = function(ui) {
      $('.ui-tooltip').remove();
      this.ui = ui;
      $('.root').append(this.ui.dom);
      return aoConnector.reportHeight($('body')[0].scrollHeight);
    };

    UIManager.prototype.extractUpdates = function(control, target) {
      var child, updates, _i, _len, _ref, _results,
        _this = this;
      updates = control.extractUpdates();
      if (updates) {
        target.push(updates);
      }
      _ref = control.children;
      _results = [];
      for (_i = 0, _len = _ref.length; _i < _len; _i++) {
        child = _ref[_i];
        _results.push((function(child) {
          return _this.extractUpdates(child, target);
        })(child));
      }
      return _results;
    };

    UIManager.prototype.checkForUpdates = function() {
      var update, updates, _i, _len, _results,
        _this = this;
      updates = [];
      this.extractUpdates(this.ui, updates);
      _results = [];
      for (_i = 0, _len = updates.length; _i < _len; _i++) {
        update = updates[_i];
        _results.push((function(update) {
          return _this.queueUpdate(update);
        })(update));
      }
      return _results;
    };

    UIManager.prototype.queueUpdate = function(update) {
      return this.pendingUpdates.push(update);
    };

    UIManager.prototype.sendUpdates = function(force) {
      var _this = this;
      if (force == null) {
        force = false;
      }
      if (this.updaterTimeout) {
        clearTimeout(this.updaterTimeout);
      }
      return this.updaterTimeout = setTimeout(function() {
        if (force || _this.pendingUpdates.length > 0) {
          _this.stream.emit_ui_update(_this.pendingUpdates);
        }
        _this.pendingUpdates = [];
        return _this.updaterTimeout = null;
      }, 50);
    };

    UIManager.prototype.event = function(control, event, params) {
      var update;
      this.checkForUpdates();
      update = {
        type: 'event',
        uid: control.uid,
        event: event,
        params: params != null ? params : null
      };
      this.queueUpdate(update);
      return this.sendUpdates();
    };

    UIManager.prototype.restoreTheme = function() {
      if (getCookie('ajenti-theme') === 'dark') {
        return this.toggleTheme();
      }
    };

    UIManager.prototype.toggleTheme = function() {
      $('html').toggleClass('ui-dark');
      $('html').toggleClass('ui-light');
      if ($('html').hasClass('ui-dark')) {
        return setCookie('ajenti-theme', 'dark');
      } else {
        return setCookie('ajenti-theme', 'light');
      }
    };

    return UIManager;

  })();

  window.LoadingDim = (function() {

    function LoadingDim(dom) {
      this.dom = dom;
      this.dom.show();
    }

    LoadingDim.prototype.hide = function() {
      var _this = this;
      $('body').removeClass('loading');
      return this.dom.stop().fadeTo(500, 0, function() {
        return _this.dom.hide();
      });
    };

    LoadingDim.prototype.show = function() {
      $('body').addClass('loading');
      return this.dom.show().stop().fadeTo(500, 1);
    };

    return LoadingDim;

  })();

  TabManager = (function() {

    function TabManager() {
      var _this = this;
      this.mainTab = $('#tab-ajenti');
      this.tabHeadersDom = $('#tab-headers');
      this.tabsDom = $('#tabs');
      this.tabHeadersDom.find('a').click(function() {
        return _this.goHome();
      });
      this.goHome();
      this.openTabs = {};
    }

    TabManager.prototype.goHome = function() {
      this.tabsDom.find('>*').hide();
      this.mainTab.show();
      this.tabHeadersDom.find('a').removeClass('active');
      return this.tabHeadersDom.find('a:first').addClass('active');
    };

    TabManager.prototype.addTab = function(url, title) {
      var dom, headerDom,
        _this = this;
      if (this.openTabs[url]) {
        this.openTabs[url].click();
        return;
      }
      dom = $("<div class=\"tab\"><iframe src=\"" + url + "\" /></div>");
      this.tabsDom.append(dom);
      headerDom = $("<a href=\"#\">" + title + "<span class=\"close\"><i class=\"icon-remove\"></span></a></a>");
      this.tabHeadersDom.append(headerDom);
      this.openTabs[url] = headerDom;
      this.openTabs[url].dom = dom;
      headerDom.click(function() {
        _this.tabsDom.find('>*').hide();
        dom.show();
        setTimeout(function() {
          return dom.find('iframe')[0].contentWindow.focus();
        }, 100);
        _this.tabHeadersDom.find('a').removeClass('active');
        return headerDom.addClass('active');
      });
      headerDom.find('.close').click(function() {
        return _this.closeTab(url);
      });
      return headerDom.click();
    };

    TabManager.prototype.closeTab = function(url) {
      this.openTabs[url].dom.remove();
      this.openTabs[url].remove();
      delete this.openTabs[url];
      return this.goHome();
    };

    return TabManager;

  })();

  $(function() {
    window.Loading = new LoadingDim($('#loading'));
    window.Tabs = new TabManager();
    if (window.UI) {
      UI.restoreTheme();
      return $('#ui-theme-toggle').click(function() {
        return UI.toggleTheme();
      });
    }
  });

  window.Controls = {};

  window.Control = (function() {

    function Control(ui, properties, children) {
      var child, _base, _fn, _i, _len, _ref, _ref1,
        _this = this;
      this.ui = ui;
      this.properties = properties;
      if ((_ref = this.properties) == null) {
        this.properties = {};
      }
      if ((_ref1 = (_base = this.properties).visible) == null) {
        _base.visible = true;
      }
      this.uid = this.properties.uid;
      this.childContainer = null;
      this.dom = null;
      this.children = [];
      profiler.start('Generating DOM');
      this.createDom();
      profiler.stop();
      if (children) {
        _fn = function(child) {
          return _this.append(child);
        };
        for (_i = 0, _len = children.length; _i < _len; _i++) {
          child = children[_i];
          _fn(child);
        }
      }
      if (this.properties.visible !== true && this.dom) {
        this.dom.hide();
      }
      if (this.dom && this.dom.length) {
        this.dom = this.dom[0];
      }
      if (this.childContainer) {
        this.childContainer = this.childContainer[0];
      }
    }

    Control.prototype.createDom = function() {
      return "";
    };

    Control.prototype.destruct = function() {};

    Control.prototype.detectUpdates = function() {
      return {};
    };

    Control.prototype.wrapChild = function(child) {
      return child.dom;
    };

    Control.prototype.onBroadcast = function(msg) {};

    Control.prototype.broadcast = function(msg) {
      var c, _i, _len, _ref, _results,
        _this = this;
      this.onBroadcast(msg);
      _ref = this.children;
      _results = [];
      for (_i = 0, _len = _ref.length; _i < _len; _i++) {
        c = _ref[_i];
        _results.push((function(c) {
          return c.broadcast(msg);
        })(c));
      }
      return _results;
    };

    Control.prototype.extractUpdates = function() {
      var k, updates, _fn,
        _this = this;
      updates = this.detectUpdates();
      if (!this.uid || $.isEmptyObject(updates)) {
        return null;
      }
      _fn = function(k) {
        return _this.properties[k] = updates[k];
      };
      for (k in updates) {
        _fn(k);
      }
      return {
        type: 'update',
        uid: this.uid,
        properties: updates
      };
    };

    Control.prototype.append = function(child) {
      var wrapper;
      this.children.push(child);
      wrapper = this.wrapChild(child);
      return $(this.childContainer).append(wrapper);
    };

    Control.prototype.publish = function() {
      this.ui.checkForUpdates();
      return this.ui.sendUpdates();
    };

    Control.prototype.event = function(event, params) {
      var localHandler;
      this.ui.checkForUpdates();
      localHandler = this['on_' + event];
      if (localHandler) {
        if (!localHandler(params)) {
          return false;
        }
      }
      if (!this.uid || this.properties.client) {
        return false;
      }
      this.ui.event(this, event, params);
      return true;
    };

    Control.prototype._int_to_px = function(i) {
      if (/^[0-9]+$/.test(i)) {
        return i + 'px';
      }
      if (i === null || i === 'auto') {
        return 'auto';
      }
      return i + '';
    };

    Control.prototype.cancel = function(event) {
      event.preventDefault();
      return event.stopPropagation();
    };

    return Control;

  })();

  _escape = function(s) {
    return s.replace(/</g, '&lt;');
  };

  window.ajentiConnectSocket = function(uri) {
    return io.connect(uri, {
      resource: 'ajenti:socket'
    });
  };

  window.ajentiCrash = function(info) {
    $('#crash').fadeIn();
    $('#crash-traceback').html(_escape(info.message + "\n" + info.traceback));
    return $('#crash-report textarea').val(info.report);
  };

  window.ajentiCrashResume = function(info) {
    return $('#crash').fadeOut();
  };

  window.ajentiCrashShowReport = function() {
    var _this = this;
    $('#crash-traceback').toggle('blind');
    $('#crash-report').toggle('blind');
    return setTimeout(function() {
      return $('#crash-report textarea').focus()[0].select();
    }, 1000);
  };

  window.ajentiSecurityError = function() {
    return $('#security-error').fadeIn();
  };

  window.ajentiSecurityResume = function(info) {
    return $('#security-error').fadeOut();
  };

  $.fn.safeRemove = function() {
    return this.each(function(i, e) {
      if (e.parentNode) {
        return e.parentNode.removeChild(e);
      }
    });
  };

  $(function() {
    if (location.protocol === 'https:' || location.hostname === 'localhost') {
      return $('#ssl-alert').hide();
    }
  });

  clickms = 100;

  lastTouchDown = -1;

  touchHandler = function(event) {
    var d, first, simulatedEvent, touches, type;
    touches = event.changedTouches;
    first = touches[0];
    type = "";
    d = new Date();
    switch (event.type) {
      case "touchstart":
        type = "mousedown";
        lastTouchDown = d.getTime();
        break;
      case "touchmove":
        type = "mousemove";
        lastTouchDown = -1;
        break;
      case "touchend":
        if (lastTouchDown > -1 && (d.getTime() - lastTouchDown) < clickms) {
          lastTouchDown = -1;
          type = "click";
        } else {
          type = "mouseup";
        }
        break;
      default:
        return;
    }
    simulatedEvent = document.createEvent("MouseEvent");
    simulatedEvent.initMouseEvent(type, true, true, window, 1, first.screenX, first.screenY, first.clientX, first.clientY, false, false, false, false, 0, null);
    first.target.dispatchEvent(simulatedEvent);
    return event.preventDefault();
  };

}).call(this);
