$AI_PATHQUERYCOUNT = 10;
$AI_MONITORJOB     = true;
$AI_MONITORHOME    = true;
$AI_MONITORHUNGER  = true;


function RestoreObjectHats(%object)
{
   // remove any existing hat
   %object.unmountImage(0);
   if ($HatEnabled == false)
   {
      return;
   }
   
   // mount base items
   %datablock = %object.getDataBlock();
   %baseMountCount = %datablock.getMountCount();
   for (%index = 0; %index < %baseMountCount; %index++)
   {
      %mountObject = %datablock.GetMountObject(%index);
      %mountPosition = %datablock.getMountPosition(%index);
      if (%mountPosition == 0)
      {
         %object.mountImage(%mountObject, %mountPosition);
      }
   }
   
   // check if the object is one of the three amigos
   if (%object.amigo == true)
   {
      %object.mountImage(Sombrero, 0);
   }
   
   // get the character (for the work hat)
   %character = slgQueryInterface(%object, $CID_CHARACTER);
   if (isObject(%character) == false)
   {
      return;
   }
   
   %workplace = %character.getWork();
   if (isObject(%workplace) == false)
   {
      return;
   }
   
   //Get the character component of the character and record whether their gender.
   %gender = slgQueryInterface(%object, $CID_CHARACTER);
   if(!isObject(%object))
   {
      return;
   }
   
   %gender = %gender.getDatablock();
   %gender = %gender.gender;
      
   //Get the workplace's building component.
   %cmpBldg = slgQueryInterface(%workplace, $CID_BUILDING);
   if(!isObject(%cmpBldg))
   {
      return;
   }
   
   //Get the work items.
   %index = 0;
   %item = %cmpBldg.getWorkItem(%index,%gender);
   while (strlen(%item) > 0)
   {
      %slot = %cmpBldg.getWorkItemMount(%index,%gender);
      %object.unmountImage(%slot);
      if (%slot != 0 || $HatEnabled == true)
      {
         %object.mountImage(%item, %slot);
      }
      
      %index++; 
      %item = %cmpBldg.getWorkItem(%index,%gender);
   }
}

//Globally Used Functions for AI////////
function RestoreCharacterOutfit(%aicmp, %initialize)
{
   %workplace = GetWorkplace(%aicmp);
   %object = GetThisObject(%aicmp);
   
   // Remove all mounted images
   if (%initialize == false)
   {
      for(%i = 0; %i < $ShapeBase::MaxMountedImages; %i++)
      {
         %object.unmountImage(%i);
      }
   }
   
   // mount base items
   %datablock = %object.getDataBlock();
   %baseMountCount = %datablock.getMountCount();
   for (%index = 0; %index < %baseMountCount; %index++)
   {
      // do not overwrite existing mounts
      if (%initialize == true)
      {
         switch (%index)
         {
         case 0: if (%object.fileMount0 !$= "" && ($HatEnabled == true ||
            %object.removeHat == false)) continue;
         case 1: if (%object.fileMount1 !$= "") continue;
         case 2: if (%object.fileMount2 !$= "") continue;
         case 3: if (%object.fileMount3 !$= "") continue;
         }
      }
      
      %mountObject = %datablock.GetMountObject(%index);
      %mountPosition = %datablock.getMountPosition(%index);
      %object.unmountImage(%mountPosition);
      if (%mountPosition != 0 || $HatEnabled == true ||
         %object.removeHat == false)
      {
         %object.mountImage(%mountObject, %mountPosition);
      }
   }

   // if the character has a work place and is not currently going to it
   if (%workplace != 0)
   {
      %building = slgQueryInterface(%workplace, $CID_BUILDING);
      %door = %building.getDoor();
      %doorX = getWord(%door, 0) + 0.5;
      %doorY = getWord(%door, 1) + 0.5;
      %position = %object.position;
      if (%aicmp.hasAction("employ") == false ||
         %doorX == getWord(%position, 0) && %doorY == getWord(%position, 1))
      {
         //Get the character component of the character and record whether their gender.
         %gender = slgQueryInterface(%object, $CID_CHARACTER);
         if(!isObject(%object))
         {
            return;
         }
         
         %gender = %gender.getDatablock();
         %gender = %gender.gender;
            
         //Get the workplace's building component.
         %cmpBldg = slgQueryInterface(%workplace, $CID_BUILDING);
         if(!isObject(%cmpBldg))
         {
            return;
         }
            
         //Change the person into their work uniform.
         %skin = %cmpBldg.getUniform();
         %object.setSkinName(%skin);
         
         //Get the work items.
         %index = 0;
         %item = %cmpBldg.getWorkItem(%index,%gender);
         while (strlen(%item) > 0)
         {
            %slot = %cmpBldg.getWorkItemMount(%index,%gender);
            %object.unmountImage(%slot);
            if (%slot != 0 || $HatEnabled == true)
            {
               %object.mountImage(%item, %slot);
            }
            
            %index++; 
            %item = %cmpBldg.getWorkItem(%index,%gender);
         }
      }
   }
   // Change back into normal outfit
   else if (%initialize == false)
   {
      %datablock = %object.getDataBlock();
      if (%datablock.skin $= "")
      {
         %object.setSkinName("base");
      }
      else      
      {
         %object.setSkinName(%datablock.skin);
      }
   }
   
   %cmpChar = slgQueryInterface(%object, $CID_CHARACTER);
   if (isObject(%cmpChar)) 
   {
      // protesting
      %cmpChar.mountProtestSign(true);
      
      // drunk bottle
      if (%cmpChar.inState($CharacterState::Drunk))
      {
         %object.mountImage("bottle", 2);
      }
   }
   
   if (%object.amigo == true)
   {
      %object.unmountImage(0);
      %object.mountImage(Sombrero, 0);
   }
}

//-Happiness Modifiers----------------------------------------------------------
////////////////////////////////////////////////////////////////////////////////
//! Lose happiness due to homelessness
//! \param %cmpAI AI component object
////////////////////////////////////////////////////////////////////////////////
function LoseHappinessFromHome(%cmpAI)
{
   // Update the happiness for the character
   %object    = GetThisObject(%cmpAI);
   %component = slgQueryInterface(%object, $CID_CHARACTER);
   %datablock = %component.getDataBlock();
   %object.homelessUnhappy += %datablock.homelessHappiness;
   
   // Update the resource happiness
   %happiness = rsGetResource($Resource::Happiness);
   %happiness.decreaseCount(%datablock.homelessHappiness);
   
   // Update character status
   %level = %object.homelessUnhappy / %datablock.homelessHappiness;
   if(%level <= 1) {
      %component.setState($CharacterState::NoHomeStageOne);
      %component.clearState($CharacterState::NoHomeStageTwo);
   }
   else {
      %component.clearState($CharacterState::NoHomeStageOne);
      %component.setState($CharacterState::NoHomeStageTwo);
   }
   
   UpdateUnhappinessIcon(%object);
}

////////////////////////////////////////////////////////////////////////////////
//! Lose happiness due to drunkenness
//! \param %cmpAI AI component object
////////////////////////////////////////////////////////////////////////////////
function LoseHappinessFromDrunk(%cmpAI)
{
   // Update character happiness
   %object    = GetThisObject(%cmpAI);
   %component = slgQueryInterface(%object, $CID_CHARACTER);
   %datablock = %component.getDataBlock();
   %object.drunkUnhappy = %datablock.drunkHappiness;
   
   // Update resource happiness
   %happiness = rsGetResource($Resource::Happiness);
   %happiness.decreaseCount(%datablock.drunkHappiness);
   
   // Update character status
   %component.setState($CharacterState::Drunk);
   
   UpdateUnhappinessIcon(%object);
}

////////////////////////////////////////////////////////////////////////////////
//! Lose happiness due to joblessness
//! \param %cmpAI AI component object
////////////////////////////////////////////////////////////////////////////////
function LoseHappinessFromJob(%cmpAI)
{
   // Update character happiness
   %object    = GetThisObject(%cmpAI);
   %component = slgQueryInterface(%object, $CID_CHARACTER);
   %datablock = %component.getDataBlock();
   %object.joblessUnhappy += %datablock.joblessHappiness;
   
   // Update resource happiness
   %happiness = rsGetResource($Resource::Happiness);
   %happiness.decreaseCount(%datablock.joblessHappiness);
   
   // Update character status
   %component.clearState($CharacterState::NoWorkStageOne);
   %component.clearState($CharacterState::NoWorkStageTwo);
   %component.clearState($CharacterState::NoWorkStageThree);
   %level = %object.joblessUnhappy / %datablock.joblessHappiness;
   if(%level <= 1) {
      %component.setState($CharacterState::NoWorkStageOne);
   }
   else if(%level <= 2) {
      %component.setState($CharacterState::NoWorkStageTwo);
   }
   else if(%level <= 3) {
      %component.setState($CharacterState::NoWorkStageThree);
   }
   
   UpdateUnhappinessIcon(%object);
}

////////////////////////////////////////////////////////////////////////////////
//! Restore happiness lost from homelessness
//! \param %cmpAI AI component object
////////////////////////////////////////////////////////////////////////////////
function RestoreLostHappinessFromHome(%cmpAI)
{
   // Update resource happiness and character happiness from homelessness
   %happiness = rsGetResource($Resource::Happiness);
   %object    = GetThisObject(%cmpAI);
   
   %happiness.increaseCount(%object.homelessUnhappy);
   %object.homelessUnhappy = 0;
   
   // Update character status
   %component = slgQueryInterface(%object, $CID_CHARACTER);
   %component.clearState($CharacterState::NoHomeStageOne);
   %component.clearState($CharacterState::NoHomeStageTwo);
   
   UpdateUnhappinessIcon(%object);
}

////////////////////////////////////////////////////////////////////////////////
//! Restore happiness lost from drunkenness
//! \param %cmpAI AI component object
////////////////////////////////////////////////////////////////////////////////
function RestoreLostHappinessFromDrunk(%cmpAI)
{
   // Update resource happiness and character happiness from drunk
   %happiness = rsGetResource($Resource::Happiness);
   %object    = GetThisObject(%cmpAI);
   
   %happiness.increaseCount(%object.drunkUnhappy);
   %object.drunkUnhappy = 0;
   
   // Update character status
   %component = slgQueryInterface(%object, $CID_CHARACTER);
   %component.clearState($CharacterState::Drunk);
   
   UpdateUnhappinessIcon(%object);
}

////////////////////////////////////////////////////////////////////////////////
//! Restore happiness lost from joblessness
//! \param %cmpAI AI component object
////////////////////////////////////////////////////////////////////////////////
function RestoreLostHappinessFromJob(%cmpAI)
{
   // Update resource happiness and character happiness from drunk
   %happiness = rsGetResource($Resource::Happiness);
   %object    = GetThisObject(%cmpAI);
   
   %happiness.increaseCount(%object.joblessUnhappy);
   %object.joblessUnhappy = 0;
   
   // Update character status
   %component = slgQueryInterface(%object, $CID_CHARACTER);
   %component.clearState($CharacterState::NoWorkStageOne);
   %component.clearState($CharacterState::NoWorkStageTwo);
   %component.clearState($CharacterState::NoWorkStageThree);
   
   UpdateUnhappinessIcon(%object);
}

////////////////////////////////////////////////////////////////////////////////
//! Used to check if monitor effects occur (drunk, leave, protest)
//! \param %percent String of percentages
//! \param %happy String of happiness modifiers
//! \param %word Index of percentage to pull from percentage string (%percent)
//! \retval bool True if effect should happen
////////////////////////////////////////////////////////////////////////////////
function CheckForMonitorEffect(%percent, %happy, %word)
{
   // Get chance of effect
   %fxchance   = getWord(%percent, %word);
   %happyLevel = ResourceHappinessLevel.getHappinessLevel();
   %happyMod   = getWord(%happy, %happyLevel);
   %fxchance   += %happyMod;
   %fxchance   = slgClamp(%fxchance, 0, 100);
   
   // Check if effect should start      
   %num = RandomNumber(0, 100);
   return (%num < %fxchance);
}

////////////////////////////////////////////////////////////////////////////////
//! Sets the boolean to monitor job
//! \param %bMonitor True to monitor
////////////////////////////////////////////////////////////////////////////////
function MonitorJob(%bMonitor)
{
   $AI_MONITORJOB = %bMonitor;
}

////////////////////////////////////////////////////////////////////////////////
//! Sets the boolean to monitor home
//! \param %bMonitor True to monitor
////////////////////////////////////////////////////////////////////////////////
function MonitorHome(%bMonitor)
{
   $AI_MONITORHOME = %bMonitor;
}

////////////////////////////////////////////////////////////////////////////////
//! Sets the boolean to monitor hunger
//! \param %bMonitor True to monitor
////////////////////////////////////////////////////////////////////////////////
function MonitorHunger(%bMonitor)
{
   $AI_MONITORHUNGER = %bMonitor;
}

////////////////////////////////////////////////////////////////////////////////
//! Sets the boolean for all monitors
//! \param %bMonitor True to monitor
////////////////////////////////////////////////////////////////////////////////
function MonitorAll(%bMonitor)
{
   MonitorJob(%bMonitor);
   MonitorHome(%bMonitor);
   MonitorHunger(%bMonitor);
}

////////////////////////////////////////////////////////////////////////////////
//! Indicates if we are monitoring job
//! \retval bool True if monitoring
////////////////////////////////////////////////////////////////////////////////
function AreMonitoringJob()
{
   return $AI_MONITORJOB;
}

////////////////////////////////////////////////////////////////////////////////
//! Indicates if we are monitoring home
//! \retval bool True if monitoring
////////////////////////////////////////////////////////////////////////////////
function AreMonitoringHome()
{
   return $AI_MONITORHOME;
}

////////////////////////////////////////////////////////////////////////////////
//! Indicates if we are monitoring hunger
//! \retval bool True if monitoring
////////////////////////////////////////////////////////////////////////////////
function AreMonitoringHunger()
{
   return $AI_MONITORHUNGER;
}

////////////////////////////////////////////////////////////////////////////////
//! Resets the monitor booleans
////////////////////////////////////////////////////////////////////////////////
function ResetMonitors()
{
   $AI_MONITORJOB     = true;
   $AI_MONITORHOME    = true;
   $AI_MONITORHUNGER  = true;
}

function slgDistanceBetweenSquared(%slg0, %slg1)
{
   %pos = %slg0.getPosition();
   %x0 = getWord(%pos,0); 
   %y0 = getWord(%pos,1);
   
   %pos = %slg1.getPosition();
   %x1 = getWord(%pos,0); 
   %y1 = getWord(%pos,1);
   
   return (%x0-%x1)*(%x0-%x1)+(%y0-%y1)*(%y0-%y1);
}