/*!
 * tiny-cookie - A tiny cookie manipulation plugin
 * https://github.com/Alex1990/tiny-cookie
 * Under the MIT license | (c) Alex Chao
 */

!(function(root, factory) {

  // Uses CommonJS, AMD or browser global to create a jQuery plugin.
  // See: https://github.com/umdjs/umd
  if (typeof define === 'function' && define.amd) {
    // Expose this plugin as an AMD module. Register an anonymous module.
    define(factory);
  } else if (typeof exports === 'object') {
    // Node/CommonJS module
    module.exports = factory();
  } else {
    // Browser globals 
    root.Cookie = factory();
  }

}(this, function() {

  'use strict';

  // The public function which can get/set/remove cookie.
  function Cookie(key, value, opts) {
    if (value === void 0) {
      return Cookie.get(key);
    } else if (value === null) {
      Cookie.remove(key);
    } else {
      Cookie.set(key, value, opts);
    }
  }

  // Check if the cookie is enabled.
  Cookie.enabled = function() {
    var key = '__test_key';
    var enabled;

    document.cookie = key + '=1';
    enabled = !!document.cookie;

    if (enabled) Cookie.remove(key);

    return enabled;
  };

  // Get the cookie value by the key.
  Cookie.get = function(key, raw) {
    if (typeof key !== 'string' || !key) return null;

    key = '(?:^|; )' + escapeRe(key) + '(?:=([^;]*?))?(?:;|$)';

    var reKey = new RegExp(key);
    var res = reKey.exec(document.cookie);

    return res !== null ? (raw ? res[1] : decodeURIComponent(res[1])) : null;
  };

  // Get the cookie's value without decoding.
  Cookie.getRaw = function(key) {
    return Cookie.get(key, true);
  };

  // Set a cookie.
  Cookie.set = function(key, value, raw, opts) {
    if (raw !== true) {
      opts = raw;
      raw = false;
    }
    opts = opts ? convert(opts) : convert({});
    var cookie = key + '=' + (raw ? value : encodeURIComponent(value)) + opts;
    document.cookie = cookie;
  };

  // Set a cookie without encoding the value.
  Cookie.setRaw = function(key, value, opts) {
    Cookie.set(key, value, true, opts);
  };

  // Remove a cookie by the specified key.
  Cookie.remove = function(key) {
    Cookie.set(key, 'a', { expires: new Date() });
  };

  // Helper function
  // ---------------

  // Escape special characters.
  function escapeRe(str) {
    return str.replace(/[.*+?^$|[\](){}\\-]/g, '\\$&');
  }

  // Convert an object to a cookie option string.
  function convert(opts) {
    var res = '';

    for (var p in opts) {
      if (opts.hasOwnProperty(p)) {

        if (p === 'expires') {
          var expires = opts[p];
          if (typeof expires !== 'object') {
            expires += typeof expires === 'number' ? 'D' : '';
            expires = computeExpires(expires);
          }
          opts[p] = expires.toUTCString();
        }

        if (p === 'secure') {
          if (opts[p]) {
            res += ';' + p;
          }

          continue;
        }

        res += ';' + p + '=' + opts[p];
      }
    }

    if (!opts.hasOwnProperty('path')) {
      res += ';path=/';
    }

    return res;
  }

  // Return a future date by the given string.
  function computeExpires(str) {
    var expires = new Date();
    var lastCh = str.charAt(str.length - 1);
    var value = parseInt(str, 10);

    switch (lastCh) {
      case 'Y': expires.setFullYear(expires.getFullYear() + value); break;
      case 'M': expires.setMonth(expires.getMonth() + value); break;
      case 'D': expires.setDate(expires.getDate() + value); break;
      case 'h': expires.setHours(expires.getHours() + value); break;
      case 'm': expires.setMinutes(expires.getMinutes() + value); break;
      case 's': expires.setSeconds(expires.getSeconds() + value); break;
      default: expires = new Date(str);
    }

    return expires;
  }

  return Cookie;

}));
