_              = require('lodash')
module.exports = (->

  has_re = _.memoize((key) ->
    new RegExp("(?:^|;\\s*)" + encodeURIComponent(key).replace(/[\-\.\+\*]/g, "\\$&") + "\\s*\\=")
  )
  forbidden_re = /^(?:expires|max\-age|path|domain|secure)$/

  get_clean_value: (name) ->
    value = '; ' + document.cookie
    parts = value.split('; ' + name + '=')
    if parts.length == 2
      parts.pop().split(';').shift()
    else
      null

  get: (key) ->
    value = @get_clean_value(key)
    return null if not value
    try
      decodeURIComponent(value)
    catch
      unescape(value)

  advanced_set: (key, value, end, path, domain, secure) ->
    return  if not key or forbidden_re.test(key)

    expires = ""
    if end
      switch typeof end
        when "number"
          expires = "; max-age=" + end
        when "string"
          if end is "unlimited"
            expires = "; expires=" + "Fri, 10 Jul 2099 13:05:42 UTC"
          else
            expires = "; expires=" + end
        when "object"
          expires = "; expires=" + end.toGMTString()  if end.hasOwnProperty("toGMTString")
    document.cookie = encodeURIComponent(key) + "=" + encodeURIComponent(value) + expires + ((if domain && domain != 'localhost' then "; domain=" + domain else "")) + ((if path then "; path=" + path else "")) + ((if secure then "; secure" else ""))
    return

  set: (key, value, end) ->
    if window.location.hostname == '127.0.0.1'
      domain = '127.0.0.1'
    else
      domain = window.location.hostname.split('.').slice(-2).join('.')
    @advanced_set(key, value, end, '/', domain, false)

  remove: (key) ->
    return  if not key or not @has(key)
    expire_date = new Date()
    expire_date.setDate expire_date.getDate() - 100
    document.cookie = encodeURIComponent(key) + "=; expires=" + expire_date.toGMTString() + "; path=/"
    return

  has: (key) ->
    has_re(key).test document.cookie

  object: (key) ->
    return  if not key or not @has(key)
    item = @get(key)
    new Function("return " + decodeURIComponent(item.replace(/\+/g, " ")))()
)()
