// 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,
    elementGroups: []
  };

  default_msg = {
    activity: '',
    action: '',
    elementId: '',
    elementType: '',
    elementGroup: '',
    elementSub: '',
    source: '',
    tags: [],
    meta: {}
  };

  userale = (function() {
    function userale(options) {
      this.options = extend(defaults, options);
      if (this.options.elementGroups.constructor === !Array) {
        this.options.elementGroups = [this.options.elementGroups];
      }
      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)');
      }
      return this.worker.postMessage({
        cmd: 'sendBuffer',
        msg: ''
      });
    };

    userale.prototype.log = function(msg) {
      var activities, activity, i, key, len, value, x;
      msg = extend(default_msg, msg);
      for (key in msg) {
        value = msg[key];
        if (key === 'elementType') {
          value = value.toUpperCase();
          if (indexOf.call(ELEMENTS, value) < 0) {
            console.warn("USERALE: Unrecognized element - " + value);
          } else if ((value === 'OTHER') && (msg.meta.element == null)) {
            console.warn("USERALE: Element type set to 'other', but 'element' not set in meta object ");
          }
          msg.elementType = msg.elementType.toUpperCase();
        }
        if (key === 'elementGroup') {
          if (indexOf.call(this.options.elementGroups, value) < 0) {
            console.warn(value + " is NOT in element groups");
          }
        }
        if (key === 'activity') {
          activities = (function() {
            var i, len, ref, results1;
            ref = value.split('_');
            results1 = [];
            for (i = 0, len = ref.length; i < len; i++) {
              x = ref[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;

  })();

  window.userale = userale;

}).call(this);

//# sourceMappingURL=userale.js.map
