/*!
 * jQuery.EventSource (jQuery.eventsource)
 *
 * Copyright (c) 2011 Rick Waldron
 * Dual licensed under the MIT and GPL licenses.
 */
!function(jQuery, global) {
  jQuery.extend(jQuery.ajaxSettings.accepts, {
    stream: "text/event-stream"
  });
  var stream = {
    defaults: {
      label: null,
      url: null,
      open: jQuery.noop,
      error: jQuery.noop,
      message: jQuery.noop
    },
    setup: {
      stream: {},
      lastEventId: 0,
      isHostApi: !1,
      retry: 500,
      options: {}
    },
    cache: {}
  }, pluginFns = {
    "public": {
      close: function(label) {
        var tmp = {};
        if (!label || "*" === label) {
          for (var prop in stream.cache) stream.cache[prop].isHostApi && stream.cache[prop].stream.close();
          return stream.cache = {}, stream.cache;
        }
        for (var prop in stream.cache) label !== prop ? tmp[prop] = stream.cache[prop] : stream.cache[prop].isHostApi ? stream.cache[prop].stream.close() : stream.cache[prop].isClosed = !0;
        return stream.cache = tmp, stream.cache;
      },
      removeEventListener: function(label, evtType) {
        if (!label || "*" === label) {
          for (var prop in stream.cache) stream.cache[prop].isHostApi ? stream.cache[prop].stream.removeEventListener(evtType, stream.cache[prop][evtType + "Callback"]) : stream.cache[prop].options[evtType] = $.noop;
          return !0;
        }
        for (var prop in stream.cache) label == prop && (stream.cache[prop].isHostApi ? (stream.cache[prop].stream.removeEventListener(evtType, stream.cache[prop][evtType + "Callback"]),
        stream.cache[prop].options[evtType + "Callback"] = jQuery.noop) : stream.cache[prop].options[evtType] = $.noop);
        return !0;
      },
      addEventListener: function(label, evtType, callback) {
        if (stream.cache[label][evtType + "Callback"] = function(event) {
          var streamData = [];
          stream.cache[label] && (this.label = label, "message" === evtType ? (streamData[streamData.length] = JSON.parse(event.data),
          stream.cache[label].lastEventId = +event.lastEventId, callback.call(this, streamData[0] ? streamData[0] : null, {
            data: streamData,
            lastEventId: stream.cache[label].lastEventId
          }, event)) : callback.call(this, event));
        }, stream.cache[label].options[evtType + "Callback"] = callback, !label || "*" === label) {
          for (var prop in stream.cache) stream.cache[prop].isHostApi ? stream.cache[prop].stream.addEventListener(evtType, stream.cache[prop][evtType + "Callback"], !1) : (stream.cache[prop].options[evtType] = $.noop,
          stream.cache[prop].options[evtType] = callback);
          return !0;
        }
        for (var prop in stream.cache) label == prop && (stream.cache[prop].isHostApi ? stream.cache[prop].stream.addEventListener(evtType, stream.cache[label][evtType + "Callback"], !1) : (stream.cache[prop].options[evtType] = $.noop,
        stream.cache[prop].options[evtType] = callback));
        return !0;
      },
      streams: function(label) {
        return label && "*" !== label ? stream.cache[label] || {} : stream.cache;
      }
    },
    _private: {
      openEventSource: function(options) {
        var label = options.label;
        return stream.cache[label].openCallback = function(event) {
          stream.cache[label] && (this.label = label, stream.cache[label].options.open.call(this, event));
        }, stream.cache[label].errorCallback = function(event) {
          stream.cache[label] && (this.label = label, stream.cache[label].options.error.call(this, event));
        }, stream.cache[label].messageCallback = function(event) {
          var streamData = [];
          stream.cache[label] && (streamData[streamData.length] = JSON.parse(event.data),
          this.label = label, stream.cache[label].lastEventId = +event.lastEventId, stream.cache[label].options.message.call(this, streamData[0] ? streamData[0] : null, {
            data: streamData,
            lastEventId: stream.cache[label].lastEventId
          }, event));
        }, stream.cache[label].stream.addEventListener("open", stream.cache[label].openCallback, !1),
        stream.cache[label].stream.addEventListener("error", stream.cache[label].errorCallback, !1),
        stream.cache[label].stream.addEventListener("message", stream.cache[label].messageCallback, !1),
        stream.cache[label].stream;
      },
      openPollingSource: function(options) {
        var source, label = options.label;
        if (stream.cache[label]) {
          if (stream.cache[label].isClosed) return void stream.cache[label].options.error.call(this, {
            eventPhase: 2,
            type: "error",
            data: "readyState:closed"
          });
          source = jQuery.ajax({
            type: "GET",
            url: options.url,
            data: options.data,
            beforeSend: function(xhr) {
              stream.cache[label] && (this.label = label, stream.cache[label].options.open.call(this)),
              xhr.setRequestHeader("Last-Event-ID", stream.cache[label].lastEventId);
            },
            success: function(data) {
              var tempdata, retries, label = options.label, streamData = jQuery.map(data.split("\n\n"), function(sdata, i) {
                return !!sdata && sdata;
              }), idx = 0, length = streamData.length, reTrim = /^(\s|\u00A0)+|(\s|\u00A0)+$/g;
              if (Array.isArray(streamData)) for (;length > idx; idx++) if (streamData[idx]) {
                for (var parts = streamData[idx].split("\n"), eventType = "message", data = [], i = 0, line = ""; i < parts.length; i++) if (line = parts[i].replace(reTrim, ""),
                0 == line.indexOf("event")) eventType = line.replace(/event:?\s*/, ""); else if (0 == line.indexOf("retry")) retries = parseInt(line.replace(/retry:?\s*/, "")),
                !isNaN(retries) && stream.cache[label] && (stream.cache[label].retry = stream.cache[label].options.retry = retries); else if (0 == line.indexOf("data")) data.push(line.replace(/data:?\s*/, "")); else if (0 == line.indexOf("id:")) {
                  var lastEventId = line.replace(/id:?\s*/, "");
                  !isNaN(lastEventId) && stream.cache[label] && (stream.cache[label].lastEventId = +lastEventId);
                } else 0 == line.indexOf("id") && stream.cache[label] && (stream.cache[label].lastEventId = null);
                if (tempdata = data.join(""), tempdata.length > 0 && stream.cache[label]) if ("json" === options.dataType) try {
                  tempdata = JSON.parse(tempdata), stream.cache[label].options.message.call(this, tempdata, {
                    data: tempdata,
                    lastEventId: stream.cache[label].lastEventId
                  });
                } catch (e) {
                  stream.cache[label].options.error.call(this, {
                    eventPhase: 0,
                    type: "error",
                    data: {
                      errorThrown: e.message
                    }
                  });
                } else stream.cache[label].options.message.call(this, tempdata, {
                  data: tempdata,
                  lastEventId: stream.cache[label].lastEventId
                });
              }
              stream.cache[label] && (this.label = label, setTimeout(function() {
                pluginFns._private.openPollingSource.call(this, options);
              }, stream.cache[label] && stream.cache[label].retry || 4e3));
            },
            error: function(jqXHR, textStatus, errorThrown) {
              if (stream.cache[label] && stream.cache[label].options.error.call(this, {
                eventPhase: 2,
                type: "error",
                data: {
                  readyState: jqXHR.readyState,
                  textStatus: textStatus,
                  errorThrown: errorThrown
                }
              }), 403 === jqXHR.status && jqXHR.responseText.indexOf("JS_ERR_LOST_SESSION") > -1) try {
                iLOGlobal.topPage.doLogout({
                  langKey: "login.sessionExp",
                  text: "Session expired."
                }, 0);
              } catch (e) {} else setTimeout(function() {
                pluginFns._private.openPollingSource.call(this, options);
              }, stream.cache[label] && stream.cache[label].retry || 4e3);
            },
            complete: function(jqXHR, textStatus) {
              stream.cache[label] && stream.cache[label].options.error.call(this, {
                eventPhase: 0,
                type: "error",
                data: {
                  readyState: jqXHR.readyState,
                  textStatus: textStatus
                }
              });
            },
            cache: !1,
            timeout: 5e4
          });
        }
        return source;
      }
    }
  }, isHostApi = global.EventSource ? !0 : !1;
  jQuery.eventsource = function(options) {
    var streamType, opts;
    if (options && !jQuery.isPlainObject(options) && pluginFns["public"][options]) return pluginFns["public"][options](arguments[1] ? arguments[1] : "*", arguments[2], arguments[3]);
    if (options.data = options.data && jQuery.isPlainObject(options.data) ? jQuery.param(options.data) : options.data,
    !options.url || "string" != typeof options.url) throw new SyntaxError("Not enough arguments: Must provide a url");
    return options.label = options.label ? options.label : options.url + "?" + options.data,
    opts = jQuery.extend({}, stream.defaults, options), stream.cache[opts.label] = {
      options: opts
    }, streamType = isHostApi ? new EventSource(opts.url + (opts.data ? "?" + opts.data : "")) : pluginFns._private.openPollingSource(opts),
    stream.cache[opts.label] = jQuery.extend({}, stream.setup, {
      stream: streamType,
      isHostApi: isHostApi,
      options: opts
    }), isHostApi && pluginFns._private.openEventSource(opts), stream.cache;
  }, jQuery.each([ "close", "streams", "addEventListener", "removeEventListener" ], function(idx, name) {
    jQuery.eventsource[name] = function(arg) {
      return jQuery.eventsource(name, arg || "*");
    };
  });
}(jQuery, window);