$Audio_MusicHandle = 0;
$Audio_AlertHandle = 0;
$Audio_SFXHandle = 0;
$Audio_VocalHandle = 0;
$Audio_CurrentMusic = "";
$Audio_TrainHandle = 0;
$Audio_Construction = 0;

// Used for train sounds
$Train::Current = -1;
$Train::Whistle = 0;

$Scenario::AmbientSound[0]  = "amb_nature";
$Scenario::AmbientHandle[0] = 0;
$Scenario::AmbientStack = 0;

function resetAudioHandles()
{
   $Audio_AlertHandle = 0;
   $Audio_SFXHandle = 0;
   $Audio_VocalHandle = 0;
   $Audio_TrainHandle = 0;
   $Audio_Construction = 0;
   stopMusic();
}

function playAlertSound(%profile)
{
   if(!alxIsPlaying($Audio_AlertHandle))
      $Audio_AlertHandle = alxPlay(%profile);
}

function playSFXSound(%profile)
{
   $Audio_SFXHandle = alxPlay(%profile);
}

function playConstructionSound()
{
   if(!alxIsPlaying($Audio_Construction)) {
      $Audio_Construction = alxPlay("building_construction");
   }
}

function stopConstructionSound()
{
   alxStop($Audio_Construction);
   $Audio_Construction = 0;
}





////////////////////////////////////////////////////////////////////////////////
// Music functions
////////////////////////////////////////////////////////////////////////////////
function stopMusic()
{
   alxStop($Audio_MusicHandle);
   $Audio_MusicHandle  = 0;
   $Audio_CurrentMusic = "";
}

function playMusic(%profile)
{
   if($Audio_CurrentMusic !$= %profile) {
      stopMusic();
      $Audio_MusicHandle = alxPlay(%profile);
      $Audio_CurrentMusic = %profile;
   }
}





////////////////////////////////////////////////////////////////////////////////
// Vocal sound functions
////////////////////////////////////////////////////////////////////////////////
function playVocalSound(%profile)
{
   // MGR:
   // I'm commenting this out for now. I'm not sure why it is even here, except
   // to reduce the chance of sounds becoming annoying.
   //if(0 == RandomNumber(0,2))
      //return;
   if(!alxIsPlaying($Audio_VocalHandle))
      $Audio_VocalHandle = alxPlay(%profile);
}

function playHeroSelectSound(%slobj)
{
   %slobj.playVocal("SEL");
}

function playSelectionSound(%slobj)
{
   if(!isObject(%slobj))
      return;
   if(%slobj.isDead())
      return;
   if(!%slobj.isOnTeam($OST_PLAYER)) {
      //Play the default selection sound.
      %slobj.playVocal("SEL");
      return;
   }
      
   // Building selection sounds
   if(slgIsBuilding(%slobj))
   {
      // if the building is not a bridge
      if (%slobj.isLinkObj() == false)
      {
         // Play construction sound if building is being constructed
         %building = slgQueryInterface(%slobj, $CID_BUILDING);
         if($BuildingState::Construction == %building.getState()) {
            playConstructionSound();
         }
         else if($BuildingState::Production == %building.getState()){
            %slobj.playVocal("SEL");
         }
      }
      // if the building is a bridge
      else
      {
         // look for any bridge links that are in the construction
         // state, and if one is found, play the construction sound
         %link = %slobj.getFirstLinkObj();
         while (isObject(%link) == true)
         {
            // a link is in the construction state, so play the sound
            %building = slgQueryInterface(%link, $CID_BUILDING);
            if (%building.getState() == $BuildingState::Construction)
            {
               playConstructionSound();
               return;
            }
            
            // next link
            %link = %link.getNextLinkObj();
         }
         
         // play the selection sound for the bridge
         %slobj.playVocal("SEL"); 
      }
   }
   
   // Character selection sounds
   else if(slgIsCharacter(%slobj)) {
      %charcmp = slgQueryInterface(%slobj, $CID_CHARACTER);
      
      // Play construction sound if character is building a building
      if(%charcmp.inState($CharacterState::Build)) {
         playConstructionSound();
      }
      
      
      if(!%charcmp.isHero()) {
         // Character is drunk
         if(%charcmp.inState($CharacterState::Drunk)) {
            %slobj.playVocal("DSEL");
            return;
         }
         
         //Is there a disaster going on to warn the player about?
         //First, fire (Check both shelter and workplace)
         %charhome = %charcmp.getHome();
         if(isObject(%charhome)) {
            %building = slgQueryInterface(%charhome, $CID_BUILDING);
            if(%building.onFire()) {
               %slobj.playVocal("SFI");
               return;
            }
         }
         %charwork = %charcmp.getWork();
         if(isObject(%charwork)) {
            %building = slgQueryInterface(%charwork, $CID_BUILDING);
            if(%building.onFire()) {
               %slobj.playVocal("SFI");
               return;
            }
         }
         
         //Second, Drought
         if($DISASTER_DROUGHT_CTR > 0) {
            %slobj.playVocal("SDR");
            return;
         }
         
         //Third, Plague
         if($DISASTER_PLAGUE_CTR > 0) {
            %slobj.playVocal("SPL");
            return;
         }
         
         // Character needs a home and is losing happiness from it
         if(%charcmp.isShelterable()) {
            if(%charcmp.inState($CharacterState::NoHomeStageOne)
            || %charcmp.inState($CharacterState::NoHomeStageTwo)) {
               %slobj.playVocal("IHO");
               return;
            }
         }
         
         // Character needs a job and is losing happiness from it
         if(%charcmp.isEmployable()) {
            if(%charcmp.inState($CharacterState::NoWorkStageOne)
            || %charcmp.inState($CharacterState::NoWorkStageTwo)
            || %charcmp.inState($CharacterState::NoWorkStageThree)) {
               %slobj.playVocal("IJO");
               return;
            }
         }
         
         // Character needs food
         if(%charcmp.isHungry()) {
            %slobj.playVocal("NFO");
            return;
         }
         
         // Character employment needs water
         if(isObject(%charwork)) {
            %cmpBldg = slgQueryInterface(%charwork, $CID_BUILDING);
            if(%cmpBldg.hasStatus($BuildingStatus::NeedWater)) {
               %slobj.playVocal("NWA");
               return;
            }
         }
      }
      
      // Play the default selection sound.
      %slobj.playVocal("SEL");
   }
}

function playHappinessSound()
{
   // No happiness sounds if not in the game
   if(!($PlayingGame && $MissionLoaded)) {
      return;
   }
   
   // Get random character and make sure he/she is visible
   %citizen = slgGetRandomPlayerCharacterObj();
   if(!isObject(%citizen)) {
      return;
   }
   if(!%citizen.isVisible()) {
      return;
   }
   
   // Get prefix if drunk
   %cmpChar = slgQueryInterface(%citizen, $CID_CHARACTER);
   if(!isObject(%cmpChar)) {
      return;
   }
   %prefix = "";
   if(%cmpChar.inState($CharacterState::Drunk)) {
      %prefix = "D";
   }
   
   // Play vocal happiness based on level
   %level = rsGetResourceCount($Resource::Happiness);
   if(%level > 65) {
      %citizen.playVocal(%prefix @ "IHA");
   }
   else {
      %citizen.playVocal(%prefix @ "ISA");
   }
}

function playBuildingCompleteSound(%bldg)
{
   if(!isObject(%bldg)) {
      return;
   }
   
   // Get builder
   %cmpBldg = slgQueryInterface(%bldg, $CID_BUILDING);
   if(!isObject(%cmpBldg)) {
      return;
   }
   %builder = %cmpBldg.builder;
   if(!isObject(%builder)) {
      return;
   }
   
   %bldgdata = %bldg.getDataBlock();
   if(!isObject(%bldgdata)) {
      return;
   }
   
   // Check chance of occurrence
   %chance = 100;
   if(%bldgdata.constructSoundChance !$= "") {
      %chance = %bldgdata.constructSoundChance;
   }
   %random = getRandom(1, 100);
   if(%random > %chance) {
      return;
   }
   
   // Get builder gender and datablock
   %cmpChar     = slgQueryInterface(%builder, $CID_CHARACTER);
   %cmpCharData = %cmpChar.getDataBlock();

   // If it is a hero, try to see if a male or female civilian is around
   if(%cmpCharData.isHero) {
      %objects = slgGetClientCharacterList();
      %teamobjs = new SLGameObjList();
      %objects.getTeamList($OST_PLAYER, %teamobjs);
      %typeobjs = new SLGameObjList();
      
      // Get random gender first
      // If gender does not exist try other sex
      %useFemale = getRandom(0, 1);
      if(%useFemale) {
         %teamobjs.getTypeList("FemaleCiv", %typeobjs);
         if(!%typeobjs.getSize()) {
            %teamobjs.getTypeList("MaleCiv", %typeobjs);
         }
      }
      else {
         %teamobjs.getTypeList("MaleCiv", %typeobjs);
         if(!%typeobjs.getSize()) {
            %teamobjs.getTypeList("FemaleCiv", %typeobjs);
         }
      }
      
      // No civilian equals no sound
      if(!%typeobjs.getSize()) {
         %teamobjs.delete();
         %typeobjs.delete();
         return;
      }
      
      // Use one of the civilians
      %builder     = %typeobjs.getRandomObject();
      %cmpChar     = slgQueryInterface(%builder, $CID_CHARACTER);
      %cmpCharData = %cmpChar.getDataBlock();
      %teamobjs.delete();
      %typeobjs.delete();
   }
   
   // Play sound based on gender of builder
   if(%cmpCharData.gender $= $GENDER_MALE) {
      %sound = %bldgdata.mConstructSound;
   }
   else if(%cmpCharData.gender $= $GENDER_FEMALE) {
      %sound = %bldgdata.fConstructSound;
   }
   if(%sound $= "") {
      return;
   }
   %soundindex = getRandom(1, getWordCount(%sound)) - 1;
   playVocalSound(getWord(%sound, %soundindex));
}





////////////////////////////////////////////////////////////////////////////////
// Ambient sound functions
// NOTE: Ambient sounds have been removed from the game, so some of the changes
// I made may still have some bugs. If revisited, ambient sounds need to be
// debugged before being used
////////////////////////////////////////////////////////////////////////////////
function setAmbientSound(%profile)
{
   // First in stack reserved for town ambience
   /*if($Scenario::AmbientSound[0] $= %profile) {
      return;
   }
   
   if(alxIsPlaying($Scenario::AmbientHandle[0])) {
      alxStop($Scenario::AmbientHandle[0]);
   }
   $Scenario::AmbientSound[0]  = %profile;
   $Scenario::AmbientHandle[0] = 0;*/
}

function pushAmbientSound(%sound)
{
   /*$Scenario::AmbientStack++;
   $Scenario::AmbientSound[$Scenario::AmbientStack]  = %sound;
   $Scenario::AmbientHandle[$Scenario::AmbientStack] = 0;*/
}

function popAmbientSoundName(%sound)
{
   // Go through stack and find ambient sound by name
   /*for(%i = 1; %i <= $Scenario::AmbientStack; %i++) {
      // Found if true
      if($Scenario::AmbientSound[%i] $= %sound) {
         break;
      }
   }
   // Shift ambient sounds
   for(%i; %i <= $Scenario::AmbientStack; %i++) {
      $Scenario::AmbientSound[%i]  = $Scenario::AmbientSound[%i + 1];
      $Scenario::AmbientHandle[%i] = $Scenario::AmbientHandle[%i + 1];
   }
   
   // Update stack count
   $Scenario::AmbientStack--;*/
}

function popAmbientSound()
{
   /*if($Scenario::AmbientStack > 0){
      $Scenario::AmbientSound[$Scenario::AmbientStack]  = "";
      $Scenario::AmbientHandle[$Scenario::AmbientStack] = 0;
      $Scenario::AmbientStack--;
   }*/
}

function popAllAmbientSound()
{
   /*while($Scenario::AmbientStack > 0) {
      popAmbientSound();
   }
   setAmbientSound("");*/
}

function stopAmbientSound()
{
   /*%handle = $Scenario::AmbientHandle[$Scenario::AmbientStack];
   if(%handle) {
      alxStop(%handle);
   }*/
   alxStop($Scenario::AmbientHandle[0]);
   $Scenario::AmbientHandle[0] = 0;
}

function startAmbientSound()
{
   /*%sIdx   = $Scenario::AmbientStack;
   %sound  = $Scenario::AmbientSound[%sIdx];
   %handle = $Scenario::AmbientHandle[%sIdx];
   if(%sound !$= "" && !alxIsPlaying(%handle)) {
      $Scenario::AmbientHandle[%sIdx] = alxPlay(%sound);
   }*/
   stopAmbientSound();
   $Scenario::AmbientHandle[0] = alxPlay($Scenario::AmbientSound[0]);
}

function chooseAmbientSound()
{   
   // Town ambience not used
   /*if($Scenario::AmbientStack > 0) {
      return;
   }
      
   // Play town ambience based on number of citizens present
   %numPlayerCitizens = rsGetResourceCount($Resource::People);
   if(%numPlayerCitizens <= 5) {
      setAmbientSound("");
   }
   else if(%numPlayerCitizens <= 15) {
      setAmbientSound("amb_town0");
      startAmbientSound();
   }
   else if(%numPlayerCitizens <= 25) {
      setAmbientSound("amb_town1");
      startAmbientSound();
   }
   else {
      setAmbientSound("amb_town2");
      startAmbientSound();
   }*/
}

function saveAmbientSounds()
{
   // Save number of sounds on stack
   /*%count = $Scenario::AmbientStack + 1;
   slgSaveInt(%count);
   
   // Save each sound on the stack
   for(%i = 0; %i < %count; %i++) {
      slgSaveString($Scenario::AmbientSound[%i]);
   }*/
}

function loadAmbientSounds()
{
   // Clear ambient sounds
   /*popAllAmbientSound();
   
   // Load number of sounds
   %count = slgLoadInt();
   $Scenario::AmbientStack = %count - 1;
   
   
   // Load each sound
   for(%i = 0; %i < %count; %i++) {
      $Scenario::AmbientSound[%i] = slgLoadString();
   }
   
   // Start ambient sound?
   startAmbientSound();
   muteSoundFX(false);*/
}




////////////////////////////////////////////////////////////////////////////////
// Train sound functions
////////////////////////////////////////////////////////////////////////////////
function playTrainStop(%traintype)
{
   if(%traintype < $TT_DEFAULT) {
      playSFXSound("audio_wagonstop");
   }
   else {
      playSFXSound("audio_trainstop");
   }
}

function playTrainStart(%traintype)
{
   if(%traintype < $TT_DEFAULT) {
      playSFXSound("audio_wagonstart");
   }
   else {
      playSFXSound("audio_trainstart");
   }
}

function playTrainWhistle()
{
   if(!slgTrain_IsTrainVisible()) {
      return;
   }
   
   if(slgTrain_GetCurrentTrainType() < $TT_DEFAULT) {
      playSFXSound("audio_wagonsoundoff");
   }
   else {
      playSFXSound("audio_trainsoundoff");
   }
}

function activateTrainWhistle()
{
   if(!isObject($Train::Whistle)) {
      $Train::Whistle = new SLEndlessTimer() {
         time = 10;
      };
      $Train::Whistle.notifyOnFire(playTrainWhistle);
   }
}
function deactivateTrainWhistle()
{
   if(isObject($Train::Whistle)) {
      $Train::Whistle.delete();
   }
}

function playTrainIdleSounds(%traintype)
{
   // If audio is playing then
   if(alxIsPlaying($Audio_TrainHandle)) {
      // Same, do nothing
      if(%traintype == $Train::Current) {
         return;
      }
      // Stop sound
      else {
         alxStop($Audio_TrainHandle);
      }
   }
   
   // Play new idle, looping sound
   if(%traintype < $TT_DEFAULT) {
      $Audio_TrainHandle = alxPlay(audio_wagonrolling);
   }
   else {
      $Audio_TrainHandle = alxPlay(audio_trainrolling);
   }
   $Train::Current = %traintype;
}

function stopTrainIdleSounds()
{
   // Stop idle sound if playing
   if(alxIsPlaying($Audio_TrainHandle)) {
      alxStop($Audio_TrainHandle);
   }
   
   // Reset idle sound globals
   $Audio_TrainHandle = 0;
   $Train::Current = $TT_NOTRAIN;
}




////////////////////////////////////////////////////////////////////////////////
// Server command sound functions
////////////////////////////////////////////////////////////////////////////////
function clientCmdPlaySFXSound(%sound)
{
   playSFXSound(%sound);
}

function clientCmdPushAmbientSound(%sound)
{
   pushAmbientSound(%sound);
}

function clientCmdPopAmbientSound()
{
   popAmbientSound();
}

function clientCmdPopAllAmbientSounds()
{
   popAllAmbientSound();
}

function clientCmdPlayAmbientSound()
{
   //chooseAmbientSound();
   startAmbientSound();
}

function clientCmdStopAmbientSound()
{
   stopAmbientSound();
}
