-------------------------------------------------------------------------------------
-- Title: MSBT Profiles
-- Author: Mik
-------------------------------------------------------------------------------------

-- Create module namespace.
MSBTProfiles = {};


-------------------------------------------------------------------------------------
-- Private constants.
-------------------------------------------------------------------------------------

local DEFAULT_PROFILE_NAME = "Default";


-------------------------------------------------------------------------------------
-- Public variables.
-------------------------------------------------------------------------------------

MSBTProfiles.CurrentProfile = nil;


-------------------------------------------------------------------------------------
-- Private variables.
-------------------------------------------------------------------------------------

-- Holds variables to be saved between sessions.
local savedVariables;
local savedVariablesPerChar;


-------------------------------------------------------------------------------------
-- Profile functions.
-------------------------------------------------------------------------------------

-- **********************************************************************************
-- This function initializes the saved variables.  A default profile will be created
-- if one doesn't already exist. 
-- **********************************************************************************
function MSBTProfiles.InitSavedVariables()
 -- Set the saved variables per character to the value specified in the .toc file.
 savedVariablesPerChar = MikSBT_SavedVarsPerChar;

 -- Check if there are no saved variables per character.
 if (not savedVariablesPerChar) then
  -- Create a new table to hold the saved variables per character, and set the .toc entry to it.
  savedVariablesPerChar = {};
  MikSBT_SavedVarsPerChar = savedVariablesPerChar;

  savedVariablesPerChar.CurrentProfileName = DEFAULT_PROFILE_NAME;
 end


 -- Set the saved variables to the value specified in the .toc file.
 savedVariables = MikSBT_SavedVars;

 -- Check if there are no saved variables.
 if (not savedVariables) then
  -- Create a new table to hold the saved variables, and set the .toc entry to it.
  savedVariables = {};
  MikSBT_SavedVars = savedVariables;

  savedVariablesPerChar.CurrentProfileName = DEFAULT_PROFILE_NAME;
  savedVariables.Profiles = {};
  savedVariables.Profiles[savedVariablesPerChar.CurrentProfileName] = {};

  -- Set all the options to their defaults.
  MSBTProfiles.ResetProfile(savedVariablesPerChar.CurrentProfileName);

 -- There are saved variables.
 else
  -- Updates profiles created by older versions.
  MSBTProfiles.UpdateProfiles();

  -- Select the current profile for the character if it exists, otherwise select the default profile.
  if (MSBTProfiles.ProfileExists(savedVariablesPerChar.CurrentProfileName)) then
   MSBTProfiles.SelectProfile(savedVariablesPerChar.CurrentProfileName);
  else
   MSBTProfiles.SelectProfile(DEFAULT_PROFILE_NAME);
  end
 end
end


-- **********************************************************************************
-- This function returns the saved variables. 
-- **********************************************************************************
function MSBTProfiles.GetSavedVariables()
 -- Returns the saved variables.
 return savedVariables;
end


-- **********************************************************************************
-- This function returns the saved variables per character. 
-- **********************************************************************************
function MSBTProfiles.GetSavedVariablesPerChar()
 -- Returns the saved variables per character.
 return savedVariablesPerChar;
end


-- **********************************************************************************
-- Updates profiles created with older versions.
-- **********************************************************************************
function MSBTProfiles.UpdateProfiles()
 -- Loop through all of the profiles to update structure changes on new versions.
 for profileName, profile in pairs(savedVariables.Profiles) do
  -- Check if the profile was created before version 4.1.
  if (profile.CreationVersion < 4.1) then
   -- Get the default profile.
   local defProfile = MSBTDefaults.GetDefaultProfile();

   -- Copy the new trigger structure into the profile.
   profile.Triggers = MSBTTableRecycler.CopyTable(defProfile.Triggers);

   -- Copy the new interrupt events into the profile.
   profile.EventSettings.INCOMING_SPELL_INTERRUPT = MSBTTableRecycler.CopyTable(defProfile.EventSettings.INCOMING_SPELL_INTERRUPT);
   profile.EventSettings.OUTGOING_SPELL_INTERRUPT = MSBTTableRecycler.CopyTable(defProfile.EventSettings.OUTGOING_SPELL_INTERRUPT);

   -- Copy the new backlash suppression into the profile.
   profile.Suppressions.MSBT_SUPPRESSION_BACKLASH = MSBTTableRecycler.CopyTable(defProfile.Suppressions.MSBT_SUPPRESSION_BACKLASH);

   profile.CreationVersion = MikSBT.VERSION_NUMBER;
  end

  -- Check if the profile was created before version 4.11.
  if (profile.CreationVersion < 4.11) then
   -- Get the default profile.
   local defProfile = MSBTDefaults.GetDefaultProfile();

   -- Copy the new low health/mana trigger settings into the profile.
   profile.Triggers.MSBT_TRIGGER_LOW_HEALTH.TriggerSettings = MSBTTableRecycler.CopyTable(defProfile.Triggers.MSBT_TRIGGER_LOW_HEALTH.TriggerSettings);
   profile.Triggers.MSBT_TRIGGER_LOW_MANA.TriggerSettings = MSBTTableRecycler.CopyTable(defProfile.Triggers.MSBT_TRIGGER_LOW_MANA.TriggerSettings);
   profile.Triggers.MSBT_TRIGGER_LOW_PET_HEALTH.TriggerSettings = MSBTTableRecycler.CopyTable(defProfile.Triggers.MSBT_TRIGGER_LOW_PET_HEALTH.TriggerSettings);

   profile.CreationVersion = MikSBT.VERSION_NUMBER;
  end
  
  -- Check if the profile was created before version 4.12.
  if (profile.CreationVersion < 4.12) then
   -- Get the default profile.
   local defProfile = MSBTDefaults.GetDefaultProfile();
   
   -- Copy the new game healing disabled setting into the profile.
   profile.GameHealingDisabled = defProfile.GameHealingDisabled;

   profile.CreationVersion = MikSBT.VERSION_NUMBER;
  end
 end
end


-- **********************************************************************************
-- Returns whether or not the passed profile exists.
-- **********************************************************************************
function MSBTProfiles.ProfileExists(profileName)
 local profileFound = false;

 -- Loop through all of the profiles looking for the passed one.
 for pName in pairs(savedVariables.Profiles) do
  if (pName == profileName) then
   profileFound = true;   
  end
 end

 -- Return whether or not the profile exists.
 return profileFound;
end


-- **********************************************************************************
-- Resets the passed profile to its defaults.
-- **********************************************************************************
function MSBTProfiles.ResetProfile(profileName, showOutput)
 -- Get whether or not the profile exists.
 local profileExists = MSBTProfiles.ProfileExists(profileName);

 -- Check if the profile exists.
 if (profileExists) then
  -- Get the default profile.
  local defProfile = MSBTDefaults.GetDefaultProfile();

  -- Reset the profile to the default profile.
  savedVariables.Profiles[profileName] = MSBTTableRecycler.CopyTable(defProfile);

  -- Check if it's the current profile being reset.
  if (profileName == savedVariablesPerChar.CurrentProfileName) then
   -- Reset the current profile pointer.
   MSBTProfiles.CurrentProfile = savedVariables.Profiles[savedVariablesPerChar.CurrentProfileName];

   -- Register the triggers.
   MSBTTriggers.RegisterAllTriggers();

   -- Hash all of the profile's suppressions.
   MSBTSuppressions.HashSuppressions();

   -- Disable or enable game damage based on the setting.
   MSBTProfiles.SetOptionGameDamageDisabled(MSBTProfiles.CurrentProfile.GameDamageDisabled);
  end

  -- Check if the output text is to be shown.
  if (showOutput) then
   -- Print the profile reset string.
   MikSBT.Print(profileName .. " " .. MSBTLocale.MSG_PROFILE_RESET, 0, 1, 0);
  end
 end 
end


-- **********************************************************************************
-- Selects the passed profile.
-- **********************************************************************************
function MSBTProfiles.SelectProfile(profileName)
 -- Get whether or not the profile exists.
 local profileExists = MSBTProfiles.ProfileExists(profileName);

 -- Check if the profile exists.
 if (profileExists) then
  -- Set the current profile name for the character to the one being selected.
  savedVariablesPerChar.CurrentProfileName = profileName;

  -- Reset the current profile pointer.
  MSBTProfiles.CurrentProfile = savedVariables.Profiles[savedVariablesPerChar.CurrentProfileName];

  -- Register the triggers.
  MSBTTriggers.RegisterAllTriggers();

  -- Hash all of the profile's suppressions.
  MSBTSuppressions.HashSuppressions();

  -- Disable or enable game damage based on the setting.
  MSBTProfiles.SetOptionGameDamageDisabled(MSBTProfiles.CurrentProfile.GameDamageDisabled);
 end
end


-- **********************************************************************************
-- Copies the passed profile to a new profile with the passed name.
-- **********************************************************************************
function MSBTProfiles.CopyProfile(srcProfileName, destProfileName)
 -- Leave the function if the the destination profile name is invalid.
 if (not destProfileName or destProfileName == "") then
  return;
 end

 -- Get whether or not the profiles exist.
 local srcProfileExists = MSBTProfiles.ProfileExists(srcProfileName);
 local destProfileExists = MSBTProfiles.ProfileExists(destProfileName);

 -- Make sure the soource profile exists and the destination profile doesn't.
 if (srcProfileExists and not destProfileExists) then
  savedVariables.Profiles[destProfileName] = MSBTTableRecycler.CopyTable(savedVariables.Profiles[srcProfileName]);
 end
end


-- **********************************************************************************
-- Deletes the passed profile.
-- **********************************************************************************
function MSBTProfiles.DeleteProfile(profileName)
 -- Check if the passed profile is the default one.
 if (profileName == DEFAULT_PROFILE_NAME) then
  return;
 end

 -- Get whether or not the profile exists.
 local profileExists = MSBTProfiles.ProfileExists(profileName);

 -- Check if the profile exists.
 if (profileExists) then
  -- Check if the profile being deleted is the current one.
  if (profileName == savedVariablesPerChar.CurrentProfileName) then
   -- Select the default profile.
   MSBTProfiles.SelectProfile(DEFAULT_PROFILE_NAME);
  end

  -- Delete the profile.
  savedVariables.Profiles[profileName] = nil;
 end
end


-------------------------------------------------------------------------------------
-- Option functions.
-------------------------------------------------------------------------------------

-- **********************************************************************************
-- Disable or enable blizzard's combat text.
-- **********************************************************************************
function MSBTProfiles.DisableBlizzardCombatText(isDisabled)
 -- Check if the text should be disabled.
 if (isDisabled) then
  -- Turn off Blizzard's default combat text.
  SHOW_COMBAT_TEXT = "0";
  if (CombatText_UpdateDisplayedMessages) then
   CombatText_UpdateDisplayedMessages();
  end
 else
  -- Turn on Blizzard's default combat text.
  SHOW_COMBAT_TEXT = "1";
  if (not IsAddOnLoaded("Blizzard_CombatText")) then
   UIParentLoadAddOn("Blizzard_CombatText");
  end
  if (CombatText_UpdateDisplayedMessages) then
   CombatText_UpdateDisplayedMessages();
  end
 end  
end


-- **********************************************************************************
-- Set the user disabled option
-- **********************************************************************************
function MSBTProfiles.SetOptionUserDisabled(isDisabled)
 savedVariables.UserDisabled = isDisabled;

 -- Check if the mod is being set to disabled.
 if (isDisabled) then
  -- Disable the event parser and triggers.
  MSBTParser.Disable(); 
  MSBTTriggers.UnregisterAllTriggers();

  -- Turn on the game's display of outgoing damage.
  SetCVar("CombatDamage", 1);
  
  -- Turn on the game's display of outgoing heals.
  SetCVar("CombatHealing", 1);
 else
  -- Enable the event parser and triggers.
  MSBTParser.Enable(); 
  MSBTTriggers.RegisterAllTriggers();

  -- Turn the game damage display on or off depending on the user setting.
  MSBTProfiles.SetOptionGameDamageDisabled(MSBTProfiles.CurrentProfile.GameDamageDisabled);
  
  -- Turn the game healing display on or off depending on the user setting.
  MSBTProfiles.SetOptionGameHealingDisabled(MSBTProfiles.CurrentProfile.GameHealingDisabled);
 
  -- Turn off Blizzard's default combat text.
  SHOW_COMBAT_TEXT = "0";
  if (CombatText_UpdateDisplayedMessages) then
   CombatText_UpdateDisplayedMessages();
  end

  -- Make sure that periodic spell effects are reported.
  SetCVar("CombatLogPeriodicSpells", 1);
 end

 -- Disable blizzard's combat text if the mod is enabled, otherwise disable it.
 MSBTProfiles.DisableBlizzardCombatText(not isDisabled);
end


-- **********************************************************************************
-- Set the game damage disabled option
-- **********************************************************************************
function MSBTProfiles.SetOptionGameDamageDisabled(damageDisabled)
 MSBTProfiles.CurrentProfile.GameDamageDisabled = damageDisabled;

 -- Check if the game damage is being set off.
 if (damageDisabled) then
   -- Turn off the game damage display.
   SetCVar("CombatDamage", 0);
 else
   -- Turn on the game damage display.
   SetCVar("CombatDamage", 1);
 end
end


-- **********************************************************************************
-- Set the game healing disabled option
-- **********************************************************************************
function MSBTProfiles.SetOptionGameHealingDisabled(healingDisabled)
 MSBTProfiles.CurrentProfile.GameHealingDisabled = healingDisabled;

 -- Check if the game healing is being set off.
 if (healingDisabled) then
   -- Turn off the game healing display.
   SetCVar("CombatHealing", 0);
 else
   -- Turn on the game healing display.
   SetCVar("CombatHealing", 1);
 end
end