// Generated by CoffeeScript 1.9.1
(function() {
  var ACTIVITIES, ELEMENTS, default_msg, defaults, extend, getParameterByName, userale,
    slice = [].slice,
    indexOf = [].indexOf || function(item) { for (var i = 0, l = this.length; i < l; i++) { if (i in this && this[i] === item) return i; } return -1; };

  ACTIVITIES = ['ADD', 'REMOVE', 'CREATE', 'DELETE', 'SELECT', 'DESELECT', 'ENTER', 'LEAVE', 'INSPECT', 'ALTER', 'HIDE', 'SHOW', 'OPEN', 'CLOSE', 'PERFORM'];

  ELEMENTS = ['BUTTON', 'CANVAS', 'CHECKBOX', 'COMBOBOX', 'DATAGRID', 'DIALOG_BOX', 'DROPDOWNLIST', 'FRAME', 'ICON', 'INFOBAR', 'LABEL', 'LINK', 'LISTBOX', 'LISTITEM', 'MAP', 'MENU', 'MODALWINDOW', 'PALETTEWINDOW', 'PANEL', 'PROGRESSBAR', 'RADIOBUTTON', 'SLIDER', 'SPINNER', 'STATUSBAR', 'TAB', 'TABLE', 'TAG', 'TEXTBOX', 'THROBBER', 'TOAST', 'TOOLBAR', 'TOOLTIP', 'TREEVIEW', 'WINDOW', 'WORKSPACE', 'OTHER'];

  console.log('in userale');

  extend = function() {
    var i, key, len, object, objects, out, value;
    objects = 1 <= arguments.length ? slice.call(arguments, 0) : [];
    out = {};
    for (i = 0, len = objects.length; i < len; i++) {
      object = objects[i];
      for (key in object) {
        value = object[key];
        out[key] = value;
      }
    }
    return out;
  };

  getParameterByName = function(name) {
    var regex, results;
    name = name.replace(/[\[]/, "\\[").replace(/[\]]/, "\\]");
    regex = new RegExp("[\\?&]" + name + "=([^&#]*)");
    results = regex.exec(location.search);
    return results = results ? decodeURIComponent(results[1].replace(/\+/g, " ")) : "";
  };

  defaults = {
    loggingUrl: '',
    toolName: 'UNK',
    toolVersion: 'UNK',
    workerUrl: 'userale-worker.js',
    debug: true,
    sendLogs: true,
    componentGroups: []
  };

  default_msg = {
    activity: null,
    action: null,
    component: {
      id: null,
      type: null,
      group: null
    },
    source: null,
    object: null,
    tags: [],
    meta: {}
  };

  userale = (function() {
    function userale(options) {
      this.options = extend(defaults, options);
      if (this.options.componentGroups.constructor === !Array) {
        this.options.componentGroups = [this.options.componentGroups];
      }
      this.options.version = '3.0.0';
      this.worker = new Worker(this.options.workerUrl);
      this.worker.postMessage({
        cmd: 'setLoggingUrl',
        msg: this.options.loggingUrl
      });
      this.debug(this.options.debug);
      this.sendLogs(this.options.sendLogs);
    }

    userale.prototype.register = function() {
      this.options.sessionID = getParameterByName('USID');
      this.options.client = getParameterByName('client');
      console.log(this.options.sessionID);
      if (!this.options.sessionID) {
        this.options.sessionID = this.options.toolName.slice(0, 3).toUpperCase() + new Date().getTime();
        console.warn('USERALE: NO SESSION ID, MAKING ONE UP.  You can pass one in as url parameter (127.0.0.1?USID=12345)');
      }
      if (!this.options.client) {
        this.options.client = 'UNK';
        console.warn('USERALE: NO CLIENT, MAKING ONE UP.   You can pass one in as url parameter (127.0.0.1?client=roger)');
      }
      this.worker.postMessage({
        cmd: 'sendBuffer',
        msg: ''
      });
      window.onload = (function(_this) {
        return function() {
          var msg;
          msg = {
            activity: 'show',
            action: 'onload',
            component: {
              id: 'window',
              type: 'window',
              group: 'top'
            },
            source: 'user'
          };
          return _this.log(msg);
        };
      })(this);
      window.onbeforeunload = (function(_this) {
        return function() {
          var msg;
          msg = {
            activity: 'hide',
            action: 'onbeforeunload',
            component: {
              id: 'window',
              type: 'window',
              group: 'top'
            },
            source: 'user'
          };
          return _this.log(msg);
        };
      })(this);
      window.onfocus = (function(_this) {
        return function() {
          var msg;
          msg = {
            activity: 'show',
            action: 'onfocus',
            component: {
              id: 'window',
              type: 'window',
              group: 'top'
            },
            source: 'user'
          };
          return _this.log(msg);
        };
      })(this);
      return window.onblur = (function(_this) {
        return function() {
          var msg;
          msg = {
            activity: 'hide',
            action: 'onblur',
            component: {
              id: 'window',
              type: 'window',
              group: 'top'
            },
            source: 'user'
          };
          return _this.log(msg);
        };
      })(this);
    };

    userale.prototype.log = function(msg) {
      var activities, activity, elementType, i, key, len, ref, value, x;
      for (key in msg) {
        value = msg[key];
        msg = extend(default_msg, msg);
        if (key === 'component') {
          if (ref = value.group, indexOf.call(this.options.componentGroups, ref) < 0) {
            console.warn(value.group + " is NOT in component groups");
          }
          elementType = value.type.toUpperCase();
          if (indexOf.call(ELEMENTS, elementType) < 0) {
            console.warn("USERALE: Unrecognized element - " + elementType);
          } else if ((elementType === 'OTHER') && (msg.meta.element == null)) {
            console.warn("USERALE: Element type set to 'other', but 'element' not set in meta object ");
          }
          msg.component.type = elementType;
        }
        if (key === 'activity') {
          activities = (function() {
            var i, len, ref1, results1;
            ref1 = value.split('_');
            results1 = [];
            for (i = 0, len = ref1.length; i < len; i++) {
              x = ref1[i];
              results1.push(x.toUpperCase());
            }
            return results1;
          })();
          for (i = 0, len = activities.length; i < len; i++) {
            activity = activities[i];
            if (indexOf.call(ACTIVITIES, activity) < 0) {
              console.warn("USERALE: Unrecognized activity - " + activity);
            }
          }
          msg[key] = activities;
        }
        if (key === 'source') {
          value = value.toUpperCase();
          if (value !== 'USER' && value !== 'SYSTEM' && value !== 'UNK') {
            console.warn("USERALE: Unrecognized source - " + value);
            msg[key] = null;
          } else {
            msg[key] = value.toUpperCase();
          }
        }
      }
      msg.timestamp = new Date().toJSON();
      msg.client = this.options.client;
      msg.toolName = this.options.toolName;
      msg.toolVersion = this.options.toolVersion;
      msg.sessionID = this.options.sessionID;
      msg.language = 'JavaScript';
      msg.useraleVersion = this.version;
      return this.worker.postMessage({
        cmd: 'sendMsg',
        msg: msg
      });
    };

    userale.prototype.debug = function(onOff) {
      this.options.debug = onOff;
      return this.worker.postMessage({
        cmd: 'setEcho',
        msg: onOff
      });
    };

    userale.prototype.sendLogs = function(onOff) {
      this.options.sendLogs = onOff;
      return this.worker.postMessage({
        cmd: 'setTesting',
        msg: !onOff
      });
    };

    return userale;

  })();

  this.userale = userale;

}).call(this);
