"use strict";

var _typeof2 = require("babel-runtime/helpers/typeof");

var _typeof3 = _interopRequireDefault(_typeof2);

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; }

__webpack_public_path__ = VVC_PUBLIC_PATH;

/**
 * Vivocha Core Library
 * @mixin
 * @alias VivochaCore
 */
var vivocha = module.exports = {};

var opt = typeof window.vvc_options !== 'undefined' ? window.vvc_options : {},
    proto = opt.secure ? "https:" : "";

require('./polyfill').then(function () {
  var _console = require('./console');
  vivocha.debug = _console;
  vivocha.console = _console('vvc-core');
  vivocha.namespaces = _console.namespaces;
  vivocha.log = vivocha.console.log;
});

/**
 * @callback GenericCallback
 * @param {*} err Set if an error occurred.
 * @param {*} data The result of the requested operation.
 */

/**
 * A class that describes objects that can handle and emit events
 * @external EventEmitter
 * @see {@link https://nodejs.org/dist/latest-v6.x/docs/api/events.html#events_class_eventemitter}
 */

function getConfig(url, config) {
  var check = url.match(/\/a\/(\w*)\/(api|apps|widgetwrap|js)\/(console\/)?(vivocha|dataframe|vivocha_app.js)?/);
  if (check && check.length > 1) {
    if (check[1] !== '_') {
      var a = document.createElement('a');
      a.setAttribute('href', url);
      config.apihost = typeof VVC_APIHOST !== 'undefined' ? VVC_APIHOST : a.hostname;
      config.acct_id = check[1];
      config.apiurl = proto + "//" + config.apihost + "/a/" + config.acct_id + "/api/";
      config.sapiurl = "https://" + config.apihost + "/a/" + config.acct_id + "/api/";
      config.liburl = typeof VVC_PUBLIC_PATH !== 'undefined' ? VVC_PUBLIC_PATH : proto + '//' + config.apihost + '/w/' + config.world + '/' + config.ajv + '/';
      if (check[3]) {
        config.apiurl = config.apiurl + '_/';
        config.sapiurl = config.sapiurl + '_/';
      } else {
        config.gifurl = config.apiurl + 'vvct.gif';
      }
      return true;
    }
  }
}

vivocha.scriptParentNode = document.body;
vivocha.nodeify = function (promise, cb) {
  if (typeof promise.then === 'function' && typeof promise.nodeify !== 'function') {
    promise.nodeify = function (cb) {
      if (cb) {
        this.then(function (data) {
          var args = Array.prototype.slice.call(arguments);
          args.unshift(undefined);
          cb.apply(this, args);
        }, function (err) {
          cb(err);
        });
      } else {
        return this;
      }
    };
  }
  if (cb) promise.nodeify(cb);
  return promise;
};

vivocha.ready = function () {
  return require('./polyfill');
};

/**
 * Utility function to safely retrieve or set the value of a property in nested objects.
 * The function allows you to do things like a.b.c.d.e.f without worrying if any of the transversed properties are defined.
 * When setting a property, the function will created any undefined properties along the path.
 * @param {object} data - The root object to read from/write to.
 * @param {string|string[]} path - A dot-separated path, e.g. `'b.c.d.e.f'`. Alternatevely the function accepts an array
 * of property names to transverse, e.g. `[ 'b', 'c', 'd', 'e', 'f' ]`.
 * @param {*} [value] - Value to set at the specified path.
 * @returns {*} The value of the requested property, `undefined` if any property along the path is `undefined`.
 * @deprecated Consider using jsonref.pointer() from the module jsonref (https://www.npmjs.com/package/jsonref) instead.
 * @example
 * var obj = {
 *   a: {
 *     b: {
 *       c: {
 *         e: {
 *           f: 10
 *         }
 *       }
 *     }
 *   }
 * }
 *
 * var out;
 *
 * out = vivocha.dot(obj, 'a.b.c.d.e.f'); // out is now 10
 * out = vivocha.dot(obj, 'a.b.c.d.e.f', 20); // out is now 20
 * out = vivocha.dot(obj, 'a.b.x.y.w.z'); // out is now undefined
 * out = vivocha.dot(obj, 'a.b.x.y.w.z', 30); // out is now 30
 */
vivocha.dot = function (data, path, value, del) {
  if (!data) return;
  var parts = path ? path.split('.') : [];
  var ref = data;
  var tmpref;
  if (typeof value === 'undefined') {
    for (var i = 0, max = parts.length; typeof ref !== 'undefined' && i < max; i++) {
      try {
        tmpref = ref;
        ref = ref[parts[i]];
      } catch (e) {
        return;
      }
    }
    if (ref && del) {
      delete tmpref[parts[i - 1]];
    }
  } else {
    for (var i = 0, max = parts.length - 1, p = null; p = parts[i], i < max; i++) {
      if ((0, _typeof3["default"])(ref[p]) !== 'object') {
        ref[p] = parseInt(parts[i + 1]) || parts[i + 1] == 0 ? [] : {};
      }
      ref = ref[p];
    }
    ref[p] = value;
    ref = ref[p];
  }
  return ref;
};

/**
 * Parses a www-urlencoded query strings and returns it as an object
 * @param {string} qs - An urlencoded query string (e.g. `a=b&c=d`)
 * @returns {object} The parsed query string (e.g. `{ a: 'b', c: 'd' }`)
 */
vivocha.query = function (qs) {
  var parts = qs.split("&");
  var $_GET = {};
  for (var i = 0; i < parts.length; i++) {
    var temp = parts[i].split("=");
    $_GET[decodeURIComponent(temp[0])] = decodeURIComponent(temp[1]);
  }
  return $_GET;
};

/**
 * Basic configuration data of the Library
 * @type {object}
 * @property ajv
 */
vivocha.config = function () {
  var config = {
    ajv: typeof VVC_AJV !== 'undefined' ? VVC_AJV : 0,
    ver: typeof VVC_VER !== 'undefined' ? VVC_VER : 0,
    version: typeof VVC_VERSION !== 'undefined' ? VVC_VERSION : 0,
    versionfull: typeof VVC_VERSIONFULL !== 'undefined' ? VVC_VERSIONFULL : 0,
    world: typeof VVC_WORLD !== 'undefined' ? VVC_WORLD : 'www',
    domain: typeof VVC_DOMAIN !== 'undefined' ? VVC_DOMAIN : '.vivocha.com'
  };
  var scripts = document.getElementsByTagName('script');
  var found;
  for (var i = 0; scripts && i < scripts.length; i++) {
    if (getConfig(scripts[i].src, config)) {
      if (scripts[i].parentNode.tagName && scripts[i].parentNode.tagName !== 'HEAD') {
        vivocha.scriptParentNode = scripts[i].parentNode;
      } else {
        vivocha.scriptParentNode = document.body;
      }
      found = true;
    }
  }
  if (!found) {
    // location check for dataframe
    getConfig(location.href, config);
  }
  return config;
}();

/**
 * Extends an object copying into it all the properties of another object
 * @param {object} obj - The object to extend
 * @param {object} extObj - The object whose property will be copied into `obj`
 * @returns {Object}
 */
vivocha.extend = function (obj, extObj) {
  if (arguments.length > 2) {
    var a = 1;
    for (; a < arguments.length; a++) {
      vivocha.extend(obj, arguments[a]);
    }
  } else {
    var i;
    for (i in extObj) {
      if (extObj.hasOwnProperty(i)) {
        obj[i] = extObj[i];
      }
    }
  }
  return obj;
};

/**
 * Creates a www-urlencoded query string from a dictionary
 * @param {object} obj - The dictionary to convert
 * @returns {string} A query string
 * @example
 * vivocha.param({a: 1, b: 2}); // returns "a=1&b=2"
 */
vivocha.param = function (obj) {
  var p,
      str = [];
  for (p in obj) {
    if (obj.hasOwnProperty(p)) {
      str.push(p + "=" + encodeURIComponent(obj[p]));
    }
  }
  return str.join("&");
};

/** @var {string} VivochaCore.domain Default domain of cookies created with {@link VivochaCore.cookie} */

/** @var {VivochaBus} VivochaCore.bus The [Vivocha Bus]{@link VivochaBus} singleton */

/**
 * Utility function to get/set a cookie
 * @param {string} key Name of the cookie.
 * @param {*} [value] If the argument is omitted, the current value of cookie is returned. Otherwise, the cookie is set
 * to `value`. Although any type can be passed, please bear in mind that cookies are converted to and stored in the
 * browser as strings. If `value` is `undefined`, the cookie is unset.
 * @param {object} [options] Cookie options.
 * @param {string} [options.domain=vivocha.domain] The domain of the cookie.
 * @param {Date|number} [options.expires] An expiration date or a number of days from the moment the cookie is set. If
 * omitted, the cookie will be a session cookie.
 * @param {string} [options.path] The path of the cookie.
 * @param {boolean} [options.secure] The secure flag of the cookie.
 * @param {boolean} [options.raw] If omitted or set to falsy, the value of the cookie is passed through
 * `encodeURIComponent` when setting, and `decodeURIComponent` when reading.
 * @returns {string} The value of the cookie, `undefined` if the cookie does not exist.
 */
vivocha.cookie = function (key, value, options) {
  // key and at least value given, set cookie...
  if (arguments.length > 1 && String(value) !== "[object Object]") {
    // Create Global "extend" method
    options = vivocha.extend(options);
    if (typeof options.domain === 'undefined' && typeof vivocha.domain !== 'undefined') {
      options.domain = vivocha.domain;
    }

    if (value === null || value === undefined) {
      options.expires = -1;
    }

    if (typeof options.expires === 'number') {
      var days = options.expires,
          t = options.expires = new Date();
      t.setDate(t.getDate() + days);
    }

    value = String(value);

    return document.cookie = [encodeURIComponent(key), '=', options.raw ? value : encodeURIComponent(value), options.expires ? '; expires=' + options.expires.toUTCString() : '', // use expires attribute, max-age is not supported by IE
    options.path ? '; path=' + options.path : '', options.domain ? '; domain=' + options.domain : '', options.secure ? '; secure' : ''].join('');
  }

  // key and possibly options given, get cookie...
  options = value || {};
  var result,
      decode = options.raw ? function (s) {
    return s;
  } : decodeURIComponent;
  result = new RegExp('(?:^|; )' + encodeURIComponent(key) + '=([^;]*)').exec(document.cookie);
  return result ? decode(result[1]) : null;
};

/**
 * Invokes a [Vivocha V1 REST Web Service](https://docs.vivocha.com/display/VVCJ/Vivocha+REST+API)
 * @param {string} type The type of web service to call
 * @param {string} cmd The command to execute
 * @param {object} [data] The data to send to the server in the query string of GETs or in the body of POSTs.
 * @param {string} [method=GET] The HTTP method of the request. This function supports only GET and POST.
 * @param {GenericCallback} cb Called with either the result or an error.
 * @deprecated Use [vivocha.channel().ws]{@link VivochaChannel#ws}
 */
vivocha.ws = function (type, cmd, data, method, cb) {
  require.ensure(['./jquery'], function (require) {
    var $ = require('./jquery');
    if (typeof data === 'function' || typeof data === 'undefined') {
      cb = data;
      method = 'GET';
      data = {};
    } else if (typeof method === 'function' || typeof method === 'undefined') {
      cb = method;
      method = 'GET';
    }
    cb = cb || function () {};
    var httpClient = null;
    var httpOptions = {
      url: vivocha.config.sapiurl + (type ? type + '/' : '') + (cmd ? cmd + '/' : ''),
      data: data,
      success: function success(data) {
        if (data.ts) vivocha.serverTimeDiff = +new Date(data.ts) - +new Date();
        if (data.acct_id) vivocha.acct_id = data.acct_id;
        if (data.user_id) vivocha.user_id = data.user_id;
        if (data.result || data.event) {
          cb(null, data);
        } else {
          cb(data || {}, null);
        }
      },
      error: function error(d) {
        cb(d, null);
      },
      timeout: 0
    };

    if (method === 'POST') {
      httpClient = $.ajax;
      httpOptions.type = 'POST';
      httpOptions.xhrFields = { withCredentials: true };
    } else {
      httpClient = $.jsonp || $.ajax;
      httpOptions.dataType = 'jsonp'; // $.ajax
      httpOptions.callbackParameter = 'callback'; // $.jsonp
    }
    httpClient(httpOptions);
  }, 'js/jquery');
};

vivocha.ws_new = function (type, cmd, query, opts) {
  var url = vivocha.config.sapiurl + (type ? type + '/' : '') + (cmd ? cmd + '/' : '');
  var qs = [];
  for (var i in query) {
    qs.push(i + '=' + encodeURIComponent(query[i]));
  }
  qs = qs.join('&');
  if (qs) url += '?' + qs;
  return fetch(url, opts).then(function (response) {
    if (response.status === 200) {
      return response.json();
    } else {
      throw new Error(response.statusText);
    }
  }).then(function (data) {
    if (data.ts) vivocha.serverTimeDiff = +new Date(data.ts) - +new Date();
    if (data.acct_id) vivocha.acct_id = data.acct_id;
    if (data.user_id) vivocha.user_id = data.user_id;
    if (data.status === 200 || data.result === true) {
      return data;
    } else {
      throw new Error(data.error || 'error');
    }
  });
};

/**
 * Utility function to detect if the browser is running on a mobile device
 * @returns {boolean}
 */
vivocha.isMobile = function () {
  var userAgent = typeof navigator !== 'undefined' ? navigator.userAgent : '';
  var mobileRegExp1 = new RegExp(/(android|bb\d+|meego).+mobile|avantgo|bada\/|blackberry|blazer|compal|elaine|fennec|hiptop|iemobile|ip(hone|od|ad)|iris|kindle|silk|lge |maemo|midp|mmp|mobile.+firefox|netfront|opera m(ob|in)i|palm( os)?|phone|p(ixi|re)\/|plucker|pocket|psp|series(4|6)0|symbian|treo|up\.(browser|link)|vodafone|wap|windows ce|xda|xiino/i);
  var mobileRegExp2 = new RegExp(/1207|6310|6590|3gso|4thp|50[1-6]i|770s|802s|a wa|abac|ac(er|oo|s\-)|ai(ko|rn)|al(av|ca|co)|amoi|an(ex|ny|yw)|aptu|ar(ch|go)|as(te|us)|attw|au(di|\-m|r |s )|avan|be(ck|ll|nq)|bi(lb|rd)|bl(ac|az)|br(e|v)w|bumb|bw\-(n|u)|c55\/|capi|ccwa|cdm\-|cell|chtm|cldc|cmd\-|co(mp|nd)|craw|da(it|ll|ng)|dbte|dc\-s|devi|dica|dmob|do(c|p)o|ds(12|\-d)|el(49|ai)|em(l2|ul)|er(ic|k0)|esl8|ez([4-7]0|os|wa|ze)|fetc|fly(\-|_)|g1 u|g560|gene|gf\-5|g\-mo|go(\.w|od)|gr(ad|un)|haie|hcit|hd\-(m|p|t)|hei\-|hi(pt|ta)|hp( i|ip)|hs\-c|ht(c(\-| |_|a|g|p|s|t)|tp)|hu(aw|tc)|i\-(20|go|ma)|i230|iac( |\-|\/)|ibro|idea|ig01|ikom|im1k|inno|ipaq|iris|ja(t|v)a|jbro|jemu|jigs|kddi|keji|kgt( |\/)|klon|kpt |kwc\-|kyo(c|k)|le(no|xi)|lg( g|\/(k|l|u)|50|54|\-[a-w])|libw|lynx|m1\-w|m3ga|m50\/|ma(te|ui|xo)|mc(01|21|ca)|m\-cr|me(rc|ri)|mi(o8|oa|ts)|mmef|mo(01|02|bi|de|do|t(\-| |o|v)|zz)|mt(50|p1|v )|mwbp|mywa|n10[0-2]|n20[2-3]|n30(0|2)|n50(0|2|5)|n7(0(0|1)|10)|ne((c|m)\-|on|tf|wf|wg|wt)|nok(6|i)|nzph|o2im|op(ti|wv)|oran|owg1|p800|pan(a|d|t)|pdxg|pg(13|\-([1-8]|c))|phil|pire|pl(ay|uc)|pn\-2|po(ck|rt|se)|prox|psio|pt\-g|qa\-a|qc(07|12|21|32|60|\-[2-7]|i\-)|qtek|r380|r600|raks|rim9|ro(ve|zo)|s55\/|sa(ge|ma|mm|ms|ny|va)|sc(01|h\-|oo|p\-)|sdk\/|se(c(\-|0|1)|47|mc|nd|ri)|sgh\-|shar|sie(\-|m)|sk\-0|sl(45|id)|sm(al|ar|b3|it|t5)|so(ft|ny)|sp(01|h\-|v\-|v )|sy(01|mb)|t2(18|50)|t6(00|10|18)|ta(gt|lk)|tcl\-|tdg\-|tel(i|m)|tim\-|t\-mo|to(pl|sh)|ts(70|m\-|m3|m5)|tx\-9|up(\.b|g1|si)|utst|v400|v750|veri|vi(rg|te)|vk(40|5[0-3]|\-v)|vm40|voda|vulc|vx(52|53|60|61|70|80|81|83|85|98)|w3c(\-| )|webc|whit|wi(g |nc|nw)|wmlb|wonu|x700|yas\-|your|zeto|zte\-/i);
  return !!(mobileRegExp1.test(userAgent) || mobileRegExp2.test(userAgent.substr(0, 4)));
};
vivocha.canShareDOM = function () {
  // TODO TODO TODO check cobrowsing capabilities like canvas
  return true;
};
vivocha.probeBaseCaps = function () {
  var caps = {
    Media: {},
    Mobile: vivocha.isMobile(),
    CoBrowsing: vivocha.canShareDOM()
  };
  return caps;
};
vivocha.flushReadyHandlers = function () {
  if (window.vvc_ready_handlers) {
    var h;
    while (h = window.vvc_ready_handlers.shift()) {
      vivocha.ready(h);
    }
    delete window.vvc_ready_handlers;
  }
};


//////////////////
// WEBPACK FOOTER
// ./src/lib/vivocha.js
// module id = 18
// module chunks = 9 10 11 12 13 14 15 16 17