-- Full Moon
-- An addon to help manage shaman cooldowns
-- Created by Evertras (bfullj@gmail.com)

-- /script local name = GetSpellTexture("Lightning Bolt"); FullMoon_Print(name);
-- /script local name, rank, icon, cost, isFunnel, powerType, castTime, minRange, maxRange = GetSpellInfo("Lightning Bolt"); FullMoon_Print(string.format("%.2f", castTime/1000));

FullMoon_Config = FullMoon_Config

-- util
function FullMoon_Print(msg)
  if (msg ~= nil) then
    DEFAULT_CHAT_FRAME:AddMessage("Full Moon - " .. msg, 1, 1, 1);
  else
    DEFAULT_CHAT_FRAME:AddMessage("Full Moon - (nil msg)");
  end
end

-- util
function FullMoon_ExtractItemID(link)
	_, _, id = string.find(link, "Hitem:([0-9]+):");
	return id;
end

function FullMoon_HideFrames()
  FullMoonFrame:Hide();
  FullMoonPvPFrame:Hide();
  FullMoonTotemFrame:Hide();
  FullMoonRacialFrame:Hide();
  -- FullMoonPvETotemFrame:Hide();
end

function FullMoon_ShowFrames()
  FullMoonFrame:Show();

  if (FullMoon_Config.PvP) then
    FullMoonPvPFrame:Show();
  end
        
  if (FullMoon_Config.totems) then
    FullMoonTotemFrame:Show();
  end
        
  if (FullMoon_Config.racial) then
    FullMoonRacialFrame:Show();
  end
  
  if (FullMoon_Config.pvetotem) then
    -- FullMoonPvETotemFrame:Show();
  end
end

function FullMoon_UnlockFrames()
  FullMoon_Config.locked = nil;
  FullMoonFrame_TitleFrame.isLocked = nil;
  FullMoonPvPFrame_TitleFrame.isLocked = nil;
  FullMoonPvPFrame_TitleFrame_AnchorBar:Show();
  FullMoonTotemFrame_TitleFrame.isLocked = nil;
  FullMoonTotemFrame_TitleFrame_AnchorBar:Show();
  FullMoonRacialFrame_TitleFrame.isLocked = nil;
  FullMoonRacialFrame_TitleFrame_AnchorBar:Show();
  -- FullMoonPvETotemFrame_TitleFrame.isLocked = nil;
  -- FullMoonPvETotemFrame_TitleFrame_AnchorBar:Show();
end

function FullMoon_LockFrames()
  FullMoon_Config.locked = 1;
  FullMoonFrame_TitleFrame.isLocked = 1;
  FullMoonPvPFrame_TitleFrame.isLocked = 1;
  FullMoonPvPFrame_TitleFrame_AnchorBar:Hide();
  FullMoonTotemFrame_TitleFrame.isLocked = 1;
  FullMoonTotemFrame_TitleFrame_AnchorBar:Hide();
  FullMoonRacialFrame_TitleFrame.isLocked = 1;
  FullMoonRacialFrame_TitleFrame_AnchorBar:Hide();
  -- FullMoonPvETotemFrame_TitleFrame.isLocked = 1;
  -- FullMoonPvETotemFrame_TitleFrame_AnchorBar:Hide();
end

function FullMoon_UpdateFrameScale()
  FullMoonFrame:SetScale(FullMoon_Config.scale);
  FullMoonPvPFrame:SetScale(FullMoon_Config.scale);
  FullMoonTotemFrame:SetScale(FullMoon_Config.scale);
  FullMoonRacialFrame:SetScale(FullMoon_Config.scale);
  -- FullMoonPvETotemFrame:SetScale(FullMoon_Config.scale);
end

function FullMoon_UpdateFrameAlpha(alpha)
  FullMoonFrame:SetAlpha(alpha);
  FullMoonPvPFrame:SetAlpha(alpha);
  FullMoonTotemFrame:SetAlpha(alpha);
  FullMoonRacialFrame:SetAlpha(alpha);
  -- FullMoonPvETotemFrame:SetAlpha(alpha);
end

-- util
function FullMoon_HasTalents()
  local maxSpent = 0;
  local name, iconTexture, pointsSpent, background = GetTalentTabInfo(1);

  maxSpent = pointsSpent;

  name, iconTexture, pointsSpent, background = GetTalentTabInfo(2);

  if (pointsSpent > maxSpent) then
    maxSpent = pointsSpent;
  end

  name, iconTexture, pointsSpent, background = GetTalentTabInfo(3);

  if (pointsSpent > maxSpent) then
    maxSpent = pointsSpent;
  end
  
  if (maxSpent > 0) then
    return true;
  else
    return false;
  end
end

-- util function copied from WoWWiki
function FullMoon_GetWords(str)
  local ret = {};
  local pos=0;
  while(true) do
    local word;
    _,pos,word=string.find(str, "^ *([^%s]+) *", pos+1);
    if(not word) then
      return ret;
    end
    table.insert(ret, word);
  end
end

function FullMoon_Slash(msg)
  local commands = FullMoon_GetWords(msg);
  
  if (#commands == 0) then
    InterfaceOptionsFrame_OpenToCategory("Full Moon");
    return;
  end
  
  if (commands[1] == "settings") then
    FullMoon_Print("Current settings as follows");
    FullMoon_Print(string.format("scale - %.2f", FullMoon_Config.scale));
    FullMoon_Print(string.format("combatfade - %.2f", FullMoon_Config.combatFade));
    
    if (FullMoon_Config.locked) then
      FullMoon_Print("lock - Locked");
    else
      FullMoon_Print("lock - Unlocked");
    end
    
    if (FullMoon_Config.PvP) then
      FullMoon_Print("pvp - PvP bars enabled");
    else
      FullMoon_Print("pvp - PvP bars disabled");
    end
    
    if (FullMoon_Config.longCDs) then
      FullMoon_Print("longcds - Long Cooldowns enabled");
    else
      FullMoon_Print("longcds - Long Cooldowns disabled");
    end
    
    if (FullMoon_Config.totems) then
      FullMoon_Print("totems - Totem bar enabled");
    else
      FullMoon_Print("totems - Totem bar disabled");
    end
    
    if (FullMoon_Config.playSound) then
      FullMoon_Print("sound - On");
    else
      FullMoon_Print("sound - Off");
    end
  end
  
  if (commands[1] == "scale") then
    if (#commands == 2 and tonumber(commands[2]) ~= nil) then
      FullMoon_Config.scale = tonumber(commands[2]);
      FullMoon_UpdateFrameScale();
    else
      FullMoon_Print("Please provide a number to scale to.");
    end
  end
  
  if (commands[1] == "pvp") then
    if (FullMoon_Config.PvP == false) then
      FullMoon_Config.PvP = true;
      FullMoon_Print("Showing PvP bars");
      FullMoonPvPFrame:Show();
    else
      FullMoon_Config.PvP = false;
      FullMoon_Print("Hiding PvP bars");
      FullMoonPvPFrame:Hide();
    end
  end
  
  if (commands[1] == "totems") then
    if (FullMoon_Config.totems == false) then
      FullMoon_Config.totems = true;
      FullMoon_Print("Showing totem bars");
      FullMoonTotemFrame:Show();
    else
      FullMoon_Config.totems = false;
      FullMoon_Print("Hiding totem bars");
      FullMoonTotemFrame:Hide();
    end
  end
  
  if (commands[1] == "racial") then
    if (FullMoon_Config.racial == false) then
      FullMoon_Config.racial = true;
      FullMoon_Print("Showing racial bar");
      FullMoonRacialFrame:Show();
    else
      FullMoon_Config.racial = false;
      FullMoon_Print("Hiding racial bar");
      FullMoonRacialFrame:Hide();
    end
  end
  
  if (commands[1] == "longcd" or commands[1] == "longcds") then
    if (FullMoon_Config.longCDs == false) then
      FullMoon_Config.longCDs = true;
      FullMoon_Print("Showing long cooldowns");
      FullMoonFrame_InfoFrame_HB1_UptimeBar:Show();
      FullMoonFrame_InfoFrame_HB2_UptimeBar:Show();
      FullMoonFrame_InfoFrame_HB1BG:Show();
      FullMoonFrame_InfoFrame_HB2BG:Show();
      
      -- May or may not have to hide some of those
      FullMoon_ReInit();
    else
      FullMoon_Config.longCDs = false;
      FullMoon_Print("Hiding long cooldowns");
      FullMoonFrame_InfoFrame_HB1_UptimeBar:Hide();
      FullMoonFrame_InfoFrame_HB2_UptimeBar:Hide();
      FullMoonFrame_InfoFrame_HB1BG:Hide();
      FullMoonFrame_InfoFrame_HB2BG:Hide();
    end
  end
  
  if (commands[1] == "combatfade") then
    if (#commands == 2 and tonumber(commands[2]) ~= nil) then
      FullMoon_Config.combatFade = tonumber(commands[2]);
      if (InCombatLockdown() == nil) then
        FullMoon_UpdateFrameAlpha(FullMoon_Config.combatFade);
      end
    else
      FullMoon_Print("Please provide a number between 0.0 and 1.0 to fade to.");
    end
  end
  
  if (commands[1] == "lock") then
    if (FullMoon_Config.locked) then
      FullMoon_UnlockFrames();
      FullMoon_Print("Frames unlocked");
    else
      FullMoon_LockFrames();
      FullMoon_Print("Frames locked");
    end
  end
  
  if (commands[1] == "sound") then
    if (FullMoon_Config.playSound) then
      FullMoon_Config.playSound = false;
      FullMoon_Print("Sounds OFF");
    else
      FullMoon_Config.playSound = true;
      FullMoon_Print("Sounds ON");
    end
  end
  
  if (commands[1] == "elemental") then
    if (FullMoon_Config.elemental) then
      FullMoon_Config.elemental = false;
      FullMoon_Print("Full Moon DISABLED for Elemental");
      
      if (FM_mode == 1) then
        FullMoon_HideFrames();
      end
    else
      FullMoon_Config.elemental = true;
      FullMoon_Print("Full Moon ENABLED for Elemental");
      
      if (FM_mode == 1) then
        FullMoon_ShowFrames();
      end
    end
  end
  
  if (commands[1] == "enhancement") then
    if (FullMoon_Config.enhancement) then
      FullMoon_Config.enhancement = false;
      FullMoon_Print("Full Moon DISABLED for Enhancement");
      
      if (FM_mode == 2) then
        FullMoon_HideFrames();
      end
    else
      FullMoon_Config.enhancement = true;
      FullMoon_Print("Full Moon ENABLED for Enhancement");
      
      if (FM_mode == 2) then
        FullMoon_ShowFrames();
      end
    end
  end
  
  if (commands[1] == "restoration") then
    if (FullMoon_Config.restoration) then
      FullMoon_Config.restoration = false;
      FullMoon_Print("Full Moon DISABLED for Restoration");
      
      if (FM_mode == 3) then
        FullMoon_HideFrames();
      end
    else
      FullMoon_Config.restoration = true;
      FullMoon_Print("Full Moon ENABLED for Restoration");
      
      if (FM_mode == 3) then
        FullMoon_ShowFrames();
      end
    end
  end
  
  if (commands[1] == "thanks") then
    FullMoon_Print("Thanks to the following people:");
    FullMoon_Print("Demyst for doing ULTRA HARD JOB of retyping an output line for me in forums");
    FullMoon_Print("Shyama for doing the same, but TWICE!");
    FullMoon_Print("Ktu for helping me fix the Titan-forged Runes");
    FullMoon_Print("The shaman forums as a whole for the awesome support, <3 you guys!");
  end
end

function FullMoon_UpdateShield()
  local name, rank, icon, count, debuffType, duration, expirationTime, unitCaster, isStealable = UnitBuff("player", FM_SpellNames["Lightning Shield"]);

  if (count) then
    FullMoonFrame_TitleFrame_TitleBar_ShieldIcon:SetTexture(FM_SpellIcons["Lightning Shield"]);
    FullMoonFrame_TitleFrame_TitleBar_ShieldIcon_Text:SetText(count);
  
    if (FM_mode == 2 and count < 3) then
      FullMoonFrame_TitleFrame_TitleBar_ShieldIcon:SetVertexColor(1.0, 0.2*count, 0.2*count);
    else
      if (count == 1) then
        FullMoonFrame_TitleFrame_TitleBar_ShieldIcon:SetVertexColor(1.0, 0.2, 0.2);
      else
        FullMoonFrame_TitleFrame_TitleBar_ShieldIcon:SetVertexColor(1.0, 1.0, 1.0);
      end
    end

  else
    local name, rank, icon, count, debuffType, duration, expirationTime, unitCaster, isStealable = UnitBuff("player", FM_SpellNames["Water Shield"]);

    if (count) then
      FullMoonFrame_TitleFrame_TitleBar_ShieldIcon:SetTexture(FM_SpellIcons["Water Shield"]);
      FullMoonFrame_TitleFrame_TitleBar_ShieldIcon_Text:SetText(count);

      if (count == 1) then
        FullMoonFrame_TitleFrame_TitleBar_ShieldIcon:SetVertexColor(1.0, 0.2, 0.2);
      else
        FullMoonFrame_TitleFrame_TitleBar_ShieldIcon:SetVertexColor(1.0, 1.0, 1.0);
      end
    else
      local name, rank, icon, count, debuffType, duration, expirationTime, unitCaster, isStealable = UnitBuff("player", FM_SpellNames["Earth Shield"]);
      
      if (count) then
        FullMoonFrame_TitleFrame_TitleBar_ShieldIcon:SetTexture("Interface\\Icons\\Spell_Nature_SkinofEarth");
        FullMoonFrame_TitleFrame_TitleBar_ShieldIcon_Text:SetText(count);
        
        if (count < 3) then
          FullMoonFrame_TitleFrame_TitleBar_ShieldIcon:SetVertexColor(1.0, 0.2*count, 0.2*count);
        else
          FullMoonFrame_TitleFrame_TitleBar_ShieldIcon:SetVertexColor(1.0, 1.0, 1.0);
        end
      else
        FullMoonFrame_TitleFrame_TitleBar_ShieldIcon:SetTexture("Interface\\Icons\\INV_Shield_45");
        FullMoonFrame_TitleFrame_TitleBar_ShieldIcon:SetVertexColor(0.1, 0.1, 0.1);
        FullMoonFrame_TitleFrame_TitleBar_ShieldIcon_Text:SetText("");
      end
    end
  end
end

function FullMoon_InitSpec()
  -- Figure out the spec of the shaman
  local maxSpent = 0;
  local name, iconTexture, pointsSpent, background = GetTalentTabInfo(1);

  maxSpent = pointsSpent;
  FM_mode = 1;
  FM_modeName = name;

  name, iconTexture, pointsSpent, background = GetTalentTabInfo(2);

  if (pointsSpent > maxSpent) then
    maxSpent = pointsSpent;
    FM_mode = 2;
    FM_modeName = name;
  end

  name, iconTexture, pointsSpent, background = GetTalentTabInfo(3);

  if (pointsSpent > maxSpent) then
    maxSpent = pointsSpent;
    FM_mode = 3;
    FM_modeName = name;
  end
  
  -- Apply icons depending on spec
  if (FM_mode == 1) then
    FullMoonFrame_TitleFrame_VBR_CDBar_Tex:SetTexture(FM_SpellIcons["Lava Burst"]);
    FullMoonFrame_TitleFrame_VBC_CDBar_Tex:SetTexture(FM_SpellIcons["Flame Shock"]);
    FullMoonFrame_TitleFrame_VBL_CDBar_Tex:SetTexture(FM_SpellIcons["Chain Lightning"]);
    FullMoonFrame_InfoFrame_HB1_UptimeBar_Tex:SetTexture(FM_SpellIcons["Elemental Mastery"]);
    FullMoonFrame_InfoFrame_HB2_UptimeBar_Tex:SetTexture(FM_SpellIcons["Thunderstorm"]);
    
    FullMoonFrame_TitleFrame_TitleBar:SetMinMaxValues(0,180);
    FullMoonFrame_TitleFrame_TitleBar:SetStatusBarColor(1.0,0.5,0);
    
    FM_VBRName = FM_SpellNames["Lava Burst"];
    FM_VBLName = FM_SpellNames["Chain Lightning"];
    
    FM_HB1Name = FM_SpellNames["Elemental Mastery"];
    FM_HB1Runtime = 0;
    
    FM_HB2Name = FM_SpellNames["Thunderstorm"];
    FM_HB2Runtime = 0;
    
    -- We care about fire nova totem
    FullMoonTotemFrame_InfoFrame_HB4_UptimeBar:Show();
    FullMoonTotemFrame_InfoFrame_HB4BG:Show();
    
    -- We want lightning bolt cast time
    FullMoonFrame_TitleFrame_LBBG:Show();
    FullMoonFrame_TitleFrame_LB_CastBar:Show();
    
    -- After all that, see if we should hide the frame
    if (FullMoon_Config.elemental) then
      FullMoon_ShowFrames();
    else
      FullMoon_HideFrames();
    end
  end
  
  if (FM_mode == 2) then
    FullMoonFrame_TitleFrame_VBR_CDBar_Tex:SetTexture(FM_SpellIcons["Stormstrike"]);
    FullMoonFrame_TitleFrame_VBC_CDBar_Tex:SetTexture(FM_SpellIcons["Earth Shock"]);
    FullMoonFrame_TitleFrame_VBL_CDBar_Tex:SetTexture(FM_SpellIcons["Lava Lash"]);
    FullMoonFrame_InfoFrame_HB1_UptimeBar_Tex:SetTexture(FM_SpellIcons["Feral Spirit"]);
    FullMoonFrame_InfoFrame_HB2_UptimeBar_Tex:SetTexture(FM_SpellIcons["Shamanistic Rage"]);
    
    FullMoonFrame_TitleFrame_TitleBar:SetMinMaxValues(0,5);
    
    FM_VBRName = FM_SpellNames["Stormstrike"];
    FM_VBLName = FM_SpellNames["Lava Lash"];
    
    FM_HB1Name = FM_SpellNames["Feral Spirit"];
    FM_HB1Runtime = 45;
    
    FM_HB2Name = FM_SpellNames["Shamanistic Rage"];
    FM_HB2Runtime = 15;
    
    -- We care about fire nova totem
    FullMoonTotemFrame_InfoFrame_HB4_UptimeBar:Show();
    FullMoonTotemFrame_InfoFrame_HB4BG:Show();
    
    -- We don't want lightning bolt cast time
    FullMoonFrame_TitleFrame_LBBG:Hide();
    FullMoonFrame_TitleFrame_LB_CastBar:Hide();
    
    -- After all that, see if we should hide the frame
    if (FullMoon_Config.enhancement) then
      FullMoon_ShowFrames();
    else
      FullMoon_HideFrames();
    end
  end
  
  if (FM_mode == 3) then
    FullMoonFrame_TitleFrame_VBL_CDBar_Tex:SetTexture(FM_SpellIcons["Riptide"]);
    FullMoonFrame_TitleFrame_VBC_CDBar_Tex:SetTexture(FM_SpellIcons["Wind Shock"]);
    FullMoonFrame_TitleFrame_VBR_CDBar_Tex:SetTexture(FM_SpellIcons["Earth Shield"]);
    FullMoonFrame_InfoFrame_HB1_UptimeBar_Tex:SetTexture(FM_SpellIcons["Nature's Swiftness"]);
    FullMoonFrame_InfoFrame_HB2_UptimeBar_Tex:SetTexture(FM_SpellIcons["Tidal Force"]);
    FullMoonFrame_TitleFrame_TitleBar_BarText:SetFont("Fonts\\FRIZQT__.TTF", 15, "OUTLINE");
    
    FullMoonFrame_TitleFrame_TitleBar:SetMinMaxValues(0,150);
    FullMoonFrame_TitleFrame_TitleBar:SetStatusBarColor(0.75,1,0);

    FM_VBLName = FM_SpellNames["Riptide"];
    
    FM_HB1Name = FM_SpellNames["Nature's Swiftness"];
    FM_HB1Runtime = 0;
    
    FM_HB2Name = FM_SpellNames["Tidal Force"];
    FM_HB2Runtime = 20;
    
    -- We don't care about fire nova totem
    FullMoonTotemFrame_InfoFrame_HB4_UptimeBar:Hide();
    FullMoonTotemFrame_InfoFrame_HB4BG:Hide();
    
    -- We don't want lightning bolt cast time
    FullMoonFrame_TitleFrame_LBBG:Hide();
    FullMoonFrame_TitleFrame_LB_CastBar:Hide();
    
    -- After all that, see if we should hide the frame
    if (FullMoon_Config.restoration) then
      FullMoon_ShowFrames();
    else
      FullMoon_HideFrames();
    end
  end
end

function FullMoon_InitFrames()
  -- Title Bar
  FullMoonFrame_TitleFrame:SetBackdropColor(0,0,0);
  FullMoonFrame_TitleFrame_TitleBar:SetMinMaxValues(0,1);
  FullMoonFrame_TitleFrame_TitleBar:SetValue(0);
  FullMoonFrame_TitleFrame_TitleBar_BarText:SetText("0");
  FullMoonFrame_TitleFrame_TitleBar_BarText:SetTextColor(1.0, 1.0, 1.0);
  FullMoonFrame_TitleFrame_TitleBar_BarText:SetFont("Fonts\\FRIZQT__.TTF", 11, "OUTLINE");
  
  -- GCD
  FullMoonFrame_TitleFrame_GCD_CDBar:SetStatusBarColor(0.0, 0.0, 1.0);
  FullMoonFrame_TitleFrame_GCD_CDBar:SetMinMaxValues(0, 150);
  FullMoonFrame_TitleFrame_GCD_CDBar_BarText:SetTextColor(1.0, 1.0, 1.0);
  FullMoonFrame_TitleFrame_GCD_CDBar_BarText:SetFont("Fonts\\FRIZQT__.TTF", 11, "OUTLINE");
  
  -- Shield tracker text
  FullMoonFrame_TitleFrame_TitleBar_ShieldIcon_Text:SetFont("Fonts\\FRIZQT__.TTF", 17, "THICKOUTLINE");
  FullMoonFrame_TitleFrame_TitleBar_ShieldIcon_Text:SetTextColor(1.0, 1.0, 1.0);
  
  -- BGs
  FullMoonFrame_InfoFrame_HB1BG:SetBackdropColor(0,0,0);
  FullMoonFrame_InfoFrame_HB2BG:SetBackdropColor(0,0,0);
  FullMoonFrame_TitleFrame_VBRBG:SetBackdropColor(0,0,0);
  FullMoonFrame_TitleFrame_VBCBG:SetBackdropColor(0,0,0);
  FullMoonFrame_TitleFrame_VBLBG:SetBackdropColor(0,0,0);
  FullMoonFrame_TitleFrame_LBBG:SetBackdropColor(0,0,0);
  FullMoonFrame_TitleFrame_GCDBG:SetBackdropColor(0.5,0.5,0.5);
  
  -- Long cooldown text
  FullMoonFrame_InfoFrame_HB1_UptimeBar_BarText:SetFont("Fonts\\FRIZQT__.TTF", 12, "OUTLINE");
  FullMoonFrame_InfoFrame_HB1_UptimeBar_BarText:SetTextColor(1.0, 1.0, 1.0);
  FullMoonFrame_InfoFrame_HB2_UptimeBar_BarText:SetFont("Fonts\\FRIZQT__.TTF", 12, "OUTLINE");
  FullMoonFrame_InfoFrame_HB2_UptimeBar_BarText:SetTextColor(1.0, 1.0, 1.0);
  
  -- Setup the short CD bars
  FullMoonFrame_TitleFrame_VBR_CDBar:SetOrientation("VERTICAL");
  FullMoonFrame_TitleFrame_VBR_CDBar:SetMinMaxValues(0,800);
  FullMoonFrame_TitleFrame_VBR_CDBar:SetValue(0);
  FullMoonFrame_TitleFrame_VBR_CDBar_BarText:SetText("0.0");
  FullMoonFrame_TitleFrame_VBR_CDBar_BarText:SetFont("Fonts\\FRIZQT__.TTF", 12, "OUTLINE");
  FullMoonFrame_TitleFrame_VBR_CDBar_BarText:SetTextColor(1.0, 1.0, 1.0);
  FullMoonFrame_TitleFrame_VBR_CDBar_IconText:SetFont("Fonts\\FRIZQT__.TTF", 17, "THICKOUTLINE");
  FullMoonFrame_TitleFrame_VBR_CDBar_IconText:SetTextColor(1.0, 1.0, 1.0);
  
  FullMoonFrame_TitleFrame_VBC_CDBar:SetOrientation("VERTICAL");
  FullMoonFrame_TitleFrame_VBC_CDBar:SetMinMaxValues(0,600);
  FullMoonFrame_TitleFrame_VBC_CDBar:SetValue(0);
  FullMoonFrame_TitleFrame_VBC_CDBar_BarText:SetText("0.0");
  FullMoonFrame_TitleFrame_VBC_CDBar_BarText:SetFont("Fonts\\FRIZQT__.TTF", 12, "OUTLINE");
  FullMoonFrame_TitleFrame_VBC_CDBar_BarText:SetTextColor(1.0, 1.0, 1.0);
  
  FullMoonFrame_TitleFrame_VBL_CDBar:SetOrientation("VERTICAL");
  FullMoonFrame_TitleFrame_VBL_CDBar:SetMinMaxValues(0,600);
  FullMoonFrame_TitleFrame_VBL_CDBar:SetValue(0);
  FullMoonFrame_TitleFrame_VBL_CDBar_BarText:SetText("0.0");
  FullMoonFrame_TitleFrame_VBL_CDBar_BarText:SetFont("Fonts\\FRIZQT__.TTF", 12, "OUTLINE");
  FullMoonFrame_TitleFrame_VBL_CDBar_BarText:SetTextColor(1.0, 1.0, 1.0);
  
  FullMoonFrame_TitleFrame_LB_CastBar_Tex:SetTexture(FM_SpellIcons["Lightning Bolt"]);
  FullMoonFrame_TitleFrame_LB_CastBar:SetOrientation("VERTICAL");
  FullMoonFrame_TitleFrame_LB_CastBar:SetMinMaxValues(0,300);
  FullMoonFrame_TitleFrame_LB_CastBar:SetValue(0);
  FullMoonFrame_TitleFrame_LB_CastBar:SetStatusBarColor(0,0.5,1);
  FullMoonFrame_TitleFrame_LB_CastBar_BarText:SetText("0.0");
  FullMoonFrame_TitleFrame_LB_CastBar_BarText:SetFont("Fonts\\FRIZQT__.TTF", 12, "OUTLINE");
  FullMoonFrame_TitleFrame_LB_CastBar_BarText:SetTextColor(1.0, 1.0, 1.0);
  
  -- Setup the PvP bars
  FullMoonPvPFrame_InfoFrame_HB1BG:SetBackdropColor(0,0,0);
  FullMoonPvPFrame_InfoFrame_HB2BG:SetBackdropColor(0,0,0);
  
  FullMoonPvPFrame_InfoFrame_HB1_UptimeBar:SetMinMaxValues(0, 45);
  FullMoonPvPFrame_InfoFrame_HB1_UptimeBar_Tex:SetTexture(FM_SpellIcons["Hex"]);
  FullMoonPvPFrame_InfoFrame_HB1_UptimeBar_BarText:SetFont("Fonts\\FRIZQT__.TTF", 12, "OUTLINE");
  FullMoonPvPFrame_InfoFrame_HB1_UptimeBar_BarText:SetTextColor(1.0, 1.0, 1.0);
  
  FullMoonPvPFrame_InfoFrame_HB2_UptimeBar:SetMinMaxValues(0, 120);
  FullMoonPvPFrame_InfoFrame_HB2_UptimeBar_BarText:SetFont("Fonts\\FRIZQT__.TTF", 12, "OUTLINE");
  FullMoonPvPFrame_InfoFrame_HB2_UptimeBar_BarText:SetTextColor(1.0, 1.0, 1.0);
  
  -- Set up PvP trinket icon depending on faction
  if (FM_Race == "Draenei") then
    FullMoonPvPFrame_InfoFrame_HB2_UptimeBar_Tex:SetTexture("Interface\\Icons\\INV_Jewelry_Necklace_37");
  else
    FullMoonPvPFrame_InfoFrame_HB2_UptimeBar_Tex:SetTexture("Interface\\Icons\\INV_Jewelry_Necklace_38");
  end
  
  -- Set up Totem bars
  FullMoonTotemFrame_InfoFrame_HB1BG:SetBackdropColor(0,0,0);
  FullMoonTotemFrame_InfoFrame_HB2BG:SetBackdropColor(0,0,0);
  FullMoonTotemFrame_InfoFrame_HB3BG:SetBackdropColor(0,0,0);
  FullMoonTotemFrame_InfoFrame_HB4BG:SetBackdropColor(0,0,0);
  
  FullMoonTotemFrame_InfoFrame_HB1_UptimeBar:SetMinMaxValues(0, 15);
  FullMoonTotemFrame_InfoFrame_HB1_UptimeBar_Tex:SetTexture(FM_SpellIcons["Grounding Totem"]);
  FullMoonTotemFrame_InfoFrame_HB1_UptimeBar_BarText:SetFont("Fonts\\FRIZQT__.TTF", 12, "OUTLINE");
  FullMoonTotemFrame_InfoFrame_HB1_UptimeBar_BarText:SetTextColor(1.0, 1.0, 1.0);
  
  FullMoonTotemFrame_InfoFrame_HB2_UptimeBar:SetMinMaxValues(0, 15);
  FullMoonTotemFrame_InfoFrame_HB2_UptimeBar_Tex:SetTexture(FM_SpellIcons["Earthbind Totem"]);
  FullMoonTotemFrame_InfoFrame_HB2_UptimeBar_BarText:SetFont("Fonts\\FRIZQT__.TTF", 12, "OUTLINE");
  FullMoonTotemFrame_InfoFrame_HB2_UptimeBar_BarText:SetTextColor(1.0, 1.0, 1.0);
  
  FullMoonTotemFrame_InfoFrame_HB3_UptimeBar:SetMinMaxValues(0, 30);
  FullMoonTotemFrame_InfoFrame_HB3_UptimeBar_Tex:SetTexture(FM_SpellIcons["Stoneclaw Totem"]);
  FullMoonTotemFrame_InfoFrame_HB3_UptimeBar_BarText:SetFont("Fonts\\FRIZQT__.TTF", 12, "OUTLINE");
  FullMoonTotemFrame_InfoFrame_HB3_UptimeBar_BarText:SetTextColor(1.0, 1.0, 1.0);
  
  FullMoonTotemFrame_InfoFrame_HB4_UptimeBar:SetMinMaxValues(0, 15);
  FullMoonTotemFrame_InfoFrame_HB4_UptimeBar_Tex:SetTexture(FM_SpellIcons["Fire Nova Totem"]);
  FullMoonTotemFrame_InfoFrame_HB4_UptimeBar_BarText:SetFont("Fonts\\FRIZQT__.TTF", 12, "OUTLINE");
  FullMoonTotemFrame_InfoFrame_HB4_UptimeBar_BarText:SetTextColor(1.0, 1.0, 1.0);
  
  -- Setup the Racial bar
  FullMoonRacialFrame_InfoFrame_BG:SetBackdropColor(0,0,0);
  FullMoonRacialFrame_InfoFrame_BG:SetBackdropColor(0,0,0);
  
  FullMoonRacialFrame_InfoFrame_UptimeBar:SetMinMaxValues(0, 45);
  FullMoonRacialFrame_InfoFrame_UptimeBar_BarText:SetFont("Fonts\\FRIZQT__.TTF", 12, "OUTLINE");
  FullMoonRacialFrame_InfoFrame_UptimeBar_BarText:SetTextColor(1.0, 1.0, 1.0);
  
  -- Set racial icon based on race
  if (FM_Race == "Orc") then
    FullMoonRacialFrame_InfoFrame_UptimeBar_Tex:SetTexture(FM_SpellIcons["Blood Fury"]);
    FM_RacialName = FM_SpellNames["Blood Fury"];
    FM_RacialRuntime = 15;
  end
  
  if (FM_Race == "Troll") then
    FullMoonRacialFrame_InfoFrame_UptimeBar_Tex:SetTexture(FM_SpellIcons["Berserking"]);
    FM_RacialName = FM_SpellNames["Berserking"];
    FM_RacialRuntime = 10;
  end
  
  if (FM_Race == "Tauren") then
    FullMoonRacialFrame_InfoFrame_UptimeBar_Tex:SetTexture(FM_SpellIcons["War Stomp"]);
    FM_RacialName = FM_SpellNames["War Stomp"];
    FM_RacialRuntime = 0;
  end
  
  if (FM_Race == "Draenei") then
    FullMoonRacialFrame_InfoFrame_UptimeBar_Tex:SetTexture(FM_SpellIcons["Gift of the Naaru"]);
    FM_RacialName = FM_SpellNames["Gift of the Naaru"];
    FM_RacialRuntime = 15;
  end
  
  -- Setup the anchors
  FullMoonPvPFrame_TitleFrame_AnchorBar_AnchorText:SetText("MOVE ME");
  FullMoonPvPFrame_TitleFrame_AnchorBar:SetStatusBarColor(0.0, 0.0, 1.0);
  
  FullMoonTotemFrame_TitleFrame_AnchorBar_AnchorText:SetText("MOVE ME");
  FullMoonTotemFrame_TitleFrame_AnchorBar:SetStatusBarColor(0.0, 0.0, 1.0);
  
  FullMoonRacialFrame_TitleFrame_AnchorBar_AnchorText:SetText("MOVE ME");
  FullMoonRacialFrame_TitleFrame_AnchorBar:SetStatusBarColor(0.0, 0.0, 1.0);
end

function FullMoon_CastRacial()
  FM_RacialRunning = 1;
  
  if (FM_RacialRuntime > 0) then
    FullMoonRacialFrame_InfoFrame_UptimeBar:SetMinMaxValues(0,FM_RacialRuntime*10);
    FullMoonRacialFrame_InfoFrame_UptimeBar:SetValue(FM_RacialRuntime*10);
    FullMoonRacialFrame_InfoFrame_UptimeBar:SetStatusBarColor(0,1.0,1.0);
    FullMoonRacialFrame_InfoFrame_UptimeBar_BarText:SetText(FM_RacialRuntime);
  else
    local name, rank, icon, count, debuffType, duration, expirationTime, unitCaster, isStealable = UnitBuff("player", FM_RacialName);

    if (duration) then
      FullMoonRacialFrame_InfoFrame_UptimeBar:SetMinMaxValues(0,duration*10);
      FullMoonRacialFrame_InfoFrame_UptimeBar:SetValue(duration*10);
      FullMoonRacialFrame_InfoFrame_UptimeBar:SetStatusBarColor(0,1.0,1.0);
      FullMoonRacialFrame_InfoFrame_UptimeBar_BarText:SetText(expirationTime - GetTime());
    end
  end
end

function FullMoon_CastHB1()
  FM_HB1Running = 1;

  if (FM_mode == 3) then
    FullMoonFrame_InfoFrame_HB1_UptimeBar:SetMinMaxValues(0, 1);
    FullMoonFrame_InfoFrame_HB1_UptimeBar:SetValue(1);
    FullMoonFrame_InfoFrame_HB1_UptimeBar:SetStatusBarColor(0,1.0,1.0);
    FullMoonFrame_InfoFrame_HB1_UptimeBar_BarText:SetText("ACTIVE");
  else
    if (FM_HB1Runtime > 0) then
      FullMoonFrame_InfoFrame_HB1_UptimeBar:SetMinMaxValues(0,FM_HB1Runtime*10);
      FullMoonFrame_InfoFrame_HB1_UptimeBar:SetValue(FM_HB1Runtime*10);
      FullMoonFrame_InfoFrame_HB1_UptimeBar:SetStatusBarColor(0,1.0,1.0);
      FullMoonFrame_InfoFrame_HB1_UptimeBar_BarText:SetText(FM_HB1Runtime);
    else
      local name, rank, icon, count, debuffType, duration, expirationTime, unitCaster, isStealable = UnitBuff("player", FM_HB1Name);

      if (duration) then
        FullMoonFrame_InfoFrame_HB1_UptimeBar:SetMinMaxValues(0,duration*10);
        FullMoonFrame_InfoFrame_HB1_UptimeBar:SetValue(duration*10);
        FullMoonFrame_InfoFrame_HB1_UptimeBar:SetStatusBarColor(0,1.0,1.0);
        FullMoonFrame_InfoFrame_HB1_UptimeBar_BarText:SetText(expirationTime - GetTime());
      end
    end
  end
end

function FullMoon_CastHB2()
  FM_HB2Running = 1;

  if (FM_HB2Runtime > 0) then
    FullMoonFrame_InfoFrame_HB2_UptimeBar:SetMinMaxValues(0,150);
    FullMoonFrame_InfoFrame_HB2_UptimeBar:SetValue(150);
    FullMoonFrame_InfoFrame_HB2_UptimeBar:SetStatusBarColor(0,1.0,1.0);
    FullMoonFrame_InfoFrame_HB2_UptimeBar_BarText:SetText("15");
  else
    local name, rank, icon, count, debuffType, duration, expirationTime, unitCaster, isStealable = UnitBuff("player", FM_HB2Name);
    
    if (duration) then
      FullMoonFrame_InfoFrame_HB2_UptimeBar:SetMinMaxValues(0,duration*10);
      FullMoonFrame_InfoFrame_HB2_UptimeBar:SetValue(duration*10);
      FullMoonFrame_InfoFrame_HB2_UptimeBar:SetStatusBarColor(0,1.0,1.0);
      FullMoonFrame_InfoFrame_HB2_UptimeBar_BarText:SetText(expirationTime - GetTime());
    end
  end
end

function FullMoon_CastGrounding()
  FM_GroundingRunning = 1;
  local start, duration, enabled = GetSpellCooldown(FM_SpellNames["Grounding Totem"]);
  
  FullMoonTotemFrame_InfoFrame_HB1_UptimeBar:SetMinMaxValues(0,150);
  FullMoonTotemFrame_InfoFrame_HB1_UptimeBar:SetValue((15 - duration)*10);
  FullMoonTotemFrame_InfoFrame_HB1_UptimeBar:SetStatusBarColor(1.0,0,0);
end

function FullMoon_CastEarthbind()
  FM_EarthbindRunning = 1;
  local start, duration, enabled = GetSpellCooldown(FM_SpellNames["Earthbind Totem"]);
  
  FullMoonTotemFrame_InfoFrame_HB2_UptimeBar:SetMinMaxValues(0,150);
  FullMoonTotemFrame_InfoFrame_HB2_UptimeBar:SetValue(0);
  FullMoonTotemFrame_InfoFrame_HB2_UptimeBar:SetStatusBarColor(1.0,0,0);
end

function FullMoon_CastStoneclaw()
  FM_StoneclawRunning = 1;
  local start, duration, enabled = GetSpellCooldown(FM_SpellNames["Stoneclaw Totem"]);
  
  FullMoonTotemFrame_InfoFrame_HB3_UptimeBar:SetMinMaxValues(0,300);
  FullMoonTotemFrame_InfoFrame_HB3_UptimeBar:SetValue(0);
  FullMoonTotemFrame_InfoFrame_HB3_UptimeBar:SetStatusBarColor(1.0,0,0);
end

function FullMoon_CastFireNova()
  FM_NovaRunning = 1;

  FullMoonTotemFrame_InfoFrame_HB4_UptimeBar:SetMinMaxValues(0,40);
  FullMoonTotemFrame_InfoFrame_HB4_UptimeBar:SetValue(40);
  FullMoonTotemFrame_InfoFrame_HB4_UptimeBar:SetStatusBarColor(0,1.0,1.0);
  FullMoonTotemFrame_InfoFrame_HB4_UptimeBar_BarText:SetText("4");
end

function FullMoon_FireNovaComplete()
  FM_NovaRunning = 2;
  
  local start, duration, enabled = GetSpellCooldown(FM_SpellNames["Fire Nova Totem"]);
  
  FullMoonTotemFrame_InfoFrame_HB4_UptimeBar:SetMinMaxValues(0,150);
  FullMoonTotemFrame_InfoFrame_HB4_UptimeBar:SetValue((40 + (15-duration))*10);
  FullMoonTotemFrame_InfoFrame_HB4_UptimeBar:SetStatusBarColor(1.0,0,0);
  FullMoonTotemFrame_InfoFrame_HB4_UptimeBar_BarText:SetText((40 + (15-duration))*10);
end

function FullMoon_CastHex()
  FM_HexRunning = 1;
  local start, duration, enabled = GetSpellCooldown(FM_SpellNames["Hex"]);

  FullMoonPvPFrame_InfoFrame_HB1_UptimeBar:SetMinMaxValues(0,45);
  FullMoonPvPFrame_InfoFrame_HB1_UptimeBar:SetValue(0);
  FullMoonPvPFrame_InfoFrame_HB1_UptimeBar:SetStatusBarColor(1.0,0,0);
  FullMoonPvPFrame_InfoFrame_HB1_UptimeBar_BarText:SetText("0");
end

function FullMoon_UseTrinket()
  FM_HexRunning = 1;
  local start, duration, enabled = GetSpellCooldown(FM_SpellNames["Hex"]);

  FullMoonPvPFrame_InfoFrame_HB1_UptimeBar:SetMinMaxValues(0,45);
  FullMoonPvPFrame_InfoFrame_HB1_UptimeBar:SetValue(0);
  FullMoonPvPFrame_InfoFrame_HB1_UptimeBar:SetStatusBarColor(1.0,0,0);
  FullMoonPvPFrame_InfoFrame_HB1_UptimeBar_BarText:SetText("0");
end

function FullMoon_CastVBR()
  FM_SSRunning = 1;
  local fm_start, fm_duration, fm_enabled = GetSpellCooldown(FM_VBRName);

  FullMoonFrame_TitleFrame_VBR_CDBar:SetValue(fm_duration*100);
  FullMoonFrame_TitleFrame_VBR_CDBar:SetStatusBarColor(1.0,0,0);
  FullMoonFrame_TitleFrame_VBR_CDBar_BarText:SetText(string.format("%.1f", fm_duration));
end

function FullMoon_CastShock()
  FM_ESRunning = 1;
  local fm_start, fm_duration, fm_enabled = GetSpellCooldown(FM_SpellNames["Earth Shock"]);

  FullMoonFrame_TitleFrame_VBC_CDBar:SetValue(fm_duration*100);
  FullMoonFrame_TitleFrame_VBC_CDBar:SetStatusBarColor(1.0,0,0);
  FullMoonFrame_TitleFrame_VBC_CDBar_BarText:SetText(string.format("%.1f", fm_duration));
end

function FullMoon_CastVBL()
  FM_LLRunning = 1;
  local fm_start, fm_duration, fm_enabled = GetSpellCooldown(FM_VBLName);

  FullMoonFrame_TitleFrame_VBL_CDBar:SetValue(fm_duration*100);
  FullMoonFrame_TitleFrame_VBL_CDBar:SetStatusBarColor(1.0,0,0);
  FullMoonFrame_TitleFrame_VBL_CDBar_BarText:SetText(string.format("%.1f", fm_duration));
end

function FullMoon_GroundingCooldownFinished()
  FM_GroundingRunning = 0;
  
  FullMoonTotemFrame_InfoFrame_HB1_UptimeBar:SetMinMaxValues(0,1);
  FullMoonTotemFrame_InfoFrame_HB1_UptimeBar:SetValue(1);
  FullMoonTotemFrame_InfoFrame_HB1_UptimeBar:SetStatusBarColor(0,1.0,0);
  FullMoonTotemFrame_InfoFrame_HB1_UptimeBar_BarText:SetText("READY");
end

function FullMoon_EarthbindCooldownFinished()
  FM_EarthbindRunning = 0;
  
  FullMoonTotemFrame_InfoFrame_HB2_UptimeBar:SetMinMaxValues(0,1);
  FullMoonTotemFrame_InfoFrame_HB2_UptimeBar:SetValue(1);
  FullMoonTotemFrame_InfoFrame_HB2_UptimeBar:SetStatusBarColor(0,1.0,0);
  FullMoonTotemFrame_InfoFrame_HB2_UptimeBar_BarText:SetText("READY");
end

function FullMoon_StoneclawCooldownFinished()
  FM_StoneclawRunning = 0;
  
  FullMoonTotemFrame_InfoFrame_HB3_UptimeBar:SetMinMaxValues(0,1);
  FullMoonTotemFrame_InfoFrame_HB3_UptimeBar:SetValue(1);
  FullMoonTotemFrame_InfoFrame_HB3_UptimeBar:SetStatusBarColor(0,1.0,0);
  FullMoonTotemFrame_InfoFrame_HB3_UptimeBar_BarText:SetText("READY");
end

function FullMoon_FireNovaCooldownFinished()
  FM_NovaRunning = 0;
  
  FullMoonTotemFrame_InfoFrame_HB4_UptimeBar:SetMinMaxValues(0,1);
  FullMoonTotemFrame_InfoFrame_HB4_UptimeBar:SetValue(1);
  FullMoonTotemFrame_InfoFrame_HB4_UptimeBar:SetStatusBarColor(0,1.0,0);
  FullMoonTotemFrame_InfoFrame_HB4_UptimeBar_BarText:SetText("READY");
end

function FullMoon_RacialComplete()
  FM_RacialRunning = 2;

  local start, duration, enabled = GetSpellCooldown(FM_RacialName);
  FM_RacialCD = duration;

  FullMoonRacialFrame_InfoFrame_UptimeBar:SetMinMaxValues(0,FM_RacialCD);
  FullMoonRacialFrame_InfoFrame_UptimeBar:SetValue(FM_RacialRuntime);
  FullMoonRacialFrame_InfoFrame_UptimeBar:SetStatusBarColor(1.0,0,0);
  FullMoonRacialFrame_InfoFrame_UptimeBar_BarText:SetText(FM_RacialRuntime);
end

function FullMoon_HB1Complete()
  FM_HB1Running = 2;

  local start, duration, enabled = GetSpellCooldown(FM_HB1Name);
  FM_HB1CD = duration;

  FullMoonFrame_InfoFrame_HB1_UptimeBar:SetMinMaxValues(0,FM_HB1CD);
  FullMoonFrame_InfoFrame_HB1_UptimeBar:SetValue(FM_HB1Runtime);
  FullMoonFrame_InfoFrame_HB1_UptimeBar:SetStatusBarColor(1.0,0,0);
  FullMoonFrame_InfoFrame_HB1_UptimeBar_BarText:SetText(FM_HB1Runtime);
end

function FullMoon_HB2Complete()
  FM_HB2Running = 2;
  
  local start, duration, enabled = GetSpellCooldown(FM_HB2Name);
  FM_HB2CD = duration;
  
  FullMoonFrame_InfoFrame_HB2_UptimeBar:SetMinMaxValues(0,FM_HB2CD);
  FullMoonFrame_InfoFrame_HB2_UptimeBar:SetValue(FM_HB2Runtime);
  FullMoonFrame_InfoFrame_HB2_UptimeBar:SetStatusBarColor(1.0,0,0);
  FullMoonFrame_InfoFrame_HB2_UptimeBar_BarText:SetText(FM_HB2Runtime);
end

function FullMoon_RacialCooldownFinished()
  FM_RacialRunning = 0;
  
  FullMoonRacialFrame_InfoFrame_UptimeBar:SetMinMaxValues(0,1);
  FullMoonRacialFrame_InfoFrame_UptimeBar:SetValue(1);
  FullMoonRacialFrame_InfoFrame_UptimeBar:SetStatusBarColor(0,1.0,0);
  FullMoonRacialFrame_InfoFrame_UptimeBar_BarText:SetText("READY");
end

function FullMoon_HB1CooldownFinished()
  FM_HB1Running = 0;
  
  FullMoonFrame_InfoFrame_HB1_UptimeBar:SetMinMaxValues(0,1);
  FullMoonFrame_InfoFrame_HB1_UptimeBar:SetValue(1);
  FullMoonFrame_InfoFrame_HB1_UptimeBar:SetStatusBarColor(0,1.0,0);
  FullMoonFrame_InfoFrame_HB1_UptimeBar_BarText:SetText("READY");
end

function FullMoon_HB2CooldownFinished()
  FM_HB2Running = 0;
  
  FullMoonFrame_InfoFrame_HB2_UptimeBar:SetMinMaxValues(0,1);
  FullMoonFrame_InfoFrame_HB2_UptimeBar:SetValue(1);
  FullMoonFrame_InfoFrame_HB2_UptimeBar:SetStatusBarColor(0,1.0,0);
  FullMoonFrame_InfoFrame_HB2_UptimeBar_BarText:SetText("READY");
end

function FullMoon_HexCooldownFinished()
  FM_HexRunning = 0;
  
  FullMoonPvPFrame_InfoFrame_HB1_UptimeBar:SetMinMaxValues(0,1);
  FullMoonPvPFrame_InfoFrame_HB1_UptimeBar:SetValue(1);
  FullMoonPvPFrame_InfoFrame_HB1_UptimeBar:SetStatusBarColor(0,1.0,0);
  FullMoonPvPFrame_InfoFrame_HB1_UptimeBar_BarText:SetText("READY");
end

function FullMoon_TrinketUnequipped()
  FM_TrinketRunning = 0;
  
  FullMoonPvPFrame_InfoFrame_HB2_UptimeBar:SetMinMaxValues(0,1);
  FullMoonPvPFrame_InfoFrame_HB2_UptimeBar:SetValue(1);
  FullMoonPvPFrame_InfoFrame_HB2_UptimeBar:SetStatusBarColor(1.0,0,0);
  FullMoonPvPFrame_InfoFrame_HB2_UptimeBar_BarText:SetText("NOT ON");
end

function FullMoon_TrinketReady()
  FM_TrinketRunning = 0;
  
  FullMoonPvPFrame_InfoFrame_HB2_UptimeBar:SetMinMaxValues(0,1);
  FullMoonPvPFrame_InfoFrame_HB2_UptimeBar:SetValue(1);
  FullMoonPvPFrame_InfoFrame_HB2_UptimeBar:SetStatusBarColor(0,1.0,0);
  FullMoonPvPFrame_InfoFrame_HB2_UptimeBar_BarText:SetText("READY");
end

function FullMoon_TrinketUsed()
  FM_TrinketRunning = 1;
  
  local start, duration, enable = GetInventoryItemCooldown("player", FM_TrinketSlot);
  
  if (start == 0) then
    FullMoon_TrinketReady();
  else
    FullMoonPvPFrame_InfoFrame_HB2_UptimeBar:SetMinMaxValues(0, FM_TrinketCD);
    if (duration == 30) then
      FM_EquipCD = true;
      FullMoonPvPFrame_InfoFrame_HB2_UptimeBar:SetValue(ceil(GetTime() - start) + FM_TrinketCD - 30);
    else
      FM_EquipCD = nil;
      FullMoonPvPFrame_InfoFrame_HB2_UptimeBar:SetValue(ceil(GetTime() - start));
    end
    FullMoonPvPFrame_InfoFrame_HB2_UptimeBar_BarText:SetText(FM_TrinketCD - floor(GetTime() - start));
    FullMoonPvPFrame_InfoFrame_HB2_UptimeBar:SetStatusBarColor(1.0,0,0);
  end
end

function FullMoon_OnLoad()
  -- First make sure it's a shaman...
  local playerClass, englishClass = UnitClass("player");
  
  if (englishClass == "SHAMAN") then
    _, FM_Race = UnitRace("player");
    FullMoon_InitLocalized();
    FullMoon_InitFrames();
    
    -- Set up slash commands
    SlashCmdList["FULLMOON"] = FullMoon_Slash;
    SLASH_FULLMOON1 = "/fullmoon";
    SLASH_FULLMOON2 = "/fm";
      
    -- Events we handle
    this:RegisterEvent("ADDON_LOADED");
    this:RegisterEvent("UNIT_SPELLCAST_SUCCEEDED");
    this:RegisterEvent("UNIT_AURA");
    this:RegisterEvent("PLAYER_ENTERING_WORLD");
    this:RegisterEvent("PLAYER_REGEN_ENABLED");
    this:RegisterEvent("PLAYER_REGEN_DISABLED");
    this:RegisterEvent("PLAYER_ALIVE");
    this:RegisterEvent("UNIT_SPELLCAST_SENT");
    this:RegisterEvent("CHARACTER_POINTS_CHANGED");
    this:RegisterEvent("UNIT_INVENTORY_CHANGED");
    this:RegisterEvent("ACTIONBAR_UPDATE_COOLDOWN");
  else
    FullMoon_HideFrames();
  end
end

function FullMoon_UpdateTrinkets()
  local itemLink, found, itemString;
  
  itemLink = GetInventoryItemLink("player", 13);

  if (itemLink) then
    local id = tonumber(FullMoon_ExtractItemID(itemLink));

    if (id == 42123 or -- Medallion of the Alliance (84 resil)
        id == 42122 or -- Medallion of the Horde (84 resil)
        id == 30351 or -- Medallion of the Alliance (blue shaman version)
        id == 30345 or -- Medallion of the Horde (blue shaman version)
        id == 42124 or -- Medallion of the Alliance (108 resil)
        id == 42126 or -- Medallion of the Horde (108 resil)
        id == 46083 or -- Titan-forged Rune of Accuracy
        id == 46085 or -- Titan-forged Rune of Alacrity
        id == 46081 or -- Titan-forged Rune of Audacity
        id == 46084 or -- Titan-forged Rune of Cruelty
        id == 46082    -- Titan-forged Rune of Determination
        ) then
      FM_TrinketSlot = 13;
      FM_TrinketCD = 120;
      FullMoon_TrinketUsed();
      return;
    end
    
    if (id == 29593 or -- Insignia of the Alliance (shaman version)
        id == 40476 or -- Insignia of the Alliance (Hellfire version)
        id == 44098 or -- Inherited Insignia of the Alliance
        id == 18845 or -- Insignia of the Horde (shaman version)
        id == 40477 or -- Insignia of the Horde (Hellfire version)
        id == 44097    -- Inherited Insignia of the Horde
        ) then
      FM_TrinketSlot = 13;
      FM_TrinketCD = 300;
      FullMoon_TrinketUsed();
      return;
    end
  end
  
  itemLink = GetInventoryItemLink("player", 14);
  
  if (itemLink) then
    local id = tonumber(FullMoon_ExtractItemID(itemLink));
    
    if (id == 42123 or -- Medallion of the Alliance (84 resil)
        id == 42122 or -- Medallion of the Horde (84 resil)
        id == 30351 or -- Medallion of the Alliance (blue shaman version)
        id == 30345 or -- Medallion of the Horde (blue shaman version)
        id == 42124 or -- Medallion of the Alliance (108 resil)
        id == 42126 or -- Medallion of the Horde (108 resil)
        id == 46083 or -- Titan-forged Rune of Accuracy
        id == 46085 or -- Titan-forged Rune of Alacrity
        id == 46081 or -- Titan-forged Rune of Audacity
        id == 46084 or -- Titan-forged Rune of Cruelty
        id == 46082    -- Titan-forged Rune of Determination
        ) then
      FM_TrinketSlot = 14;
      FM_TrinketCD = 120;
      FullMoon_TrinketUsed();
      return;
    end
    
    if (id == 29593 or -- Insignia of the Alliance (shaman version)
        id == 40476 or -- Insignia of the Alliance (Hellfire version)
        id == 44098 or -- Inherited Insignia of the Alliance
        id == 18845 or -- Insignia of the Horde (shaman version)
        id == 40477 or -- Insignia of the Horde (Hellfire version)
        id == 44097    -- Inherited Insignia of the Horde
        ) then
      FM_TrinketSlot = 14;
      FM_TrinketCD = 300;
      FullMoon_TrinketUsed();
      return;
    end
  end
  
  -- Nothing was found
  FM_TrinketSlot = nil;
  FM_TrinketCD = nil;

  FullMoon_TrinketUnequipped();
end

function FullMoon_ReInit()
  -- Check spec
  FullMoon_InitSpec();
  
  -- Update trinket
  FullMoon_UpdateTrinkets();
    
  -- Check state of long CDs
  local fm_start, fm_duration, fm_enabled = GetSpellCooldown(FM_HB1Name);

  if(fm_start) then
    FullMoonFrame_InfoFrame_HB1BG:Show();
    FullMoonFrame_InfoFrame_HB1_UptimeBar:Show();

    if(fm_start==0 and fm_enabled ~= 0) then
      FullMoon_HB1CooldownFinished();
    else
      if(FM_mode == 3 or FM_HB1Runtime - (GetTime() - fm_start) > 0) then
        FullMoon_CastHB1();
      else
        FullMoon_HB1Complete();
      end
    end
  else
    FullMoonFrame_InfoFrame_HB1BG:Hide();
    FullMoonFrame_InfoFrame_HB1_UptimeBar:Hide();
  end

  fm_start, fm_duration, fm_enabled = GetSpellCooldown(FM_HB2Name);
      
  if(fm_start) then
    FullMoonFrame_InfoFrame_HB2BG:Show();
    FullMoonFrame_InfoFrame_HB2_UptimeBar:Show();
      
    if (fm_start == 0) then
      FullMoon_HB2CooldownFinished();
    else
      if(FM_HB2Runtime - (GetTime() - fm_start) > 0) then
        FullMoon_CastHB2();
      else
        FullMoon_HB2Complete();
      end
    end
  else
    FullMoonFrame_InfoFrame_HB2BG:Hide();
    FullMoonFrame_InfoFrame_HB2_UptimeBar:Hide();
  end
  
  fm_start, fm_duration, fm_enabled = GetSpellCooldown(FM_SpellNames["Hex"]);
  
  if (fm_start ~= nil) then
    if (fm_start == 0) then
      FullMoon_HexCooldownFinished();
    else
      FullMoon_CastHex();
    end
  end
  
  fm_start, fm_duration, fm_enabled = GetSpellCooldown(FM_RacialName);
      
  if(fm_start) then      
    if (fm_start == 0) then
      FullMoon_RacialCooldownFinished();
    else
      if(FM_RacialRuntime - (GetTime() - fm_start) > 0) then
        FullMoon_CastRacial();
      else
        FullMoon_RacialComplete();
      end
    end
  end
  
  -- Totems are so short we don't even care
  FullMoon_GroundingCooldownFinished();
  FullMoon_EarthbindCooldownFinished();
  FullMoon_StoneclawCooldownFinished();
  FullMoon_FireNovaCooldownFinished();
  
  -- In case the user doesn't want long cooldown bars at all
  if (FullMoon_Config.longCDs == false) then
    FullMoonFrame_InfoFrame_HB1_UptimeBar:Hide();
    FullMoonFrame_InfoFrame_HB2_UptimeBar:Hide();
    FullMoonFrame_InfoFrame_HB1BG:Hide();
    FullMoonFrame_InfoFrame_HB2BG:Hide();
  end
end

function FullMoon_OnEvent()
  if (event == "UNIT_SPELLCAST_SENT" and arg1 == "player" and arg2 == FM_SpellNames["Earth Shield"]) then
    FM_ESTarget = arg4;
  end
  
  if (event == "ACTIONBAR_UPDATE_COOLDOWN") then
    -- TrinketUsed() will take care of any status changes, even if the trinket is just sitting there and wasn't used
    FullMoon_TrinketUsed();
  end
  
  if (event == "UNIT_INVENTORY_CHANGED" and arg1 == "player") then
    -- Check trinkets
    FullMoon_UpdateTrinkets();
  end
  
  if(event == "CHARACTER_POINTS_CHANGED" or event == "PLAYER_ALIVE" or (event == "PLAYER_ENTERING_WORLD" and FullMoon_HasTalents())) then
    -- Only check these once
    this:UnregisterEvent("PLAYER_ALIVE");
    this:UnregisterEvent("PLAYER_ENTERING_WORLD");
    
    FullMoon_ReInit();
  end
  
  if (event == "PLAYER_REGEN_ENABLED") then
    FullMoon_UpdateFrameAlpha(FullMoon_Config.combatFade);
  end
  
  if (event == "PLAYER_REGEN_DISABLED") then
    FullMoon_UpdateFrameAlpha(1.0);
  end
  
  if(event == "ADDON_LOADED" and arg1 == "FullMoon") then
    -- Check persistant variables
    FM_CUR_VERSION = "1.10";
    
    if (FullMoon_Config == nil) then
      -- First time loading
      FullMoon_Config = { locked = nil, scale = 1.0, playSound = true, combatFade = 0.5, PvP = true, longCDs = true, elemental = true, enhancement = true, restoration = true, racial = true, ver = FM_CUR_VERSION };
      FullMoon_Print("Full Moon loaded for the first time.  Please use /fm or /fullmoon for config options.");
    end
    
    if (FullMoon_Config.ver ~= FM_CUR_VERSION) then
      FullMoon_Print("You have updated to "..FM_CUR_VERSION..", please double check all your settings are as you like them!");
      
      if (FullMoon_Config.scale == nil) then
        FullMoon_Config.scale = 1.0;
      end
      
      if (FullMoon_Config.playSound == nil) then
        FullMoon_Config.playSound = true;
      end
      
      if (FullMoon_Config.combatFade == nil) then
        FullMoon_Config.combatFade = 0.5;
      end
      
      if (FullMoon_Config.PvP == nil) then
        FullMoon_Config.PvP = true;
      end
      
      if (FullMoon_Config.longCDs == nil) then
        FullMoon_Config.longCDs = true;
      end
      
      if (FullMoon_Config.elemental == nil) then
        FullMoon_Config.elemental = true;
      end
      
      if (FullMoon_Config.enhancement == nil) then
        FullMoon_Config.enhancement = true;
      end
      
      if (FullMoon_Config.restoration == nil) then
        FullMoon_Config.restoration = true;
      end
      
      if (FullMoon_Config.racial == nil) then
        FullMoon_Config.racial = true;
      end
      
      FullMoon_Config.ver = FM_CUR_VERSION;
    end
    
    if (FullMoon_Config.PvP == false) then
      FullMoonPvPFrame:Hide();
    else
      FullMoonPvPFrame:Show();
    end
    
    if (FullMoon_Config.totems == false) then
      FullMoonTotemFrame:Hide();
    else
      FullMoonTotemFrame:Show();
    end
    
    if (FullMoon_Config.racial == false) then
      FullMoonRacialFrame:Hide();
    else
      FullMoonRacialFrame:Show();
    end
    
    if (FullMoon_Config.locked) then
      FullMoon_LockFrames();
    else
      FullMoon_UnlockFrames();
    end
    
    FullMoon_UpdateFrameScale();

    FullMoon_UpdateShield();
    
    FullMoon_UpdateFrameAlpha(FullMoon_Config.combatFade);

    FullMoon_Print("Full Moon loaded.  Use /fm or /fullmoon for options.");
  end
  
  if(event == "UNIT_SPELLCAST_SUCCEEDED" and arg1 == "player") then
    if (arg2 == FM_SpellNames["Activate Primary"] or arg2 == FM_SpellNames["Activate Secondary"]) then
      FullMoon_ReInit();
    end
    
    if (arg2 == FM_SpellNames["Hex"]) then
      FullMoon_CastHex();
    end
    
    if (arg2 == FM_SpellNames["Grounding Totem"]) then
      FullMoon_CastGrounding();
    end
    
    if (arg2 == FM_SpellNames["Earthbind Totem"]) then
      FullMoon_CastEarthbind();
    end
    
    if (arg2 == FM_SpellNames["Stoneclaw Totem"]) then
      FullMoon_CastStoneclaw();
    end
    
    if (arg2 == FM_SpellNames["Fire Nova Totem"]) then
      FullMoon_CastFireNova();
    end
    
    if (arg2 == FM_RacialName) then
      FullMoon_CastRacial();
    end
    
    if (arg2 == FM_HB1Name) then
      FullMoon_CastHB1();
    end
  
    if (arg2 == FM_HB2Name) then
      FullMoon_CastHB2();
    end
    
    if (arg2 == FM_VBRName) then
      FullMoon_CastVBR();
    end
    
    if (arg2 == FM_SpellNames["Earth Shock"] or arg2 == FM_SpellNames["Frost Shock"] or arg2 == FM_SpellNames["Flame Shock"] or arg2 == FM_SpellNames["Wind Shock"]) then
      FullMoon_CastShock();
    end
    
    if (arg2 == FM_VBLName) then
      FullMoon_CastVBL();
    end
  end
  
  if(event == "UNIT_AURA" and arg1 == "player") then
    FullMoon_UpdateShield();
  end

  if(event == "UNIT_AURA" and arg1 == "player" and FM_mode == 2) then
    local name, rank, icon, count, debuffType, duration, expirationTime, unitCaster, isStealable = UnitBuff("player", FM_SpellNames["Maelstrom Weapon"]);
    if (count) then
      FullMoonFrame_TitleFrame_TitleBar:SetValue(count);
      if(count<5) then
        FullMoonFrame_TitleFrame_TitleBar:SetStatusBarColor(1.0-count*0.1, count*0.2, 0);
        FullMoonFrame_TitleFrame_TitleBar_BarText:SetTextColor(1.0, 1.0, 1.0);
        FullMoonFrame_TitleFrame_TitleBar_BarText:SetText(count);
        FM_Hit5 = nil;
      else
        if (FM_Hit5 ~= 1) then

          if (FullMoon_Config.playSound) then
            PlaySoundFile("Sound\\Doodad\\Cannon01_BlastA.wav");
          end

          FullMoonFrame_TitleFrame_TitleBar_BarText:SetTextColor(1.0, 0.0, 0.0);
          FullMoonFrame_TitleFrame_TitleBar_BarText:SetText("FULL STACK");
          FullMoonFrame_TitleFrame_TitleBar:SetStatusBarColor(0, 1.0, 1.0);
          FM_Hit5 = 1;
        end
      end
    else
      FullMoonFrame_TitleFrame_TitleBar:SetValue(0);
      FullMoonFrame_TitleFrame_TitleBar_BarText:SetText("0");
      FullMoonFrame_TitleFrame_TitleBar_BarText:SetTextColor(1.0, 1.0, 1.0);
    end
  end
end

function FullMoon_OnUpdate()
  -- Update GCD bar
  local fm_start, fm_duration, fm_enabled = GetSpellCooldown(FM_SpellNames["Water Shield"]);
  
  if (fm_start ~= nil) then
    if (fm_start > 0) then
      local remaining = GetTime()*100 - fm_start*100 + (150-fm_duration*100);
      FullMoonFrame_TitleFrame_GCD_CDBar:SetValue(remaining);
      FullMoonFrame_TitleFrame_GCD_CDBar_BarText:SetText(string.format("%.1f", (150-remaining)/100));
      FullMoonFrame_TitleFrame_GCD_CDBar:SetStatusBarColor(1.0, 0.0, 0.0);
    else
      FullMoonFrame_TitleFrame_GCD_CDBar:SetValue(150);
      FullMoonFrame_TitleFrame_GCD_CDBar_BarText:SetText("READY");
      FullMoonFrame_TitleFrame_GCD_CDBar:SetStatusBarColor(0.0, 1.0, 0.0);
    end
  end
  
  -- Update long CDs
  if(FM_HB1Running==1 and FM_HB1Runtime > 0) then
    local uptime;
    local fm_start, fm_duration, fm_enabled = GetSpellCooldown(FM_HB1Name);
    uptime = FM_HB1Runtime*10 - (GetTime()*10 - fm_start*10);
    
    if(uptime<0) then
      FullMoon_HB1Complete();
    else
      FullMoonFrame_InfoFrame_HB1_UptimeBar:SetValue(uptime);
      FullMoonFrame_InfoFrame_HB1_UptimeBar_BarText:SetText(ceil(uptime/10));
    end
  end
  
  if (FM_HB1Running==1 and FM_HB1Runtime==0) then
    local name, rank, icon, count, debuffType, duration, expirationTime, unitCaster, isStealable = UnitBuff("player", FM_HB1Name);
    local fm_start, fm_duration, fm_enabled = GetSpellCooldown(FM_HB1Name);
    
    if (FM_mode ~= 3) then
      if(name==nil) then
        FullMoon_HB1Complete();
      else
        FullMoonFrame_InfoFrame_HB1_UptimeBar:SetValue(expirationTime*10 - GetTime()*10);
        FullMoonFrame_InfoFrame_HB1_UptimeBar_BarText:SetText(floor(expirationTime - GetTime()));
      end
    else
      if(name==nil) then
        FullMoon_HB1Complete();
      else
        FullMoonFrame_InfoFrame_HB1_UptimeBar:SetValue(1);
        FullMoonFrame_InfoFrame_HB1_UptimeBar_BarText:SetText("ACTIVE");
      end
    end
  end
  
  if(FM_HB1Running==2) then
    local fm_start, fm_duration, fm_enabled = GetSpellCooldown(FM_HB1Name);
    
    if(fm_start==0) then
      FullMoon_HB1CooldownFinished();
    else
      FullMoonFrame_InfoFrame_HB1_UptimeBar:SetValue(ceil(GetTime() - fm_start));
      FullMoonFrame_InfoFrame_HB1_UptimeBar_BarText:SetText(FM_HB1CD - floor(GetTime() - fm_start));
    end
  end
  
  if(FM_HB2Running==1) then
    local uptime;
    local fm_start, fm_duration, fm_enabled = GetSpellCooldown(FM_HB2Name);
    uptime = FM_HB2Runtime*10 - (GetTime()*10 - fm_start*10);
    
    if(uptime<0) then
      FullMoon_HB2Complete();
    else
      FullMoonFrame_InfoFrame_HB2_UptimeBar:SetValue(uptime);
      FullMoonFrame_InfoFrame_HB2_UptimeBar_BarText:SetText(ceil(uptime/10));
    end
  end
  
  if(FM_HB2Running==2) then
    local fm_start, fm_duration, fm_enabled = GetSpellCooldown(FM_HB2Name);
    
    if(fm_start==0) then
      FullMoon_HB2CooldownFinished();
    else
      FullMoonFrame_InfoFrame_HB2_UptimeBar:SetValue(ceil(GetTime() - fm_start));
      FullMoonFrame_InfoFrame_HB2_UptimeBar_BarText:SetText(FM_HB2CD - floor(GetTime() - fm_start));
    end
  end
  
  if(FM_RacialRunning==1) then
    local uptime;
    local fm_start, fm_duration, fm_enabled = GetSpellCooldown(FM_RacialName);
    uptime = FM_RacialRuntime*10 - (GetTime()*10 - fm_start*10);
    
    if(uptime<0) then
      FullMoon_RacialComplete();
    else
      FullMoonRacialFrame_InfoFrame_UptimeBar:SetValue(uptime);
      FullMoonRacialFrame_InfoFrame_UptimeBar_BarText:SetText(ceil(uptime/10));
    end
  end
  
  if(FM_RacialRunning==2) then
    local fm_start, fm_duration, fm_enabled = GetSpellCooldown(FM_RacialName);
    
    if(fm_start==0) then
      FullMoon_RacialCooldownFinished();
    else
      FullMoonRacialFrame_InfoFrame_UptimeBar:SetValue(ceil(GetTime() - fm_start));
      FullMoonRacialFrame_InfoFrame_UptimeBar_BarText:SetText(FM_RacialCD - floor(GetTime() - fm_start));
    end
  end
  
  if (FM_HexRunning == 1) then
    local fm_start, fm_duration, fm_enabled = GetSpellCooldown(FM_SpellNames["Hex"]);

    if (fm_start == 0) then
      FullMoon_HexCooldownFinished();
    else
      FullMoonPvPFrame_InfoFrame_HB1_UptimeBar:SetValue(ceil(GetTime() - fm_start));
      FullMoonPvPFrame_InfoFrame_HB1_UptimeBar_BarText:SetText(fm_duration - floor(GetTime() - fm_start));
    end
  end
  
  if (FM_GroundingRunning == 1) then
    local fm_start, fm_duration, fm_enabled = GetSpellCooldown(FM_SpellNames["Grounding Totem"]);
    
    if (fm_start == 0) then
      FullMoon_GroundingCooldownFinished();
    else
      FullMoonTotemFrame_InfoFrame_HB1_UptimeBar:SetValue(ceil(GetTime()*10 - fm_start*10));
      FullMoonTotemFrame_InfoFrame_HB1_UptimeBar_BarText:SetText(fm_duration - floor(GetTime() - fm_start));
    end
  end
  
  if (FM_EarthbindRunning == 1) then
    local fm_start, fm_duration, fm_enabled = GetSpellCooldown(FM_SpellNames["Earthbind Totem"]);
    
    if (fm_start == 0) then
      FullMoon_EarthbindCooldownFinished();
    else
      FullMoonTotemFrame_InfoFrame_HB2_UptimeBar:SetValue(ceil(GetTime()*10 - fm_start*10));
      FullMoonTotemFrame_InfoFrame_HB2_UptimeBar_BarText:SetText(fm_duration - floor(GetTime() - fm_start));
    end
  end
  
  if (FM_StoneclawRunning == 1) then
    local fm_start, fm_duration, fm_enabled = GetSpellCooldown(FM_SpellNames["Stoneclaw Totem"]);
    
    if (fm_start == 0) then
      FullMoon_StoneclawCooldownFinished();
    else
      FullMoonTotemFrame_InfoFrame_HB3_UptimeBar:SetValue(ceil(GetTime()*10 - fm_start*10));
      FullMoonTotemFrame_InfoFrame_HB3_UptimeBar_BarText:SetText(fm_duration - floor(GetTime() - fm_start));
    end
  end
  
  if (FM_NovaRunning == 1) then
    local uptime;
    local fm_start, fm_duration, fm_enabled = GetSpellCooldown(FM_SpellNames["Fire Nova Totem"]);
    uptime = 40 - (GetTime()*10 - fm_start*10);
    
    if(uptime<0) then
      FullMoon_FireNovaComplete();
    else
      FullMoonTotemFrame_InfoFrame_HB4_UptimeBar:SetValue(uptime);
      FullMoonTotemFrame_InfoFrame_HB4_UptimeBar_BarText:SetText(ceil(uptime/10));
    end
  end
  
  if(FM_NovaRunning==2) then
    local fm_start, fm_duration, fm_enabled = GetSpellCooldown(FM_SpellNames["Fire Nova Totem"]);
    
    if(fm_start==0) then
      FullMoon_FireNovaCooldownFinished();
    else
      local timeOff = 15-fm_duration;
      FullMoonTotemFrame_InfoFrame_HB4_UptimeBar:SetValue(ceil(GetTime()*10 - fm_start*10) + timeOff*10);
      FullMoonTotemFrame_InfoFrame_HB4_UptimeBar_BarText:SetText(15 - floor(GetTime() - fm_start) - timeOff);
    end
  end
  
  if (FM_TrinketRunning == 1) then
    local fm_start, fm_duration, fm_enabled = GetInventoryItemCooldown("player", FM_TrinketSlot);
    
    if (fm_start == 0) then
      FullMoon_TrinketReady();
    else
      if (FM_EquipCD == true) then
        FullMoonPvPFrame_InfoFrame_HB2_UptimeBar:SetValue(ceil(GetTime() - fm_start) + FM_TrinketCD - 30);
      else
        FullMoonPvPFrame_InfoFrame_HB2_UptimeBar:SetValue(ceil(GetTime() - fm_start));
      end
      FullMoonPvPFrame_InfoFrame_HB2_UptimeBar_BarText:SetText(fm_duration - floor(GetTime() - fm_start));
    end
  end
  
  if(FM_SSRunning==1) then
    local fm_start, fm_duration, fm_enabled = GetSpellCooldown(FM_VBRName);
    
    if(fm_start==0) then
      FullMoonFrame_TitleFrame_VBR_CDBar:SetValue(0);
      FullMoonFrame_TitleFrame_VBR_CDBar_BarText:SetText("0.0");
      FM_SSRunning = 0;
    else
      local left = fm_duration*100 - (GetTime() - fm_start)*100;
      FullMoonFrame_TitleFrame_VBR_CDBar:SetValue(left);
      FullMoonFrame_TitleFrame_VBR_CDBar:SetStatusBarColor(left/(fm_duration*100),1.0-left/(fm_duration*100),0);
      FullMoonFrame_TitleFrame_VBR_CDBar_BarText:SetText(string.format("%.1f",left/100));
    end
  end
  
  if(FM_ESRunning==1) then
    local fm_start, fm_duration, fm_enabled = GetSpellCooldown(FM_SpellNames["Earth Shock"]);
    
    if(fm_start==0) then
      FullMoonFrame_TitleFrame_VBC_CDBar:SetValue(0);
      FullMoonFrame_TitleFrame_VBC_CDBar_BarText:SetText("0.0");
      FM_ESRunning = 0;
    else
      local left = fm_duration*100 - (GetTime() - fm_start)*100;
      FullMoonFrame_TitleFrame_VBC_CDBar:SetValue(left);
      FullMoonFrame_TitleFrame_VBC_CDBar:SetStatusBarColor(left/(fm_duration*100),1.0-left/(fm_duration*100),0);
      FullMoonFrame_TitleFrame_VBC_CDBar_BarText:SetText(string.format("%.1f",left/100));
    end
  end
  
  if(FM_LLRunning==1) then
    local fm_start, fm_duration, fm_enabled = GetSpellCooldown(FM_VBLName);
    
    if(fm_start==0) then
      FullMoonFrame_TitleFrame_VBL_CDBar:SetValue(0);
      FullMoonFrame_TitleFrame_VBL_CDBar_BarText:SetText("0.0");
      FM_LLRunning = 0;
    else
      local left = fm_duration*100 - (GetTime() - fm_start)*100;
      FullMoonFrame_TitleFrame_VBL_CDBar:SetValue(left);
      FullMoonFrame_TitleFrame_VBL_CDBar:SetStatusBarColor(left/(fm_duration*100),1.0-left/(fm_duration*100),0);
      FullMoonFrame_TitleFrame_VBL_CDBar_BarText:SetText(string.format("%.1f",left/100));
    end
  end
  
  -- Handle mode-specific stuff
  if (FM_mode == 1) then
    local HadFlameShock = false;

    if (UnitExists("target")) then
      for i=1,40 do
        local name, rank, icon, count, debuffType, duration, expirationTime, unitCaster, isStealable = UnitDebuff("target", i);
    
        if (name == FM_SpellNames["Flame Shock"] and unitCaster == "player") then
          local timeLeft = (expirationTime - GetTime())*10;
          FullMoonFrame_TitleFrame_TitleBar:SetValue(timeLeft);
          FullMoonFrame_TitleFrame_TitleBar_BarText:SetText(string.format("%.1f", timeLeft/10));
          HadFlameShock = true;
        end
      end
    end
    
    if (HadFlameShock == false) then
      FullMoonFrame_TitleFrame_TitleBar:SetValue(0);
      FullMoonFrame_TitleFrame_TitleBar_BarText:SetText("0.0");
    end
  end
  
  if (FM_mode == 2) then
    local HadStormstrike = false;

    if (UnitExists("target")) then
      for i=1,40 do
        local name, rank, icon, count, debuffType, duration, expirationTime, unitCaster, isStealable = UnitDebuff("target", i);
    
        if (name == FM_SpellNames["Stormstrike"] and unitCaster == "player") then
          FullMoonFrame_TitleFrame_VBR_CDBar_IconText:SetText(count);
          HadStormstrike = true;
        end
      end
    end
    
    if (HadStormstrike == false) then
      FullMoonFrame_TitleFrame_VBR_CDBar_IconText:SetText("");
    end
  end
  
  if (FM_mode == 3) then
    local HadEarthShield = false;

    if (FM_ESTarget ~= nil) then
      for i=1,40 do
        local name, rank, icon, count, debuffType, duration, expirationTime, unitCaster, isStealable = UnitBuff(FM_ESTarget, i);
    
        if (name == FM_SpellNames["Earth Shield"] and unitCaster == "player") then
          FullMoonFrame_TitleFrame_VBR_CDBar_IconText:SetText(count);
          FullMoonFrame_TitleFrame_VBR_CDBar_IconText:SetTextColor(1.0, count/4, count/4);
          FullMoonFrame_TitleFrame_VBR_CDBar:SetValue(count*100);
          FullMoonFrame_TitleFrame_VBR_CDBar:SetStatusBarColor((8-count)/8,count/8,0);
          FullMoonFrame_TitleFrame_VBR_CDBar_Tex:SetVertexColor(1, 1, 1);
          FullMoonFrame_TitleFrame_VBR_CDBar_BarText:SetText(strsub(FM_ESTarget, 1, 3));
          HadEarthShield = true;
        end
      end
    end
    
    if (HadEarthShield == false) then
      FullMoonFrame_TitleFrame_VBR_CDBar:SetValue(0);
      FullMoonFrame_TitleFrame_VBR_CDBar_BarText:SetText("");
      FullMoonFrame_TitleFrame_VBR_CDBar_IconText:SetText("");
      FullMoonFrame_TitleFrame_VBR_CDBar_Tex:SetVertexColor(0.4, 0.1, 0.1);
    end
    
    -- Now check for Tidal Waves
    local name, rank, icon, count, debuffType, duration, expirationTime, unitCaster, isStealable = UnitBuff("player", "Tidal Waves");
    
    if (count ~= nil) then
      local timeLeft = (expirationTime - GetTime())*10;
      FullMoonFrame_TitleFrame_TitleBar:SetValue(timeLeft);
      FullMoonFrame_TitleFrame_TitleBar_BarText:SetText(count);
    else
      FullMoonFrame_TitleFrame_TitleBar:SetValue(0);
      FullMoonFrame_TitleFrame_TitleBar_BarText:SetText("0");
    end
  end
  
  -- Update lightning bolt cast time for elemental
  if (FM_mode == 1) then
    local name, rank, icon, cost, isFunnel, powerType, castTime, minRange, maxRange = GetSpellInfo(FM_SpellNames["Lightning Bolt"]);
    
    FullMoonFrame_TitleFrame_LB_CastBar_BarText:SetText(string.format("%d", castTime/10));
    FullMoonFrame_TitleFrame_LB_CastBar:SetValue(castTime/10);
  end
  
  -- Red out any out of range spells
  if (FM_VBLName ~= nil) then
    local range = IsSpellInRange(FM_VBLName, "target");
    if (range == 1 or range == nil) then
      FullMoonFrame_TitleFrame_VBL_CDBar_Tex:SetVertexColor(1.0, 1.0, 1.0);
    else
      FullMoonFrame_TitleFrame_VBL_CDBar_Tex:SetVertexColor(0.6, 0.0, 0.0);
    end
  end

  local range = IsSpellInRange("Flame Shock", "target");
  if (range == 1 or range == nil) then
    FullMoonFrame_TitleFrame_VBC_CDBar_Tex:SetVertexColor(1.0, 1.0, 1.0);
  else
    FullMoonFrame_TitleFrame_VBC_CDBar_Tex:SetVertexColor(0.6, 0.0, 0.0);
  end

  if (FM_VBRName ~= nil) then
    local range = IsSpellInRange(FM_VBRName, "target");
    if (range == 1 or range == nil) then
      FullMoonFrame_TitleFrame_VBR_CDBar_Tex:SetVertexColor(1.0, 1.0, 1.0);
    else
      FullMoonFrame_TitleFrame_VBR_CDBar_Tex:SetVertexColor(0.6, 0.0, 0.0);
    end
  end
  
  local range = IsSpellInRange("Hex", "target");
  if (range == 1 or range == nil) then
    FullMoonPvPFrame_InfoFrame_HB1_UptimeBar_Tex:SetVertexColor(1.0, 1.0, 1.0);
  else
    FullMoonPvPFrame_InfoFrame_HB1_UptimeBar_Tex:SetVertexColor(0.6, 0.0, 0.0);
  end
end