

/*--------------------------------------------------------------------------
 //scr/jscript/util.js
--------------------------------------------------------------------------*/
if (!Array.slice)
{
  Array.slice = function(object)
  {
    var slice = Array.prototype.slice;
    return slice.apply(object, slice.call(arguments, 1));
  }
}

var Util =
{
  selectOpt: function(selectEl, valueToSelect)
  {
    for (var i = 0; i < selectEl.options.length; i++)
    {
      if (selectEl.options[i].value == valueToSelect)
      {
        selectEl.selectedIndex = i;
        return i;
      }
    }

    return false;
  }
};


/*-----------------------------------------------------------------------------------
 Klasse für eigene Events
-----------------------------------------------------------------------------------*/

/**
*
* @constructor
* @class
*/
var Observable = function()
{
  /**
   * The DOM id of the selection
   * @memberOf Observable
   * @type {Array}
   */
  this._observers = {};
}

Observable.prototype =
{
  /**
   *
   * @method
   * @memberOf Observable
   */
  observe: function(evtName, observer)
  {
    if (typeof evtName == "string" && typeof observer == "function")
    {
      this._observers[evtName] = this._observers[evtName] || [];

      if(this._observers[evtName].indexOf(observer) == -1)
      {
        this._observers[evtName].push(observer);
      }
    }
  },

  /**
   *
   * @method
   * @memberOf Observable
   */
  stopObserve: function(evtName, observer)
  {
    if (typeof evtName == "string" && typeof this._observers[evtName] != "undefined")
    {
      if (typeof observer == "function")
      {
        for (var i = 0; i < this._observers[evtName].length; i++)
        {
          if (this._observers[evtName][i] === observer)
          {
            this._observers[evtName].splice(i, 1);
            return true;
          }
        }
      }
      else
      {
        this._observers[evtName] = [];
      }

      return true;
    }
  },

  /**
   *
   * @method
   * @memberOf Observable
   */
  fireEvent: function(evtName)
  {
    if (typeof evtName == "string" && typeof this._observers[evtName] != "undefined")
    {
      var args = Array.slice(arguments, 1);

      for (var i = 0; i < this._observers[evtName].length; i++)
      {
        this._observers[evtName][i].apply(this._observers[evtName][i], args);
      }
    }
  }
}

/*-----------------------------------------------------------------------------------
 Erweitern von JavaScript eigenen, vordefinierten Objekten
-----------------------------------------------------------------------------------*/

/**
 * Ändert den scope der Funktion d.h. beim Ausführen der Funktion zeigt 'this' auf das angegebene Objekt.
 * @param {Object} Der neue scope der Funktion
 * @param ... Zusätzliche Parameter, die an die Funktion übergeben werden sollen
 * @return {Function}
 */
Function.prototype.tie = function()
{
  var fn = this, args = Array.slice(arguments, 0), obj = args.shift();

  var h = function()
  {
    return fn.apply(obj || fn, Array.slice(arguments, 0).concat(args));
  };

  return h;
}

/**
 * Gleiche Funktionsweise wie bei 'tie' nur speziell für event listener.
 * An den listener wird als zweiter Paramter außerdem das DOM objekt übergeben, an welches der listener gebunden ist ('this' wird ja überschrieben).
 * @param {Object} Der neue scope der Funktion
 * @param ... Zusätzliche Parameter, die an die Funktion übergeben werden sollen
 * @return {Function}
 */
Function.prototype.evt = function()
{
  var fn = this, args = Array.slice(arguments, 0), obj = args.shift();

  var h = function()
  {
    return fn.apply(obj || this, Array.slice(arguments, 0).concat(this, args));
  };

  return h;
}

/**
 * Führt die Funktion um die von Timeout angegebene Zeitspanne verspätet aus.
 * @param {Object} Timeout in Millisekunden (1000ms = 1s)
 * @param ... Zusätzliche Parameter, die an die Funktion übergeben werden sollen
 * @return {Function}
 */
Function.prototype.delay = function()
{
  var fn = this, args = Array.slice(arguments, 0), timeout = args.shift();

  var h = window.setTimeout(function()
  {
    return fn.apply(fn, Array.slice(arguments, 0).concat(args));
  }, timeout);

  return h;
};
