------------------------------------------------
--                 DagAssist                  --
--             Dagos of Cenarius              --
------------------------------------------------

if (not DagAssist) then
  DagAssist = {};
end

function DagAssist:Debug(msg)
  DEFAULT_CHAT_FRAME:AddMessage(msg);
end

--Set up the minimap button
DagAssist.MinimapButton = CreateFrame("Button", "DA_Minimap", Minimap, "SecureHandlerClickTemplate, DA_MinimapButton");
local btnMinimap = DagAssist.MinimapButton;
btnMinimap:RegisterForDrag("LeftButton");
btnMinimap:SetClampedToScreen(true);

local texture = btnMinimap:CreateTexture(nil, "ARTWORK");
texture:SetTexture("Interface\\AddOns\\DagAssist\\Images\\MinmapIconHighlight");
texture:SetBlendMode("BLEND");
texture:SetAllPoints(btnMinimap);
btnMinimap:SetHighlightTexture(texture);
  
btnMinimap:Execute([[
  menuOpen = false;
  keepOpen = false;
  menuItems = table.new();
  
  Close = [=[
    menuOpen = false;
    menu:Hide();
    for i, button in ipairs(menuItems) do
      button:Hide();
    end
  ]=]

  Show = [=[
    menuOpen = true;
    local previous;
    
    menu:ClearAllPoints();
    menu:SetPoint("TOPLEFT", self, "BOTTOMLEFT");
    menu:Show();
    
    local menuHeight = 20;
    for i, button in ipairs(menuItems) do
      local visible = button:GetAttribute("visible");
      local enabled = button:GetAttribute("enabled");
              
      if (visible) then
        menuHeight = menuHeight + 18;
        if (previous) then
          button:SetPoint("TOPLEFT", previous, "BOTTOMLEFT");
        else
          button:SetPoint("TOPLEFT", menu, "TOPLEFT", 10, -10);
        end
        if (enabled) then
          button:Enable();
        else
          button:Disable();
        end
        previous = button;
        button:Show();
      end
    end
    
    menu:SetHeight(menuHeight);

    local _,rt,_,_,mb = self:GetPoint(1);
    if ( mb and ( mb < menuHeight+32 ) ) and ( rt and rt:GetName() == "UIParent" ) then
      menu:ClearAllPoints();
      menu:SetPoint("BOTTOMLEFT", self, "TOPLEFT");
    end
    
  ]=]
]]);

btnMinimap:SetAttribute("_onclick", [[ 
  if menuOpen then
    control:Run(Close);
  else
    control:Run(Show);
  end
]]);

-- btnMinimap:SetAttribute("_onenter", [[ 
  -- keepOpen = true;
-- ]]);

-- btnMinimap:SetAttribute("_onleave", [[ 
  -- keepOpen = false;
  -- control:SetTimer(2.5, "");
-- ]]);

-- btnMinimap:SetAttribute("_ontimer", [[ 
  -- if not keepOpen then
    -- control:Run(Close);
  -- end
-- ]]);

-- btnMinimap:SetAttribute("_onupdate", [[
  -- if self:IsUnderMouse(true) then
    -- open = 0
  -- else
    -- open = open + elapsed
  -- end
  -- if open > 2.5 then
    -- control:Run(Close)
  -- end
-- ]]);

DagAssist.Menu = CreateFrame("Frame", "DA_Menu", btnMinimap, "SecureHandlerBaseTemplate, DA_MenuContainer");
DagAssist.Menu:SetClampedToScreen(true);
DagAssist.Menu:SetBackdropBorderColor(TOOLTIP_DEFAULT_COLOR.r, TOOLTIP_DEFAULT_COLOR.g, TOOLTIP_DEFAULT_COLOR.b);
DagAssist.Menu:SetBackdropColor(TOOLTIP_DEFAULT_BACKGROUND_COLOR.r, TOOLTIP_DEFAULT_BACKGROUND_COLOR.g, TOOLTIP_DEFAULT_BACKGROUND_COLOR.b, 1);
btnMinimap:SetFrameRef("menu", DagAssist.Menu);
btnMinimap:Execute([[
  menu = self:GetFrameRef("menu");
  table.insert(menuItems, menu);
]]);

btnMinimap:SetScript("OnDragStart", 
  function()
    if IsShiftKeyDown() then
      this:StartMoving();
      this.Dragging = true;
      if (InCombatLockdown() ~= 1) then
        btnMinimap:Execute([[
          control:Run(Close);
        ]]);
      end
    end
  end
)

btnMinimap:SetScript("OnDragStop",
  function()
    this:StopMovingOrSizing();
    
    if (this.Dragging) then
      this.Dragging = false;
      local s = this:GetEffectiveScale();
      DA_Vars.Minimap.X = this:GetLeft() * s;
      DA_Vars.Minimap.Y = this:GetTop() * s;
      this:ClearAllPoints()
      this:SetPoint("TOPLEFT", UIParent, "BOTTOMLEFT", DA_Vars.Minimap.X / s, DA_Vars.Minimap.Y /s);
    end
  end
)

btnMinimap:SetScript("OnEnter", 
  function()
    DagAssist:SetMenuItemVisibility();
  end
)

btnMinimap:RegisterForClicks("AnyDown");
--btnMinimap.NeedsTooltip = true;
--btnMinimap.TooltipText = DA_TOOLTIP_TEXT;

function DagAssist:OnEvent()
  if (type(DagAssist[event]) == 'function') then
    DagAssist[event](DagAssist, event);
  end
end

btnMinimap:SetScript("OnEvent", DagAssist.OnEvent);
btnMinimap:RegisterEvent("PLAYER_ENTERING_WORLD");

function DagAssist:PLAYER_ENTERING_WORLD(event)
  if (not DA_Vars) then
    DA_Vars = {Minimap = {}};
  end

  local s = btnMinimap:GetEffectiveScale();
  if not DA_Vars.Minimap.Y then
    btnMinimap:SetPoint("CENTER", Minimap, "BOTTOMLEFT", 15, 15);
    DA_Vars.Minimap.X = this:GetLeft() * s;
    DA_Vars.Minimap.Y = this:GetTop() * s;
  end
  btnMinimap:ClearAllPoints();
  btnMinimap:SetPoint("TOPLEFT", UIParent, "BOTTOMLEFT", DA_Vars.Minimap.X / s, DA_Vars.Minimap.Y /s);
  
  local menu = DagAssist.Menu;
  for index = 1, table.getn(DagAssist.MenuList) do 
    local value = DagAssist.MenuList[index];
    
    if ((value.type == "spell" or value.type == "buff") and value.id) then
      value.text = GetSpellInfo(value.id);
    elseif (value.type == "item" and value.id) then
      value.text = GetItemInfo(value.id);
    end
      
    local btnMenuItem;
    if (value.type == "header") or (value.type == "spacer") then
      btnMenuItem = CreateFrame("Button", "DA_MenuButton"..index, menu, "SecureHandlerBaseTemplate, DA_MenuLabelTemplate");
      if (value.text == "" and value.reagent and value.reagent ~= "") then
        value.text = GetItemInfo(value.reagent);
      end
      
    elseif value.type == "spell" or value.type == "buff" then
      btnMenuItem = CreateFrame("Button", "DA_MenuButton"..index, menu, "SecureActionButtonTemplate, SecureHandlerBaseTemplate, DA_MenuSpellButtonTemplate");
      btnMenuItem:SetAttribute("type","spell");
      btnMenuItem:SetAttribute("*spell1",value.text);
      btnMenuItem:SetAttribute("checkselfcast","1");
      btnMenuItem:SetAttribute("checkfocuscast","1");

    elseif value.type == "item" then
      btnMenuItem = CreateFrame("Button", "DA_MenuButton"..index, menu, "SecureActionButtonTemplate, SecureHandlerBaseTemplate, DA_MenuSpellButtonTemplate");
      btnMenuItem:SetAttribute("type","item");
      btnMenuItem:SetAttribute("*item1", value.text);
      btnMenuItem:SetAttribute("checkselfcast","1");
      btnMenuItem:SetAttribute("checkfocuscast","1");

    end   
    btnMinimap:WrapScript(btnMenuItem, "OnClick", [[control:Run(Close)]])
    btnMenuItem:SetClampedToScreen(true);
    btnMenuItem:SetAttribute("visible", false);
    btnMenuItem:SetAttribute("enabled", false);
    
    value.button = btnMenuItem;
    value.buttonIcon = getglobal("DA_MenuButton"..index.."Icon");
    
    DagAssist:SetButtonIcon(value);
    btnMenuItem:SetFrameLevel(btnMenuItem:GetFrameLevel() + 1);
    btnMenuItem:SetText(value.text);
    
    btnMinimap:SetFrameRef("child", btnMenuItem);
    btnMinimap:Execute([[
      table.insert(menuItems, self:GetFrameRef("child"));
    ]]);
  end
  
  --Add the close button
  btnMenuItem = CreateFrame("Button", "DA_MenuButtonClose", menu, "SecureActionButtonTemplate, SecureHandlerBaseTemplate, DA_MenuButtonTemplate");
  btnMenuItem:SetText("Close");
  btnMenuItem:SetAttribute("type", "click");
  btnMenuItem:SetAttribute("clickbutton", btnMinimap);
  btnMenuItem:SetAttribute("visible", true);
  btnMenuItem:SetAttribute("enabled", true);
  btnMinimap:SetFrameRef("child", btnMenuItem);
  btnMinimap:Execute([[
    table.insert(menuItems, self:GetFrameRef("child"));
  ]]);
    
  DagAssist:SetMenuItemVisibility();
  DagAssist.MinimapButton:Show();
  

  btnMinimap:RegisterEvent("BAG_UPDATE");
  btnMinimap:RegisterEvent("LEARNED_SPELL_IN_TAB");
  btnMinimap:RegisterEvent("PLAYER_REGEN_DISABLED");
  btnMinimap:RegisterEvent("PLAYER_REGEN_ENABLED");
  btnMinimap:UnregisterEvent("PLAYER_ENTERING_WORLD");
end

function DagAssist:BAG_UPDATE(event)
  DagAssist:SetMenuItemVisibility();
end
function DagAssist:LEARNED_SPELL_IN_TAB(event)
  DagAssist:SetMenuItemVisibility();
end
function DagAssist:PLAYER_REGEN_DISABLED(event)
  DagAssist:SetMenuItemVisibility();
end
function DagAssist:PLAYER_REGEN_ENABLED(event)
  DagAssist:SetMenuItemVisibility();
end

function DagAssist:PlayerKnowsSpell(spellId)
  -- Calling GetSpellInfo with the spellID will always return spell information.
  -- Calling GetSpellInfo with the spell name will only return a value if the player knows the spell
  -- By nesting two calls to GetSpellInfo, we can test if the player knows the spellId
  local value = GetSpellInfo(spellId);
  if (value ~= nil) then
    return (GetSpellInfo(value) ~= nil);
  else
    return false;
  end
end

function DagAssist:SetMenuItemVisibility()
  --Don't update the menu item visibility if the player is in combat.
  if (InCombatLockdown()) then
    return;
  end
  
  local previousItem = nil;
  for index = 1, table.getn(DagAssist.MenuList) do 
    local value = DagAssist.MenuList[index];
    
    if (not value.text) then
      if ((value.type == "spell" or value.type == "buff") and value.id) then
        value.text = GetSpellInfo(value.id);
      elseif (value.type == "item" and value.id) then
        value.text = GetItemInfo(value.id);
      end
    end

    
    if ((value.button) and (value.reagent) and (value.reagent ~= "")) then
      if (not value.reagentname) then value.reagentname = GetItemInfo(value.reagent) end
      if (value.text and value.reagentname) then
        -- If the item acting as reagent has never been seen by this client, then value.reagentname will be nil
        value.button:SetText(value.text .. " (" .. GetItemCount(value.reagentname, false) .. ")");
      end
    end

    if ((value.type) and (value.type ~= "") and (value.button)) then
      if (value.type == "header") then
        value.visible = true;
        
      elseif ((value.type == "spell") or (value.type == "buff")) then
        if ((value.text) and (value.text ~= "")) then
          if (DagAssist:PlayerKnowsSpell(value.text)) then
            value.visible = true;
            if (not value.IconSet) then
              DagAssist:SetButtonIcon(value);
            end
            
            if (IsUsableSpell(value.text)) then
              value.enabled = true;
            else
              value.enabled = false;
            end
            
            local startTime, duration, cooldownEnabled; 
            startTime, duration, cooldownEnabled = GetSpellCooldown(value.text);
            
            local secondsRemaining = math.ceil(duration - (GetTime() - startTime));
            if (secondsRemaining > 1) then
              if (secondsRemaining > 60) then
                secondsRemaining = math.ceil(secondsRemaining / 60);
                secondsRemaining = string.format(MINUTES_ABBR, secondsRemaining);
              else
                secondsRemaining = string.format(SECONDS_ABBR, secondsRemaining);
              end
              value.enabled = false;
              value.button:SetText(value.text.." ("..secondsRemaining..")");
            else
              value.button:SetText(value.text);
            end           

            -- Add Skill Rand/MaxRank
            for i = 1, GetNumSkillLines() do
              local skillName, _, _, skillRank, _, _, skillMaxRank = GetSkillLineInfo(i);
              if (value.text == skillName) or (value.text=="가죽세공" and skillName=="가죽 세공") then
                value.button:SetText(value.button:GetText().." ("..skillRank.."/"..skillMaxRank..")")
                break;
              elseif (value.text == "제련술" and skillName == "채광") then 
                value.button:SetText(value.button:GetText().." ("..skillRank.."/"..skillMaxRank..")")
                break;
              elseif (value.text == "약초 찾기" and skillName == "약초채집") then
                value.button:SetText(value.button:GetText().." ("..skillRank.."/"..skillMaxRank..")")
                break;
              end
            end     

          else
            value.visible = false;
          end
        else
          value.visible = false;
        end
        
      elseif (value.type == "item") then
        value.visible = true;
        if (not value.IconSet) then
          DagAssist:SetButtonIcon(value);
        end
        
        if (GetItemCount(value.text, false)) > 0 then
          local displayName = value.text;
          if (value.hearthstone) then
            --Set the text and cooldown
            displayName = GetBindLocation();
          end
          
          local startTime, duration, cooldownEnabled; 
          startTime, duration, cooldownEnabled = GetItemCooldown(value.text);
          
          local secondsRemaining = math.ceil(duration - (GetTime() - startTime));
          if ((cooldownEnabled == 1) and (secondsRemaining > 1)) then
            if (secondsRemaining > 60) then
              secondsRemaining = math.ceil(secondsRemaining / 60);
              secondsRemaining = string.format(MINUTES_ABBR, secondsRemaining);
            else
              secondsRemaining = string.format(SECONDS_ABBR, secondsRemaining);
            end
            value.enabled = false;
            value.button:SetText(displayName.." ("..secondsRemaining..")");
          else
            value.enabled = true;
            value.button:SetText(displayName);
          end
        else
          value.enabled = false;
        end
        
      elseif (value.type == "special") then
        value.visible = true;
        
      elseif (value.type == "spacer") then
        value.visible = true;
        
      end
      
      if (value.enabled) then
        value.button:SetAttribute("enabled", true);
      else
        value.button:SetAttribute("enabled", false);
      end
      
      if (value.visible) then
        if previousItem then
          if ((value.type == "header") and (previousItem.type == "header")) then
            if previousItem.button then
              previousItem.button:SetAttribute("visible", false);
            end
            previousItem = previousItem.previous;
          end
        end
        
        if previousItem then
          value.count = previousItem.count + 1;
          value.previous = previousItem;
        else
          value.count = 1;
        end
        
        previousItem = value;
        
        value.button:SetAttribute("visible", true);
      else
        value.button:SetAttribute("visible", false);
      end
    end
    
  end
end

function DagAssist:SetButtonIcon(tableEntry)
  local itemTexture;
  if (tableEntry.text) then
  if ((tableEntry.type == "spell") or (tableEntry.type == "buff")) then
    itemTexture = GetSpellTexture(tableEntry.text);
    
  elseif tableEntry.type == "item" then
    --Get the item texture
    _, _, _, _, _, _, _, _, _, itemTexture = GetItemInfo(tableEntry.text);
    end   
  end   
  
  if (itemTexture) then
    tableEntry.buttonIcon:SetTexture(itemTexture);
    tableEntry.IconSet = true;
  end
end