// $Id: zpeventdriven.js 4322 2006-09-04 08:49:33Z shacka $
/**
 * @fileoverview southprojects EventDriven library. Base EventDriven class. Contains
 * functions to handle events and basic methods for event-driven class.
 *
 * <pre>
 * Copyright (c) 2006 by SouthProjects
 * http://www.southprojects.com
 * Santiago, Chile,
 * Version 1.2 Dec 2006.
 * All rights reserved.
 * </pre>
 */

if (typeof southprojects == 'undefined') {
  /**
   * @ignore Namespace definition.
   */
  southprojects = {};
}

/**
 * Base event-driven class.
 *
 * @constructor
 */
southprojects.EventDriven = function() {};

/**
 * Initializes object.
 */
southprojects.EventDriven.prototype.init = function() {
  // Holds events of this object
  this.events = {};
};

/**
 * Adds event listener.
 *
 * @param {string} strEvent Event name
 * @param {function} funcListener Event listener
 * @param {function} first If true funcListener will be put as the first one
 */
southprojects.EventDriven.prototype.
 addEventListener = function(strEvent, funcListener, first) {
  if (typeof funcListener != "function") {
    return false;
  }
  if (!this.events[strEvent]) {
    this.events[strEvent] = {
      listeners: []
    };
  }
  if (!first) {
    this.events[strEvent].listeners.push(funcListener);
  } else {
    this.events[strEvent].listeners.unshift(funcListener);
  }
};

/**
 * Removes event listener.
 *
 * @param {string} strEvent Event name
 * @param {function} funcListener Event listener
 */
southprojects.EventDriven.prototype.
 removeEventListener = function(strEvent, funcListener) {
  if (!this.events[strEvent]) {
    return;
  }
  var arrListeners = this.events[strEvent].listeners;
  for (var iListener = 0; iListener < arrListeners.length; iListener++) {
    if (arrListeners[iListener] == funcListener) {
      arrListeners.splice(iListener, 1);
      return;
    }
  }
};

/**
 * Checks if the event exists.
 *
 * @param {string} strEvent Event name
 * @return Exists
 * @type boolean
 */
southprojects.EventDriven.prototype.isEvent = function(strEvent) {
  if (this.events[strEvent]) {
    return true;
  }
  return false;
};

/**
 * Removes all listeners for the event.
 *
 * @param {string} strEvent Event name
 */
southprojects.EventDriven.prototype.removeEvent = function(strEvent) {
  if (this.events[strEvent]) {
    var undef;
    this.events[strEvent] = undef;
  }
};

/**
 * Fires event. Takes in one mandatory argument strEvent and optionally
 * any number of other arguments that should be passed to the listeners.
 *
 * @param {string} strEvent Event name
 */
southprojects.EventDriven.prototype.fireEvent = function(strEvent) {
  if (!this.events[strEvent]) {
    return;
  }
  var arrListeners = this.events[strEvent].listeners;
  for (var iListener = 0; iListener < arrListeners.length; iListener++) {
    // Remove first argument
    var arrArgs = [].slice.call(arguments, 1);
    // Call in scope of this object
    arrListeners[iListener].apply(this, arrArgs);
  }
};

/**
 * Holds static events.
 * @private
 */
southprojects.EventDriven.events = {};

/**
 * Adds event listener to static event.
 *
 * @param {string} strEvent Event name
 * @param {function} funcListener Event listener
 */
southprojects.EventDriven.addEventListener = function(strEvent, funcListener) {
  if (typeof funcListener != "function") {
    return false;
  }
  if (!southprojects.EventDriven.events[strEvent]) {
    southprojects.EventDriven.events[strEvent] = {
      listeners: []
    };
  }
  southprojects.EventDriven.events[strEvent].listeners.push(funcListener);
};

/**
 * Removes event listener from static event.
 *
 * @param {string} strEvent Event name
 * @param {function} funcListener Event listener
 */
southprojects.EventDriven.removeEventListener = function(strEvent, funcListener) {
  if (!southprojects.EventDriven.events[strEvent]) {
    return;
  }
  var arrListeners = southprojects.EventDriven.events[strEvent].listeners;
  for (var iListener = 0; iListener < arrListeners.length; iListener++) {
    if (arrListeners[iListener] == funcListener) {
      arrListeners.splice(iListener, 1);
      return;
    }
  }
};

/**
 * Checks if the static event exists.
 *
 * @param {string} strEvent Event name
 * @return Exists
 * @type boolean
 */
southprojects.EventDriven.isEvent = function(strEvent) {
  if (southprojects.EventDriven.events[strEvent]) {
    return true;
  }
  return false;
};

/**
 * Removes all listeners for the static event.
 *
 * @param {string} strEvent Event name
 */
southprojects.EventDriven.removeEvent = function(strEvent) {
  if (southprojects.EventDriven.events[strEvent]) {
    var undef;
    southprojects.EventDriven.events[strEvent] = undef;
  }
};

/**
 * Fires static event. Takes in one mandatory argument strEvent and optionally
 * any number of other arguments that should be passed to the listeners.
 *
 * @param {string} strEvent Event name
 */
southprojects.EventDriven.fireEvent = function(strEvent) {
  if (!southprojects.EventDriven.events[strEvent]) {
    return;
  }
  var arrListeners = southprojects.EventDriven.events[strEvent].listeners;
  for (var iListener = 0; iListener < arrListeners.length; iListener++) {
    // Remove first argument
    var arrArgs = [].slice.call(arguments, 1);
    // Call listener
    arrListeners[iListener].apply(arrListeners[iListener], arrArgs);
  }
};
