//------------------------------------------------------------------------------
// File: client_cmdstates.cs
// This file is for the command system state callbacks
// Author: Matthew Rudge
//------------------------------------------------------------------------------

//-Wait State-------------------------------------------------------------------
////////////////////////////////////////////////////////////////////////////////
//! Called when the command system's "Wait" state has been entered
////////////////////////////////////////////////////////////////////////////////
function Wait::onEnter(%this)
{

}

////////////////////////////////////////////////////////////////////////////////
//! Called when the command system's "Wait" state has been exited
////////////////////////////////////////////////////////////////////////////////
function Wait::onExit(%this)
{

}

////////////////////////////////////////////////////////////////////////////////
//! Called when the command system's "Wait" state is running
////////////////////////////////////////////////////////////////////////////////
function Wait::onUpdate(%this)
{   
   // If anyone is selected then go to select state
   if(CmdStateTracker.hasSelection()) {
      return $CSWI_SELECT;
   }
   else {
      return $CSWI_WAIT;
   }
}
//------------------------------------------------------------------------------

//-Select State-----------------------------------------------------------------
////////////////////////////////////////////////////////////////////////////////
//! Called when the command system's "Select" state has been entered
////////////////////////////////////////////////////////////////////////////////
function Select::onEnter(%this)
{
   
}

////////////////////////////////////////////////////////////////////////////////
//! Called when the command system's "Select" state has been exited
////////////////////////////////////////////////////////////////////////////////
function Select::onExit(%this)
{
   
}

////////////////////////////////////////////////////////////////////////////////
//! Called when the command system's "Select" state is running
////////////////////////////////////////////////////////////////////////////////
function Select::onUpdate(%this)
{
   // If nothing is selected then go back to the wait state
   if(!CmdStateTracker.hasSelection()) {
      return $CSSI_WAIT;
   }
   
   // If dragging, go to the drag state
   if($CS_STARTDRAG) {
      return $CSSI_DRAG;
   }
   
   // If a command has been decided
   else if(CmdStateTracker.hasCommand()) {
      // If a target has been decided then go to execute state
      if(CmdStateTracker.hasTarget()) {
         return $CSSI_EXECUTE;
      }
      
      // Otherwise go to target state
      else {
         return $CSSI_TARGET;
      }
   }
   
   // Remaining in select state
   else {
      // Button was clicked and command was issued
      if($CSC_ISSUED != $CSC_NONE) {
         CmdStateTracker.setCommand($CSC_ISSUED);
         $CSC_ISSUED = $CSC_NONE;
      }
      
      // Chose a new target and command
      else if($CSC_RGHTBTN) {
         CmdStateTracker.updateTargetAndCmd();
         $CSC_RGHTBTN = false;
      }
      
      return $CSSI_SELECT;
   }
}
//------------------------------------------------------------------------------

//-Drag State-------------------------------------------------------------------
////////////////////////////////////////////////////////////////////////////////
//! Called when the command system's "Drag" state has been entered
////////////////////////////////////////////////////////////////////////////////
function Drag::onEnter(%this)
{   
   // Clear drag state variables
   $CS_STARTDRAG = false;
   $CS_ENDDRAG   = false;
   
   // Create drag group
   csCreateDragGroup();
   
   // Get dragged object
   %drg = getDraggedObject();
   
   // Set dragged object
   csSetDragStart(%drg);
}

////////////////////////////////////////////////////////////////////////////////
//! Called when the command system's "Drag" state has been exited
////////////////////////////////////////////////////////////////////////////////
function Drag::onExit(%this)
{
   // Clear drag state variables
   $CS_ENDDRAG   = false;
      
   // Reset cursor
   csUpdateCursor($CSC_NONE);
   
   // Destroy drag group
   csDestroyDragGroup();
}

////////////////////////////////////////////////////////////////////////////////
//! Called when the command system's "Drag" state is running
////////////////////////////////////////////////////////////////////////////////
function Drag::onUpdate(%this)
{
   // Forcefully exiting drag state
   if($CS_ENDDRAG) {
      return $CSDI_SELECT;
   }
   
   // Update target and command (not only when the mouse moves since game 
   // objects can move as well)
   CmdStateTracker.updateTargetAndCmd();
   
   // Update cursor
   csUpdateCursor(CmdStateTracker.getCommand());
   
   // If mouse button has been released then
   if(!$mouseLButtonDown) {
      
      // Execute current command and target if there is one
      if(CmdStateTracker.hasCommand() && CmdStateTracker.hasTarget()) {
         return $CSDI_EXECUTE;
      }
      // Otherwise fall back to select state
      else {
         return $CSDI_SELECT;
      }
   }
   
   // Otherwise stay in drag state
   else {
      // We SHOULD have some target currently
      if(CmdStateTracker.hasTarget()) {
         %tgtPos = csGetDragTarget();
         
         // Update drag group
         csUpdateDragGroup(
            csGetDragStartX(), 
            csGetDragStartY(), 
            getWord(%tgtPos, 0), 
            getWord(%tgtPos, 1),
            getWord(%tgtPos, 2)
         );
      }
      
      return $CSDI_DRAG;
   }
   
}
//------------------------------------------------------------------------------

//-Target State-----------------------------------------------------------------
////////////////////////////////////////////////////////////////////////////////
//! Called when the command system's "Target" state has been entered
////////////////////////////////////////////////////////////////////////////////
function Target::onEnter(%this)
{   
   // Set cursor to current command
   csUpdateCursor(CmdStateTracker.getCommand());
}

////////////////////////////////////////////////////////////////////////////////
//! Called when the command system's "Target" state has been exited
////////////////////////////////////////////////////////////////////////////////
function Target::onExit(%this)
{   
   // Reset cursor to default
   csUpdateCursor($CSC_NONE);
}

////////////////////////////////////////////////////////////////////////////////
//! Called when the command system's "Target" state is running
////////////////////////////////////////////////////////////////////////////////
function Target::onUpdate(%this)
{
   // Update tools
   if(CmdStateTracker.hasCommand()) {
      if(CmdStateTracker.getCommand() == $CSC_TOOL) {
         toolsUpdateSelect(invClientGetSelectedItem());
      }
   }
    
   // Go back to select state if the command state tracker no longer has 
   // a command
   if(!CmdStateTracker.hasCommand()) {
      return $CSTI_SELECT;
   }  
   
   // When we finally have a target we can move to the execute state
   else if(CmdStateTracker.hasTarget()) {
      return $CSTI_EXECUTE;
   }
   
   // Remain in target state
   else {
      // Command issued through button
      if($CSC_ISSUED != $CSC_NONE) {
         csClearTargetState();
         CmdStateTracker.setCommand($CSC_ISSUED);
         csUpdateCursor($CSC_ISSUED);
         $CSC_ISSUED = $CSC_NONE;
      }
      
      else {
         // On left button down update target
         if($CSC_LEFTBTN) {
            $CSC_LEFTBTN = false;
            CmdStateTracker.updateTarget();
         }

         // On right button down clear target state
         if($CSC_RGHTBTN) {
            $CSC_RGHTBTN = false;
            csClearTargetState();
         }
      }
      
      return $CSTI_TARGET;
   }
}
//------------------------------------------------------------------------------

//-Execute State----------------------------------------------------------------
////////////////////////////////////////////////////////////////////////////////
//! Called when the command system's "Execute" state has been entered
////////////////////////////////////////////////////////////////////////////////
function Execute::onEnter(%this)
{  
   // Close task buttons for any commanded object
   %selList = CmdStateTracker.getSelection(); 
   %selSize = %selList.getSize();
   for(%i = 0; %i < %selSize; %i++) {
      showTaskBtns(%selList.getID(%i), false);
   }
   
   // Send command request
   if(CmdStateTracker.hasCommand() && CmdStateTracker.hasTarget()) {
      if(CmdStateTracker.getCommand() == $CSC_BUILD) {
         csBeginWaitForCmd();
      }
      CmdStateTracker.sendCmdMsg();
   }
}

////////////////////////////////////////////////////////////////////////////////
//! Called when the command system's "Execute" state has been exited
////////////////////////////////////////////////////////////////////////////////
function Execute::onExit(%this)
{
   
}

////////////////////////////////////////////////////////////////////////////////
//! Called when the command system's "Execute" state is running
////////////////////////////////////////////////////////////////////////////////
function Execute::onUpdate(%this)
{
   // Just in case
   if(CmdStateTracker.hasCommand() && CmdStateTracker.hasTarget()) {
      // Wait for command request response
      if(!CmdStateTracker.cmdResponseReceived())
         return $CSEI_EXECUTE;
   }
   
   // Request succeeded
   if(CmdStateTracker.cmdRequestSuccess()) {
      // Execute current command on target
      %this.onSuccess();

      // Clear command and target
      CmdStateTracker.clearCommand();
      CmdStateTracker.clearTarget();
      
      // Clear response
      CmdStateTracker.clearCmdResponse();
      
      //Play the accept sound on the first unit
      if(CmdStateTracker.hasSelection())
      {
         %selectList = CmdStateTracker.getSelection();
         if(%selectList) {
            %selectList.getRandomObject().playVocal("ACC");
         }
      }
      
      return $CSEI_SELECT;
   }
   // Request failed
   else {      
      // Clear target
      CmdStateTracker.clearTarget();
      
      // Clear response
      CmdStateTracker.clearCmdResponse();
      
      //Play the deny sound on the first unit
      if(CmdStateTracker.hasSelection())
      {
         %selectList = CmdStateTracker.getSelection();
         if(%selectList) {
            %selObj  = %selectList.getRandomObject();
            %cmpChar = slgQueryInterface(%selObj, $CID_CHARACTER);
            %prefix  = "";
            if(isObject(%cmpChar)) {
               if(%cmpChar.inState($CharacterState::Drunk)) {
                  %prefix = "D";
               }
            }
            %selObj.playVocal(%prefix @ "DNY");
         }
      }
      
      // Return from whence we came
      %prevState = CmdStateTracker.getPreviousState();
      if(%prevState == $CSS_SELECT || %prevState == $CSS_DRAG) {
         CmdStateTracker.clearCommand();
         return $CSEI_SELECT;
      }
      else {
         return $CSEI_TARGET;
      }
   }
}

////////////////////////////////////////////////////////////////////////////////
//! Called on successful execute
////////////////////////////////////////////////////////////////////////////////
function Execute::onSuccess(%this)
{
   %command = CmdStateTracker.getCommand();
   
   // If it is a move command, play move animation
   if (%command == $CSC_MOVE || %command == $CSC_TOOL)
   {
      if (%command == $CSC_TOOL)
      {
         $PLACE_DYNAMITE = false;
      }
      
      // Get target and play animation at location
      if(CmdStateTracker.hasLocTarget())
      {
         if (isObject($DestinationObject) == true)
         {
            $DestinationObject.delete();
            $DestinationObject = 0;
         }
         
         commandToServer('CreateDestinationFlag', CmdStateTracker.getLocTarget());
      }
   }
}
//------------------------------------------------------------------------------

// End client_cmdstates.cs
