//------------------------------------------------------------------------------
// File: Picket.cs
// This file is responsible for implementing the picketing state of protesting
// Author: Matthew Rudge
//------------------------------------------------------------------------------

////////////////////////////////////////////////////////////////////////////////
//! Called when the picket state is entered
//! \param %cmpAI AI component
////////////////////////////////////////////////////////////////////////////////
function AISMN_Picket::OnEnter(%this, %cmpAI)
{
   // Pick an initial direction to move
   %direction = PickDirection();
   
   // Store direction
   SetStringVariable(%cmpAI, "direction", %direction);
   
   // Start moving
   PicketWalk(%cmpAI, %cmpAI.getDataBlock().protestWalkRange / 2);
   
   return;
}

////////////////////////////////////////////////////////////////////////////////
//! Called when the picket state is exited
//! \param %cmpAI AI component
////////////////////////////////////////////////////////////////////////////////
function AISMN_Picket::OnExit(%this, %cmpAI)
{
   // Stop an protest animations
   %object = GetThisObject(%cmpAI);
   %cmpChar = slgQueryInterface(%object, $CID_CHARACTER);
   if(%cmpChar.isPlayingProtestAnimation()) {
      %cmpChar.stopProtestAnimation();
   }
   
   // If not performing any actions and not reacting then
   if(!%cmpAI.numActionsQueued() && !%cmpAI.isReacting()) {
      // If following a path from behavior then stop
      if(IsFollowingPath(%cmpAI)) {
         StopMoving(%cmpAI);
         %object.playThread(0, "root");
      }
   }
   
   %bWorkProtest = %cmpChar.isProtestingWork();
   %bHomeProtest = %cmpChar.isProtestingHome();
   %bDrunk       = %cmpChar.inState($CharacterState::Drunk);
   
   // No longer protesting
   // This needs to be like this because the picket OnEnd is called
   // prematurely if a unit is given any action. If a unit is told to move, we
   // don't want them to stop protesting. If a unit is told to employ somewhere,
   // however, we do want thm to stop protesting. Note that this was originally
   // located in a "PicketEnd" state node comparable to the "PicketBegin" state 
   // node, but due to the premature ending of this state, that node was never
   // called and the state tracker was reset, forcing a restart of the picketing
   // state
   if(%bWorkProtest) {
      if(%cmpChar.hasWork() || %bDrunk) {
         %cmpChar.endProtestingWork();
         if(!%bDrunk) {
            %cmpChar.mountProtestSign(false);
         }
      }
   }
   if(%bHomeProtest) {
      if(%cmpChar.hasHome() || %bDrunk) {
         %cmpChar.endProtestingHome();
         if(!%bDrunk) {
            %cmpChar.mountProtestSign(false);
         }
      }
   }
   
   return;
}

////////////////////////////////////////////////////////////////////////////////
//! Called every update for the picket state
//! \param %cmpAI AI component
////////////////////////////////////////////////////////////////////////////////
function AISMN_Picket::Update(%this, %cmpAI)
{
   %object    = GetThisObject(%cmpAI);
   %datablock = %cmpAI.getDataBlock();
   %cmpChar   = slgQueryInterface(%object, $CID_CHARACTER);
   
   if(%cmpChar.isProtestingHome() && %cmpChar.hasHome()) {
      // No need to protest anymore
      if(!%cmpChar.isProtestingWork()) {
         ReturnValue(%cmpAI, 0);
         return;
      }

      // Stop protesting home and continue protesting work
      else {
         %cmpChar.endProtestingHome();
      }      
   }
   
   if(%cmpChar.isProtestingWork() && %cmpChar.hasWork()) {
      // No need to protest anymore
      if(!%cmpChar.isProtestingHome()) {
         ReturnValue(%cmpAI, 0);
         return;
      }
      
      // Stop protesting work and continue protesting home
      else {
         %cmpChar.endProtestingWork();
      }
   }
   
   // If drunk then protesting ends
   if(%cmpChar.inState($CharacterState::Drunk)) {
      ReturnValue(%cmpAI, 0);
      return;
   }
   
   // If not playing a protest animation then
   if(!%cmpChar.isPlayingProtestAnimation()) {
      // Check if we reached time to test animation play
      %animstarttime = GetStringVariable(%cmpAI, "animtime");
      %currtime = TimeInNode(%cmpAI) - %animstarttime;
      if(%currtime >= %datablock.protestAnimTime) {
         // Check chance
         %num = RandomNumber(0, 100);
         if(%num < %datablock.protestAnimPercent) {
            // If following a path, stop
            if(IsFollowingPath(%cmpAI)) {
               StopMoving(%cmpAI);
               %object.playThread(0, "root");
            }

            // Play animation
            %cmpChar.playProtestAnimation();
         }
         SetStringVariable(%cmpAI, "animtime", TimeInNode(%cmpAI));
      }
      
      // If we have reached our destination then
      else if(!IsFollowingPath(%cmpAI)) {
         // Get time to idle
         %idletime = GetStringVariable(%cmpAI, "idletime");
         
         // Check elapsed time
         %starttime = GetStringVariable(%cmpAI, "starttime");
         if(%starttime <= 0) {
            // Reset start time
            %starttime = TimeInNode(%cmpAI);
            SetStringVariable(%cmpAI, "starttime", %starttime);
            
            // Reset destination
            SetStringVariable(%cmpAI, "destx", 0);
            SetStringVariable(%cmpAI, "desty", 0);
            
            // Stop moving
            %object.playThread(0, "root");
         }
         %currtime = TimeInNode(%cmpAI) - %starttime;
         
         // If done idling then start in new direction
         if(%currtime >= %idletime) {
            PicketWalk(%cmpAI, %datablock.protestWalkRange);
         }
      }
   }

   // Stay in state
   ReturnValue(%cmpAI, -1);
   return;
}

////////////////////////////////////////////////////////////////////////////////
//! Picks a direction to walk while protesting
////////////////////////////////////////////////////////////////////////////////
function PickDirection(%this)
{
   // Get random direction
   %direction = 1;
   if(getRandom(1)) {
     %direction = -%direction;
   }
      
   // Return new direction
   return %direction;
}

////////////////////////////////////////////////////////////////////////////////
//! Starts picket walking to the left or right, depending on last direction
//! \param %cmpAI AI component object
//! \param %range Range to walk
////////////////////////////////////////////////////////////////////////////////
function PicketWalk(%cmpAI, %range)
{
   // Use direction to set a path to our walk range
   %object    = GetThisObject(%cmpAI);
   %datablock = %cmpAI.getDataBlock();
   %direction = GetStringVariable(%cmpAI, "direction");
   
   %cpos   = %object.getPosition();
   %destx  = getWord(%cpos, 0) + %direction * %range;
   %desty  = getWord(%cpos, 1);
   SetPathToSpot(%cmpAI, %destx, %desty);
   SetStringVariable(%cmpAI, "destx", %destx);
   SetStringVariable(%cmpAI, "desty", %desty);
   
   // Reset idle time and start time for next idle
   %idletime = getRandom(%datablock.protestIdleMinTime, %datablock.protestIdleMaxTime);
   SetStringVariable(%cmpAI, "idletime", %idletime);
   SetStringVariable(%cmpAI, "starttime", 0);
   
   // Set new direction for next path
   SetStringVariable(%cmpAI, "direction", -%direction);
   
   // Play animation
   %object.playThread(0, "run");
}

////////////////////////////////////////////////////////////////////////////////
//! Used to reset the time for picket animation and reset the walking animation
//! after a picket animation has ended
//! \param %cmpAI AI component object
////////////////////////////////////////////////////////////////////////////////
function CCmpAI::PicketResetAnimation(%cmpAI)
{
   // Stop the protest animation from "playing" on the server
   %object  = GetThisObject(%cmpAI);
   %cmpChar = slgQueryInterface(%object, $CID_CHARACTER);
   %cmpChar.stopProtestAnimation();
   
   // Start moving again
   %destx = GetStringVariable(%cmpAI, "destx");
   %desty = GetStringVariable(%cmpAI, "desty");
   %curpos = %object.getPosition();
   if(%destx != 0 && getWord(%curpos, 0) != %destx) {
      SetPathToSpot(%cmpAI, %destx, %desty);
      %object.playThread(0, "run");
   }
}

// End Picket.cs