EventManager = {

  storage: new Array(),
  interval_storage: new Array(),
  suspendedEvents: new Array(),

  // Supported events and posibility to generate them
  windowLoad: false,
  windowUnLoad: false,
  bodyClick: false,

  wizardClosed: true,

  receivedAdServerURL: true,
  receivedAdStreamURL: true,
  receivedStreamURL: true,
  receivedMainFreeStreamURL: true,
  beforeTabActive: true,

  onPlayerStatusChanged: true,
  onPlayerClick: true,
  onMediaTypeChanged: true,

  addListener: function(event_name, object_pointer)
  {
    if (typeof eval("this." + event_name) != "boolean")
      return false;

    for (var i = 0; i < this.storage.length; i++) {
      if (this.storage[i]['name'] == event_name)
        if (this.storage[i]['object'] == object_pointer)
          return true;
    }

    new_index = this.storage.length;
    this.storage[new_index] = new Array();
    this.storage[new_index]['name'] = event_name;
    this.storage[new_index]['object'] = object_pointer;

    return true;
  },

  generate: function(event_name, custom_event_object)
  {
    if (typeof eval("this." + event_name) != "boolean" || eval("this." + event_name) != true)
      return false;

    var called_events = 0;

    for (var i = 0; i < this.storage.length; i++) {
      if (this.storage[i]['name'] != event_name)
        continue;

      var current_object = this.storage[i]['object'];
      EventManager.runEvent(current_object, event_name, custom_event_object, null);

      called_events++;
    }

    return called_events;
  },

  runEvent: function(current_object, event_name, custom_event_object, suspended_index)
  {
    var retval = eval("current_object." + event_name + "(custom_event_object)");
    EventManager.processResult(event_name, custom_event_object, current_object, retval, suspended_index);
  },

  processResult: function(event_name, custom_event_object, current_object, retval, suspended_index)
  {
    var is_suspended = (typeof suspended_index == "numeric") ? true : false;

    if (typeof(retval) == "undefined") {
      // Object skips this event because. All right
      if (is_suspended)
        this.suspendedEvents[suspended_index]['status'] = 'skipped';
    }
    else
      if (typeof(retval) == "boolean" && retval == true) {
        // Object processes this event successfully
        if (is_suspended)
          this.suspendedEvents[suspended_index]['status'] = 'done';
      }
      else
        if (typeof(retval) == "boolean" && retval == false) {
          // Object could not process this event. Looks like logic issue
          if (is_suspended)
            this.suspendedEvents[suspended_index]['status'] = 'failed';
        }
        else
          if (typeof(retval) == "number" && retval < 0) {
            // Object want to suspend this issue because data is not ready
            if (is_suspended) {
              var index = suspended_index;
            }
            else {
              var index = this.suspendedEvents.length;
              this.suspendedEvents[index] = new Array();
              this.suspendedEvents[index]['name'] = event_name;
              this.suspendedEvents[index]['object'] = current_object;
              this.suspendedEvents[index]['event_object'] = custom_event_object;
              this.suspendedEvents[index]['suspended_times'] = 0;
              this.suspendedEvents[index]['status'] = 'waiting';
            }

            var suspended_event = this.suspendedEvents[index];
            var timer = window.setTimeout("EventManager.runSuspendedEvent(" + index + ")", (-retval));
            suspended_event['timer'] = timer;
            suspended_event['suspended_times']++;
            suspended_event['interval'] = (-retval);
          }
  },

  runSuspendedEvent: function(index)
  {
    suspended_event = this.suspendedEvents[index];
    window.clearTimeout(suspended_event['timer']);

    if (suspended_event['status'] == 'waiting')
      EventManager.runEvent(suspended_event['object'], suspended_event['name'], suspended_event['event_object'], index);
  },


  cancelSuspendedEvent: function(event_name)
  {
    for (var i = 0; i < this.suspendedEvents.length; i++) {
      if (this.suspendedEvents[i]['name'] == event_name)
        this.suspendedEvents[i]['status'] = 'canceled';
    }
  },

  initInterval: function(object_pointer, method_name, milliseconds)
  {
    var new_index = null;

    for (var i = 0; i < this.interval_storage.length; i++) {
      if (this.interval_storage[i]['name'] == method_name)
        if (this.interval_storage[i]['object'] == object_pointer) {
          if (this.interval_storage[i]['interval'])
            return true;

          new_index = i;
          break;
        }
    }

    if (!new_index)
      new_index = this.interval_storage.length;
    this.interval_storage[new_index] = new Array();
    this.interval_storage[new_index]['name'] = method_name;
    this.interval_storage[new_index]['object'] = object_pointer;
    this.interval_storage[new_index]['interval'] = milliseconds;

    return new_index;
  },

  //! \brief Execute method each milliseconds time
  startInterval: function(object_pointer, method_name, milliseconds)
  {
    var index = this.initInterval(object_pointer, method_name, milliseconds);
    if (typeof index == "boolean")
      return index;
    this.interval_storage[index]['type'] = 'interval';
    this.interval_storage[index]['timerID'] = window.setInterval("EventManager.runInterval(" + index + ")", milliseconds);

    return true;
  },

  //! \brief Execute method each milliseconds time
  startTimeout: function(object_pointer, method_name, milliseconds)
  {
    var index = this.initInterval(object_pointer, method_name, milliseconds);
    if (typeof index == "boolean")
      return index;
    this.interval_storage[index]['type'] = 'once';
    this.interval_storage[index]['timerID'] = window.setTimeout("EventManager.runInterval(" + index + ")", milliseconds);

    return true;
  },

  stopInterval: function(object_pointer, method_name)
  {
    for (var i = 0; i < this.interval_storage.length; i++) {
      if (this.interval_storage[i]['name'] == method_name)
        if (this.interval_storage[i]['object'] == object_pointer) {
          if (!this.interval_storage[i]['interval'])
            return false;

          window.clearTimeout(this.interval_storage[i]['timerID']);
          this.interval_storage[i]['interval'] = 0;
          return true;
        }
    }

    return false;
  },

  runInterval: function(index)
  {
    var interval_data = this.interval_storage[index];

    var object_pointer = interval_data['object'];
    var method_name = interval_data['name'];
    var type = interval_data['type'];

    if (type == 'once') {
      interval_data['interval'] = 0;
      window.clearTimeout(interval_data['timerID']);
    }

    var retval = eval("object_pointer." + method_name + "()");

    return true;
  },

  // Add support window.onload
  generateWindowLoad: function()
  {
    this.windowLoad = true;
    EventManager.generate("windowLoad", {});
    this.windowLoad = false;
  },

  generateWindowUnLoad: function()
  {
    this.windowUnLoad = true;
    EventManager.generate("windowUnLoad", {});
    this.windowUnLoad = false;
  },

  generateBodyClick: function()
  {
    this.bodyClick = true;
    EventManager.generate("bodyClick", {});
    this.bodyClick = false;
  }
}
