// ---------------------------------------------------------------------------
// (c) 2003 KystAtlas, Hans Martin Mohn
// ---------------------------------------------------------------------------
// Utility class to aid in connecting events.
//
// The gtWaitForAll class helps in the startup phase of an application where
// many frames and other elements are loaded asynchronously.
//
// gtWaitForAll can be set up to fire an event when a specific set of other
// events have ocurred.
//
// Dependencies:
gtAssert("gtEventHandler != null");
//
//
// Example:
//
//  Create a gtWaitForAll that raises an event to the event handler
//  imageAndPageHasLoaded() when both "imageLoaded" and "pageLoaded"
//  have been signalled.
//
//  In this example, the event handler should be declared as
//    handler = function(image, field)
//  in order to match the calls to setEventArguments() below!
//
//   wait = new gtWaitForAll(imageAndPageHasLoaded, "imageLoaded", "pageLoaded");
//                  :
//
// During page loading, gtWaitForAll should be signalled as the respective objects are loaded:
//
//   wait.setEventArgument(1, field);
//   wait.signal("pageLoaded");
//                  :
//   wait.setEventArgument(0, image);
//   wait.signal("imageLoaded");  // This will trigger the event
//                  :

function gtWaitForAll()
{
  this.superclass();
  var argno = 0;
  var me    = null;
  
  // If the first argument is an object, treat it as the this pointer for the handler function
  if (typeof arguments[argno] == "object")
    me = arguments[argno++];
    
  this.addHandler(arguments[argno++], me);

  this.m_conditions = [];
  for (var i = argno; i < arguments.length; i++)
    this.m_conditions.push(arguments[i]);
} // end gtWaitForAll()



// Connect to parent class
var GTWAITFORALL = gtWaitForAll.prototype = new gtEventHandler();
GTWAITFORALL.superclass = gtEventHandler;



// Add argument values that will be passed to the event handler function
GTWAITFORALL.setEventArgument = function gtWaitForAll_setEventArgument(index, value)
{
  if (this.m_args === null)
    this.m_args = new Array();
  this.m_args[index] = value;
}; // end setEventArgument()



GTWAITFORALL.signal = function gtWaitForAll_signal(name)
{
//top.gtTrace("Signal: " + name + "\n");
  for (var i = 0; i < this.m_conditions.length; i++)
  {
    if (this.m_conditions[i] == name)
    {
//top.gtTrace("Signal: " + name + " removed\n");
      this.m_conditions.splice(i, 1); // removes one condition at 'i'
      if (this.m_conditions.length === 0)
        this.fire();
      return true;
    }
  }
  return false; // Didn't find it!
}; // end signal()



// Just fire the event
GTWAITFORALL.fire = function gtWaitForAll_fire()
{
  if (this.m_args)
    this.raise(this.m_args[0], this.m_args[1], this.m_args[2], this.m_args[3], this.m_args[4], this.m_args[5], this.m_args[6], this.m_args[7], this.m_args[8], this.m_args[9]);
  else
    this.raise();
}; // end fire()



// Install a new set of conditions (all previous conditions are thrown away)
//   wait.reset("imageLoaded", "test"); // Event will trigger the next time both "imageLoaded" and "test" are signalled...
GTWAITFORALL.reset = function gtWaitForAll_reset()
{
  this.m_conditions = [];
  for (var i = 0; i < arguments.length; i++)
    this.m_conditions.push(arguments[i]);
}; // end reset()
