// Initialize schedule manager
// This implements a schedule function placeholder that allows pausing and
// resuming of event scheduling
function initScheduleLCA()
{
   $ScheduleIDNum = 0;
   $PauseScheduleLCA = false;
}

// Call this method instead of the standard 'obj.schedule' in order to use the
// pause/resume features.
// Parameters are equal to standard schedule function, except for
// the second parameter (%classID) which is a value used to classify
// schedules in classes. This can be used to selectively pause classes of
// scheduled events, while keeping other classes running.
function scheduleObjLCA(%objID, %classID, %t, %functionName, %numArgs,
                        %a0, %a1, %a2, %a3, %a4, %a5, %a6, %a7, %a8, %a9)
{
   return scheduleCoreLCA(true, %classID, %t, %objID, %functionName, %numArgs,
      %a0, %a1, %a2, %a3, %a4, %a5, %a6, %a7, %a8, %a9);
}

// Call this method instead of the standard 'schedule' in order to use the
// pause/resume features.
// Parameters are equal to standard schedule function, except for
// the first parameter (%classID) which is a value used to classify
// schedules in classes. This can be used to selectively pause classes of
// scheduled events, while keeping other classes running.
function scheduleLCA(%classID, %t, %objID, %functionName, %numArgs,
                     %a0, %a1, %a2, %a3, %a4, %a5, %a6, %a7, %a8, %a9)
{
   return scheduleCoreLCA(false, %classID, %t, %objID, %functionName, %numArgs,
      %a0, %a1, %a2, %a3, %a4, %a5, %a6, %a7, %a8, %a9);
}

// Internal use only
function scheduleCoreLCA(%useObj, %classID, %t, %objID, %functionName, %numArgs, 
                         %a0, %a1, %a2, %a3, %a4, %a5, %a6, %a7, %a8, %a9)
{
   // Remove not pending schedules
   for(%i=0; %i<$ScheduleIDNum; %i++)
   {
      if(!isEventPending($ScheduleIDArray[%i]) && $ScheduleIDArray[%i,"paused"] <= 0)
         $ScheduleIDArray[%i] = "";
   }
   
   // Look for a free room in $ScheduleIDArray
   %freeIdx = -1;
   for(%i=0; %i<$ScheduleIDNum; %i++)
   {
      if(!$ScheduleIDArray[%i])
      {
         %freeIdx = %i;
         break;
      }
   }
   
   if(%freeIdx $= -1)
   {
      %freeIdx = $ScheduleIDNum;
      $ScheduleIDNum++;      
   }

   %text = "";
   if(%useObj)
   {
      %text = "$ScheduleIDArray[%freeIdx] = %objID.schedule(%t, %functionName";
      for(%j=0;%j<%numArgs;%j++) %text = %text @ ",%a" @ %j;
      %text = %text @ ");";
   }
   else
   {
      %text = "$ScheduleIDArray[%freeIdx] = schedule(%t, %objID, %functionName";
      for(%j=0;%j<%numArgs;%j++) %text = %text @ ",%a" @ %j;
      %text = %text @ ");";
   }
   eval(%text);

   $ScheduleIDArray[%freeIdx,"objID"]        = %objID;
   $ScheduleIDArray[%freeIdx,"functionName"] = %functionName;
   $ScheduleIDArray[%freeIdx,"numArgs"]      = %numArgs;   
   $ScheduleIDArray[%freeIdx,"arg0"]         = %a0;
   $ScheduleIDArray[%freeIdx,"arg1"]         = %a1;
   $ScheduleIDArray[%freeIdx,"arg2"]         = %a2;
   $ScheduleIDArray[%freeIdx,"arg3"]         = %a3;
   $ScheduleIDArray[%freeIdx,"arg4"]         = %a4;
   $ScheduleIDArray[%freeIdx,"arg5"]         = %a5;
   $ScheduleIDArray[%freeIdx,"arg6"]         = %a6;
   $ScheduleIDArray[%freeIdx,"arg7"]         = %a7;
   $ScheduleIDArray[%freeIdx,"arg8"]         = %a8;
   $ScheduleIDArray[%freeIdx,"arg9"]         = %a9;   
   $ScheduleIDArray[%freeIdx,"classID"]      = %classID;
   $ScheduleIDArray[%freeIdx,"paused"]       = 0;
   $ScheduleIDArray[%freeIdx,"useObj"]       = %useObj;
   
   return %freeIdx;
}

// Pause all events scheduled by the scheduleLCA function
// The %classID arguments are optional parameters containing classIDs
// that should be paused. If they are not passed, events with any classID
// are paused
function pauseSchedulesLCA(%classID0, %classID1, %classID2)
{
   %pauseAll = false;
   if(%classID0 $="" && %classID1 $="" && %classID2 $="")
      %pauseAll = true;
   
   for(%i=0; %i<$ScheduleIDNum; %i++)
   {
      %eventID = $ScheduleIDArray[%i];
      if(%eventID)
      {
         if(%pauseAll ||
            $ScheduleIDArray[%i,"classID"] $= %classID0 ||
            $ScheduleIDArray[%i,"classID"] $= %classID1 ||
            $ScheduleIDArray[%i,"classID"] $= %classID2)
         {
            if(isEventPending(%eventID))            
            {
               if($ScheduleIDArray[%i,"paused"] <= 0)
               {
                  $ScheduleIDArrayRem[%i] = getEventTimeLeft(%eventID);
                  cancel(%eventID);
               }
               $ScheduleIDArray[%i,"paused"]++;            
            }
         }
      }
   }
}

// Resume all events paused by the pauseSchedulesLCA function
function resumeSchedulesLCA(%classID)
{
   for(%i=0; %i<$ScheduleIDNum; %i++)
   {
      if (%classID !$= "" && $ScheduleIDArray[%i,"classID"] !$= %classID)
         continue;

      %eventID = $ScheduleIDArray[%i];
      
      if($ScheduleIDArray[%i,"paused"] > 0)
      {
         if($ScheduleIDArray[%i,"paused"] == 1)
         {
            %text = "";
            if($ScheduleIDArray[%i,"useObj"])
            {
               %text = "$ScheduleIDArray[%i] = $ScheduleIDArray[%i,\"objID\"].schedule("@
                  "$ScheduleIDArrayRem[%i],"@
                  "$ScheduleIDArray[%i,\"functionName\"]";
                  for(%j=0;%j<$ScheduleIDArray[%i,"numArgs"];%j++) 
                     %text = %text @ ",$ScheduleIDArray[%i,\"arg" @ %j @ "\"]";
                  %text = %text @ ");";
            }
            else
            {
               %text = "$ScheduleIDArray[%i] = schedule("@
                  "$ScheduleIDArrayRem[%i],"@
                  "$ScheduleIDArray[%i,\"objID\"],"@
                  "$ScheduleIDArray[%i,\"functionName\"]";
                  for(%j=0;%j<$ScheduleIDArray[%i,"numArgs"];%j++) 
                     %text = %text @ ",$ScheduleIDArray[%i,\"arg" @ %j @ "\"]";
                  %text = %text @ ");";               
            }
            eval(%text);
         }
         $ScheduleIDArray[%i,"paused"]--;
      }
   }
}

// Cancel all events scheduled by the scheduleLCA function
// The %classID arguments are optional parameters containing classIDs
// that should be cancelled. If they are not passed, events with any classID
// are cancelled
function cancelSchedulesLCA(%classID0, %classID1, %classID2)
{
   %cancelAll = false;
   
   if(%classID0 $="" && %classID1 $="" && %classID2 $="")
      %cancelAll = true;
   
   for(%i=0; %i<$ScheduleIDNum; %i++)
   {
      %eventID = $ScheduleIDArray[%i];
      if(%eventID)
      {
         if(%cancelAll ||
            $ScheduleIDArray[%i,"classID"] $= %classID0 ||
            $ScheduleIDArray[%i,"classID"] $= %classID1 ||
            $ScheduleIDArray[%i,"classID"] $= %classID2)
         {
            if(isEventPending(%eventID))
               cancel(%eventID);

            $ScheduleIDArray[%i] = "";            
         }
      }
   }
}

// Cancel an event scheduled by the scheduleLCA function
function cancelScheduleLCA(%i)
{
   %eventID = $ScheduleIDArray[%i];
   if(%eventID)
   {
      if(isEventPending(%eventID))
         cancel(%eventID);

      $ScheduleIDArray[%i] = "";
   }
}
