local _G = getfenv(0);    -- Holds all the values WoW passes to us, like all the stat names
local abs = abs;          
local modName, L = ...;   -- mod name and mod-specific variables (like localization)

ForTheHorde = {};

-- Saved Variables
local gvif_opts,current_opts;

-- Triggers

local triggers = {
  { trigger = GetSpellInfo(2825),   var_name = 'bloodlust',             opt_name = "Bloodlust",          gv = 'FTH_BL',  default = 1 },
  { trigger = GetSpellInfo(178207), var_name = 'drums_of_fury',         opt_name = "DrumsOfFury",        gv = 'FTH_DOF', default = 1 },
  { trigger = GetSpellInfo(230935), var_name = 'drums_of_the_mountain', opt_name = "DrumsOfTheMountain", gv = 'FTH_DOM', default = 1 },
  { trigger = GetSpellInfo(32182),  var_name = 'heroism',               opt_name = "Heroism",            gv = 'FTH_H',   default = 1 },
  { trigger = GetSpellInfo(204276), var_name = 'primal_rage',           opt_name = "PrimalRage",         gv = 'FTH_PR',  default = 1 },
  { trigger = GetSpellInfo(80353),  var_name = 'time_warp',             opt_name = "TimeWarp",           gv = 'FTH_TW',  default = 1 },
};

-- Main Options Window
ForTheHorde.gvif = CreateFrame("Frame",modName,InterfaceFrameOptionsPanelContainer);
ForTheHorde.gvif.name = "For The Horde";
ForTheHorde.gvif:SetWidth( 500 );
ForTheHorde.gvif:SetHeight( 500 );

local chkbox_title = ForTheHorde.gvif:CreateFontString( nil, "Overlay", "GameFontNormalSmall" );
chkbox_title:SetHeight(20);
chkbox_title:SetJustifyH( "LEFT" );
chkbox_title:SetText( L["PLAY_SOUND_OPTS"] );
chkbox_title:SetPoint( "TOPLEFT", 10, -10 );

function createOptions( label, name, varName, x, y ) 
  local checkbox = CreateFrame( "CheckButton", name .. "_CheckBox_GlobalName", ForTheHorde.gvif, "InterfaceOptionsCheckButtonTemplate" );

  if ForTheHorde[varName] == 1 then
    checkbox:SetChecked(true);
  end
  getglobal(checkbox:GetName() .. 'Text'):SetText( label );
  checkbox:SetPoint( "TOPLEFT", x, y);
  checkbox:SetScript( "OnClick", 
    function() 
      if ForTheHorde[varName] == nil or ForTheHorde[varName] == 0 then
        ForTheHorde[varName] = 1;
      else
        ForTheHorde[varName] = 0;
      end
    end
  ); 
  return checkbox;
end

-- Register events that we listen for
ForTheHorde.gvif:RegisterEvent("ADDON_LOADED");
ForTheHorde.gvif:RegisterEvent("COMBAT_LOG_EVENT_UNFILTERED");
ForTheHorde.gvif:RegisterEvent("PLAYER_ENTERING_WORLD");
ForTheHorde.gvif:RegisterEvent("PLAYER_LOGOUT");

function ForTheHorde.gvif:OnEvent( event, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13 ) 
  if ( event == "COMBAT_LOG_EVENT_UNFILTERED" ) then
    local arg1, arg2, _, _, _, _, _, arg8, _, _, _, _, arg13 = CombatLogGetCurrentEventInfo();
    if ( arg8 ~= nil and arg8 == ForTheHorde["playerGuid"] and arg2 ~= nil and arg2 == "SPELL_AURA_APPLIED" and arg13 ~= nil ) then
      for _,trigger_table in ipairs(triggers) do
        if ( arg13 == trigger_table["trigger"] and ForTheHorde['sound_on_' .. trigger_table["var_name"]] == 1 ) then
          local buff, duration, expiration, i, doTrigger = nil, nil, nil, 1, false;
          repeat 
            buff,_,_,_,duration,expiration = UnitBuff("player",i);
            if ( buff == arg13 ) then
              if ( duration - (expiration - GetTime()) < 1 ) then
                doTrigger = true;
                break;
              end
            end
            i = i + 1;
          until( buff == nil );

          if doTrigger then
            PlayCustomSound();
          end
        end
      end
    end
  elseif event == "ADDON_LOADED" then
    if arg1 == modName then
      for _,trigger_table in ipairs(triggers) do
        if _G[trigger_table["gv"]] ~= nil then
          ForTheHorde['sound_on_' .. trigger_table["var_name"]] = _G[trigger_table["gv"]];
        else
          ForTheHorde['sound_on_' .. trigger_table["var_name"]] = trigger_table["default"];
        end
      end
      InterfaceOptions_AddCategory(ForTheHorde.gvif);
      local y = -40;
      for _,trigger_table in ipairs(triggers) do
        createOptions( trigger_table["trigger"], trigger_table["opt_name"], "sound_on_" .. trigger_table["var_name"], 10, y );
        y = y - 30;
      end
      y = y - 60;
      -- Sound override
      local chkbox_override = CreateFrame( "CheckButton","Override_CheckBox_GlobalName", ForTheHorde.gvif, "InterfaceOptionsCheckButtonTemplate" );
      if FTH_SND_OVERRIDE ~= nil and FTH_SND_OVERRIDE == 1 then
        chkbox_override:SetChecked(true);
      end
      getglobal(chkbox_override:GetName() .. 'Text'):SetText(  L["PLAY_SOUND_OVERRIDE"] );
      chkbox_override:SetPoint( "TOPLEFT", 10, y);
      chkbox_override:SetScript( "OnClick", 
        function() 
          if FTH_SND_OVERRIDE == nil or FTH_SND_OVERRIDE == 0 then
            FTH_SND_OVERRIDE = 1;
          else
            FTH_SND_OVERRIDE = 0;
          end
        end
      ); 
      -- Volume override
      y = y - 30;
      local chkbox_volume = CreateFrame( "CheckButton", "Volume_CheckBox_GlobalName", ForTheHorde.gvif, "InterfaceOptionsCheckButtonTemplate" );
      if ( FTH_USE_CUSTOM_VOLUME ) then
        chkbox_volume:SetChecked(true); 
      end
      getglobal(chkbox_volume:GetName() .. 'Text'):SetText( L["USE_CUSTOM_VOLUME"] );
      chkbox_volume:SetPoint( "TOPLEFT", 10, y );
      chkbox_volume:SetScript( "OnClick",
        function()
	  if FTH_USE_CUSTOM_VOLUME == nil or FTH_USE_CUSTOM_VOLUME == false then
            FTH_USE_CUSTOM_VOLUME = true;
	  else
	    FTH_USE_CUSTOM_VOLUME = false;
	  end
	end
      );
      y = y - 30;
      local custom_vol_text = ForTheHorde.gvif:CreateFontString( nil, "Overlay", "GameFontNormalSmall" );
      custom_vol_text:SetHeight(20);
      custom_vol_text:SetJustifyH( "LEFT" );
      custom_vol_text:SetText( L["CUSTOM_VOLUME"] );
      custom_vol_text:SetPoint( "TOPLEFT", 20, y );
      local custom_vol_entry_edit = CreateFrame( "EditBox", "Volume_EntryBox_GlobalName", ForTheHorde.gvif, "InputBoxTemplate" );
      custom_vol_entry_edit:SetAutoFocus(false);
      custom_vol_entry_edit:SetHeight(20);
      custom_vol_entry_edit:SetWidth(40);
      custom_vol_entry_edit:SetPoint("TOPLEFT", custom_vol_text, "TOPRIGHT", 20, 0 );
      custom_vol_entry_edit:SetNumeric();
      if ( FTH_CUSTOM_VOLUME ~= nil ) then
        custom_vol_entry_edit:SetText(FTH_CUSTOM_VOLUME)
	custom_vol_entry_edit:SetCursorPosition(0);
      end
      local custom_vol_save = CreateFrame("Button", "Volume_Save", ForTheHorde.gvif, "UIPanelButtonTemplate");
      custom_vol_save:SetText( L["SAVE_CHANGES"] );
      custom_vol_save:SetPoint( "TOPLEFT", custom_vol_entry_edit, "TOPRIGHT" );
      custom_vol_save:SetScript( "OnClick", 
      function()
        local volValue = custom_vol_entry_edit:GetNumber();
	if volValue ~= nil then
	  local convertedVal = tonumber(volValue);
	  if convertedVal ~= nil then
	    if convertedVal < 0 then
	      convertedVal = 0;
	    elseif convertedVal > 100 then
	      convertedVal = 100;
	    end
	    FTH_CUSTOM_VOLUME = convertedVal;
	  end
        end
      end );
      custom_vol_save:SetWidth( string.len(L["SAVE_CHANGES"])*10 );
    end
  elseif event == "PLAYER_ENTERING_WORLD" then
    ForTheHorde["playerGuid"] = UnitGUID("player"); -- Get the player's GUID for comparison
  elseif event == "PLAYER_LOGOUT" then
    for _,trigger_table in ipairs(triggers) do
      _G[trigger_table["gv"]] = ForTheHorde['sound_on_' .. trigger_table["var_name"]];
    end
  end
end

function PlayCustomSound()
  local channelVar;
  if FTH_SND_OVERRIDE ~= nil and FTH_SND_OVERRIDE == 1 then
    channelVar = "Master"; 
  else
    channelVar = "SFX";
  end
  local newVolume;
  if FTH_USE_CUSTOM_VOLUME ~= nil and FTH_USE_CUSTOM_VOLUME then
    newVolume = validVolume(FTH_CUSTOM_VOLUME);
    if newVolume ~= nil then
      local cvar = "Sound_" .. channelVar .. "Volume"
      local origVolume = GetCVar(cvar);
      SetCVar(cvar,newVolume/100);
      PlaySoundFile( "Interface\\AddOns\\ForTheHorde\\bloodlust.mp3", channelVar );
      -- A bit of a hack. There doesn't appear to be an event indicating the end of a sound, so
      -- this might not work well for all sounds.
      C_Timer.After( 3.5, function() SetCVar(cvar,origVolume) end );
    else
      PlaySoundFile( "Interface\\AddOns\\ForTheHorde\\bloodlust.mp3", channelVar );
    end
  else
    PlaySoundFile( "Interface\\AddOns\\ForTheHorde\\bloodlust.mp3", channelVar );
  end
end

function validVolume(value)
  if value ~= nil then
    local converted = tonumber(value);
    if converted < 0 then
      return 0;
    elseif converted > 100 then
      return 100;
    else
      return converted;
    end
  end
  return nil;
end

ForTheHorde.gvif:SetScript("OnEvent",ForTheHorde.gvif.OnEvent);

