BINDING_HEADER_Stocks = "Stocks";
BINDING_NAME_Stocks = "검색창 열기/닫기";

local Stocks = CreateFrame("Frame");
local prevTime;
local cs,player;
local tDisplayData = {};
local currencyIndex = {
  ["달라란 보석세공사의 징표"] = 61,
  ["달라란 요리상"] = 81,
  ["용사의 인장"] = 241,
  ["정복 점수"] = 390,
  ["명예 점수"] = 392,
  ["정의 점수"] = 395 };
StocksOption = {};

local function GetItemID(link)
  return link:match("|Hitem:(%d+)");
end

local function UpdateStocks(loc, link, count)
  if not ( link ) then return end;
  local id = GetItemID(link) or currencyIndex[link];
  if not ( id ) then return end;
  if not cs[loc][id] then
    cs[loc][id] = {};
    cs[loc][id].count = count;
    cs[loc][id].link = link;
  else
    cs[loc][id].count = cs[loc][id].count + count;
  end
end

local function GetBankItems()
  if not ( cs ) then return end;
  if prevTime and (GetTime() - prevTime < 1) then
    return
  else
    prevTime = GetTime();
  end
  wipe(cs["BANK"]);
  for container = NUM_BAG_SLOTS + 1, NUM_BAG_SLOTS + NUM_BANKBAGSLOTS + 1 do
    if ( container == NUM_BAG_SLOTS + NUM_BANKBAGSLOTS + 1 ) then container = -1 end;
    local slots =  GetContainerNumSlots(container);
    if  slots > 0 then
      for slot = 1, slots do
        local texture, count, locked, quality, readable, lootable, link = GetContainerItemInfo(container, slot);
        if link and count and ( count > 0 ) then
          UpdateStocks("BANK",link,count);
        end
      end
    end
  end
end

local function GetBagItems()
  if not ( cs ) then return end;
  wipe(cs["BAG"]);
  for container = 0, NUM_BAG_SLOTS do
    local slots =  GetContainerNumSlots(container);
    if  slots > 0 then
      for slot = 1, slots do
        local texture, count, locked, quality, readable, lootable, link = GetContainerItemInfo(container, slot);
        if link and count and ( count > 0 ) then
          UpdateStocks("BAG",link,count);
        end
      end
    end
  end
  MyMoney[player] = GetMoney();
end

local function GetPostItems()
  if not ( cs ) then return end;
  if prevTime and (GetTime() - prevTime < 1) then
    return
  else
    prevTime = GetTime();
  end
  wipe(cs["POST"]);
  local numItems, totalItems = GetInboxNumItems();
  for mailID = 1, numItems do
    local itemCount = select(8,GetInboxHeaderInfo(mailID));
    if itemCount and (itemCount > 0) then
      for attachmentIndex = 1, itemCount do
        local name, itemTexture, count, quality, canUse = GetInboxItem(mailID, attachmentIndex);
        local link = GetInboxItemLink(mailID,attachmentIndex);
        if count and link then
          UpdateStocks("POST",link,count);
        end
      end
    end
  end
end

local function GetInventoryItems()
  if not ( cs ) then return end;
  if ( cs["INVEN"] ) then wipe(cs["INVEN"]) else cs["INVEN"] = {} end;
  for slot = 1, 19 do
    local link = GetInventoryItemLink("player", slot);
    local count = 1;
    if ( slot == 0 ) then
      count = GetInventoryItemCount("player", 0)
    end
    if ( link ) then
      UpdateStocks("INVEN",link,count);
    end
  end
  MyMoney[player] = GetMoney();
end

local function GetCurrencyItems()
  if not ( cs ) then return end;
  wipe(cs["CURRENCY"]);
  local numEntries = GetCurrencyListSize();
  for index = 1, numEntries do
    local name, isHeader, isExpanded, isUnused, isWatched, count, icon = GetCurrencyListInfo(index);
    if ( not isHeader ) and name and ( count and count > 0 ) then
      UpdateStocks("CURRENCY",name,count);
    end
  end
end

local function UpdateGuildStocks(link, count)
  if not ( StocksOption.includeGuildBank ) or not ( link ) then return end;
  local pName, gName;
  local guildName = GetGuildInfo("player");
  local id = GetItemID(link);
  for pName, gName in pairs(StocksOption.guildList) do
    if ( gName == guildName ) and ( MyStocks[pName] ) then
      if not ( MyStocks[pName]["GUILD"][id] ) then
        MyStocks[pName]["GUILD"][id] = {};
        MyStocks[pName]["GUILD"][id].link = cs["GUILD"].link;
      end
      MyStocks[pName]["GUILD"][id].count = cs["GUILD"][id].count;
    end
  end
end

local function GetGuildBankItems()
  if not ( cs ) then return end;
  if not ( StocksOption.includeGuildBank ) then return end;
  if ( prevTime ) and (GetTime() - prevTime < 1) then
    return
  else
    prevTime = GetTime();
  end
  wipe(cs["GUILD"]);
  if IsInGuild() and not ( StocksOption.guildList[player] ) then
    StocksOption.guildList[player] = GetGuildInfo("player");
  end
  if ( not MAX_GUILDBANK_SLOTS_PER_TAB ) then return end;
  for tab = 1, GetNumGuildBankTabs() do
    for slot = 1, MAX_GUILDBANK_SLOTS_PER_TAB do
      local texture, count, locked = GetGuildBankItemInfo(tab, slot);
      if count and ( count > 0 ) then
        local link = GetGuildBankItemLink(tab, slot);
        UpdateStocks("GUILD",link,count);
        UpdateGuildStocks(link,count);
      end
    end
  end
end

function Stocks.OnLoad(self)
  self:SetScript("OnEvent",self.OnEvent);
  self:RegisterEvent("VARIABLES_LOADED");
  self:RegisterEvent("PLAYER_ENTERING_WORLD");
  SLASH_Stocks1 = "/stocks";
  SLASH_Stocks2 = "/ㄴ새찬";
  SlashCmdList["Stocks"] = function(cmd)
    local param1 = cmd:match("^(.*)$");
    if ( param1 ) then
      id = tonumber(param1);
      _G["StocksConfig"]:Show();
      if ( id ) then
        _G["mID"]:SetText(param1);
      else
        _G["mItem"]:SetText(param1);
      end
      self:ExecQuery();
    else
      _G["StocksConfig"]:Show();
    end
  end;
end

function Stocks.OnEvent(self,event,...)
  local arg1 = ...;
  if (event == "VARIABLES_LOADED") then
    player = UnitName("player");
    MyStocks = MyStocks or {};
    MyMoney = MyMoney or {};
    if not ( MyStocks[player] ) then
      MyStocks[player] = {};
      MyStocks[player]["BANK"] = {};
      MyStocks[player]["BAG"] = {};
      MyStocks[player]["POST"] = {};
      MyStocks[player]["INVEN"] = {};
      MyStocks[player]["CURRENCY"] = {};
      MyStocks[player]["GUILD"] = {};
    end
    if not ( MyMoney[player] ) then
      MyMoney[player] = 0;
    end
    if not ( MyStocks[player].realm ) then
      MyStocks[player].realm = GetRealmName();
    end
    if not ( MyStocks[player]["CURRENCY"] ) then
      MyStocks[player]["CURRENCY"] = {};
    end
    if not ( MyStocks[player]["GUILD"] ) then
      MyStocks[player]["GUILD"] = {};
    end
    if not ( StocksOption.guildList ) then
      StocksOption.guildList = {};
    end
    cs = MyStocks[player];
    cm = MyMoney[player];
    self:Config();
  elseif (event == "BANKFRAME_CLOSED") then
    GetBankItems();
    GetBagItems();
  elseif (event == "BAG_UPDATE") and (arg1 >= 0) then
    self.wait = 0;
    if not self:GetScript("OnUpdate") then
      self:SetScript("OnUpdate",self.OnUpdate);
    end
  elseif (event == "MAIL_CLOSED") then
    GetPostItems();
  elseif (event == "UNIT_INVENTORY_CHANGED") then
    GetInventoryItems();
  elseif (event == "PLAYER_ENTERING_WORLD") then
    self:UnregisterEvent(event);
    self:RegisterEvent("BANKFRAME_CLOSED");
    self:RegisterEvent("BAG_UPDATE");
    self:RegisterEvent("MAIL_CLOSED");
    self:RegisterEvent("UNIT_INVENTORY_CHANGED");
    self:RegisterEvent("CURRENCY_DISPLAY_UPDATE");
    self:RegisterEvent("GUILDBANKFRAME_CLOSED");
    if ( IsInGuild() ) then
      self:RegisterEvent("PLAYER_GUILD_UPDATE");
    end
    GetInventoryItems();
    GetCurrencyItems();
    --GetBagItems();
  elseif (event == "PLAYER_REGEN_ENABLED") then
    self:UnregisterEvent(event);
    self:SetScript("OnUpdate",self.OnUpdate);
  elseif (event == "CURRENCY_DISPLAY_UPDATE") then
    GetCurrencyItems();
  elseif (event == "GUILDBANKFRAME_CLOSED") then
    GetGuildBankItems();
  elseif (event == "PLAYER_GUILD_UPDATE") then
    local guildName = GetGuildInfo("player");
    StocksOption.guildList[player] = guildName;
    self:UnregisterEvent(event);
  end
end

function Stocks.OnUpdate(self,elapsed)
  self.wait = self.wait + elapsed;
  if ( self.wait > 5 ) then
    if InCombatLockdown() then
      self:SetScript("OnUpdate",nil);
      self.wait = 0;
      self:RegisterEvent("PLAYER_REGEN_ENABLED");
      return;
    end
    GetBagItems();
    self:SetScript("OnUpdate",nil);
    self.wait = 0;
 end
end

function Stocks.Reset(self)
  StocksConfig:Hide();
  wipe(MyStocks);
  MyStocks[player] = {};
  MyStocks[player]["BANK"] = {};
  MyStocks[player]["BAG"] = {};
  MyStocks[player]["POST"] = {};
  MyStocks[player]["INVEN"] = {};
  MyStocks[player]["CURRENCY"] = {};
  MyStocks[player]["GUILD"] = {};
  MyStocks[player].realm = GetRealmName();
  wipe(MyMoney);
  MyMoney[player] = 0;
  cs = MyStocks[player];
  cm = MyMoney[player];
  GetBagItems();
  GetInventoryItems();
  GetCurrencyItems();
  print("Stocks-> 모든 자료가 초기화 되었습니다.");
end

local tLoc = {BANK = "은행", BAG = "가방", POST = "우편", INVEN = "착용", CURRENCY = "화폐", GUILD = "길드"};
local numFind,sum;
function Stocks.SearchItems(self,sname,sid,sclass,ssubclass)
  numFind,sum = 0,0;
  for p,v1 in pairs(MyStocks) do
    if ( cs.realm == v1.realm ) then
      for l,v2 in pairs(v1) do
        if ( type(v2) == "table" ) then
          for id,v3 in pairs(v2) do
            local name, link, quality, iLevel, reqLevel, class, subclass, maxStack, equipSlot, texture, vendorPrice = GetItemInfo(id);
            name = name or GetCurrencyInfo(id);
            if not ( name ) or ( name == "" ) then
              -- print("아이템 ID: "..id.." (은)는 잘못된 자료이거나, 해당 아이템에 대한 캐쉬 정보가 없습니다.");
            else
              local flag=0; local logic;
              if ( sname ) then logic = name:match(sname);flag=1; end;
              if ( sid ) then
                if ( flag == 1 ) then
                  logic = logic and (id == sid);
                else
                  logic = (id == sid);
                  flag = 1;
                end;
              end
              if ( sclass ) then
                if ( flag == 1 ) then
                  logic = logic and class:match(sclass);
                else
                  logic = class:match(sclass);
                  flag = 1;
                end;
              end
              if ( ssubclass ) then
                if ( flag == 1 ) then
                  logic = logic and subclass:match(ssubclass);
                else
                  logic = subclass:match(ssubclass);
                end;
              end
              if ( logic ) then
                table.insert(tDisplayData,{p,tLoc[l],v3.count,class,subclass,v3.link});
                numFind = numFind + 1;
                sum = sum + v3.count;
              end
            end
          end
        end
      end
    end
  end
end

local fieldName = {"Owner","Loc","Count","Class","SubClass","Link"};
function Stocks.ScrollBar_Update(self)
  local index;
  local numList = numFind and (numFind < 10 and 11 or numFind) or 11;
  FauxScrollFrame_Update(mList,numList,10,16);
  for line = 1, 10 do
    index = line + FauxScrollFrame_GetOffset(mList);
    if index < numList then
      if tDisplayData[index] then
        for k = 1, 6 do
          _G["mListLine"..line..fieldName[k]]:SetText(tDisplayData[index][k]);
        end
        _G["mListLine"..line]:Show();
      else
        _G["mListLine"..line]:Hide();
      end
    else
      _G["mListLine"..line]:Hide();
    end
  end
end

local function GetTotalMoney(name)
  local sum = 0;
  if ( name ) then
    sum = MyMoney[name] or 0;
  else
    for k,v in pairs(MyMoney) do
      if ( cs.realm == MyStocks[k].realm ) then
        sum = sum + v;
      end
    end
  end
  local copper = (sum % 100);
  local silver = floor(sum % 10000 / 100);
  local gold = floor(sum / 10000);
  return format(GOLD_AMOUNT_TEXTURE.." "..SILVER_AMOUNT_TEXTURE.." "..COPPER_AMOUNT_TEXTURE,gold,16,16,silver,16,16,copper,16,16);
end

function Stocks.Config(self)
  local menu = CreateFrame("Frame","StocksConfig",UIParent);
  menu:SetWidth(590);
  menu:SetHeight(190);
  menu:SetPoint("CENTER",0,100);
  menu:SetBackdrop(ChatConfigBackgroundFrame:GetBackdrop());
  menu:SetBackdropColor(0.15,0.15,0.15);
  menu:SetBackdropBorderColor(0.0,0.1,1.0);
  menu:SetMovable(true);
  menu:EnableMouse(true);
  local tr = menu:CreateTitleRegion();
  tr:SetAllPoints(menu);
  tinsert(UISpecialFrames,"StocksConfig");
  menu:Hide();
  local title = menu:CreateFontString(nil,"OVERLAY","GameFontNormalLarge");
  title:SetPoint("TOPLEFT",menu,"TOPLEFT",30,-30);
  title:SetText("Stocks 검색 메뉴");
  local subtitle = menu:CreateFontString(nil,"OVERLAY","GameFontHighlightSmall");
  subtitle:SetPoint("TOPLEFT",title,"BOTTOMLEFT",0,-10);
  subtitle:SetText("각 해당 항목별 또는 다중 항목을 조건으로 검색 가능합니다.");
  local mResetBtn = CreateFrame("Button","mResetButton",menu,"OptionsButtonTemplate");
  mResetBtn:SetPoint("TOPRIGHT",menu,"TOPRIGHT",-10,-10);
  mResetBtn:SetText("자료 초기화");
  mResetBtn:SetScript("OnClick",function(self)
    StaticPopup_Show("STOCKS_DATA_RESET");
  end);
  local showTooltip = CreateFrame("CheckButton","mShowTooltip",menu,"InterfaceOptionsCheckButtonTemplate");
  showTooltip:SetPoint("TOPLEFT",subtitle,"TOPRIGHT",30,-5);
  _G["mShowTooltipText"]:SetText("툴팁에 보유수량 표시");
  showTooltip:SetScript("OnShow",function(self) self:SetChecked(StocksOption.showtooltip) end);
  showTooltip:SetScript("OnClick",function(self) StocksOption.showtooltip = self:GetChecked() end);
  local includeGuildBank = CreateFrame("CheckButton","mIncludeGuildBank",menu,"InterfaceOptionsCheckButtonTemplate");
  includeGuildBank:SetPoint("TOPLEFT",showTooltip,"TOPRIGHT",110,0);
  _G["mIncludeGuildBankText"]:SetText("길드 은행 포함");
  includeGuildBank:SetScript("OnShow",function(self) self:SetChecked(StocksOption.includeGuildBank) end);
  includeGuildBank:SetScript("OnClick",function(self) StocksOption.includeGuildBank = self:GetChecked() end);
  local mNameTag = menu:CreateFontString(nil,"OVERLAY","GameFontNormal");
  mNameTag:SetPoint("TOPLEFT",subtitle,"BOTTOMLEFT",0,-20);
  mNameTag:SetText("검색할 아이템 이름");
  local mName = CreateFrame("EditBox","mItem",menu,"InputBoxTemplate");
  mName:SetWidth(100);
  mName:SetHeight(20);
  mName:SetPoint("LEFT",mNameTag,"LEFT",130,0);
  mName:SetScript("OnShow",function(self) self:SetText("") end);
  mName:SetScript("OnTabPressed",function(self) _G["mID"]:SetFocus() end);
  mName:SetScript("OnEnterPressed",function(self) Stocks:ExecQuery() end);
  mName:SetAutoFocus(false);
  local mIDTag = menu:CreateFontString(nil,"OVERLAY","GameFontNormal");
  mIDTag:SetPoint("TOPLEFT",mNameTag,"BOTTOMLEFT",0,-10);
  mIDTag:SetText("검색할 아이템 ID");
  local mID = CreateFrame("EditBox","mID",menu,"InputBoxTemplate");
  mID:SetWidth(100);
  mID:SetHeight(20);
  mID:SetPoint("LEFT",mIDTag,"LEFT",130,0);
  mID:SetScript("OnShow",function(self) self:SetText("") end);
  mID:SetScript("OnTabPressed",function(self) _G["mClass"]:SetFocus() end);
  mID:SetScript("OnEnterPressed",function(self) Stocks:ExecQuery() end);
  mID:SetAutoFocus(false);
  local mClassTag = menu:CreateFontString(nil,"OVERLAY","GameFontNormal");
  mClassTag:SetPoint("TOPLEFT",mIDTag,"BOTTOMLEFT",0,-10);
  mClassTag:SetText("검색할 아이템 대분류");
  local mClass = CreateFrame("EditBox","mClass",menu,"InputBoxTemplate");
  mClass:SetWidth(100);
  mClass:SetHeight(20);
  mClass:SetPoint("LEFT",mClassTag,"LEFT",130,0);
  mClass:SetScript("OnShow",function(self) self:SetText("") end);
  mClass:SetAutoFocus(false);
  mClass:SetScript("OnTabPressed",function(self) _G["mSubClass"]:SetFocus() end);
  mClass:SetScript("OnEnterPressed",function(self) Stocks:ExecQuery() end);
  local mSubClassTag = menu:CreateFontString(nil,"OVERLAY","GameFontNormal");
  mSubClassTag:SetPoint("TOPLEFT",mClassTag,"BOTTOMLEFT",0,-10);
  mSubClassTag:SetText("검색할 아이템 소분류");
  local mSubClass = CreateFrame("EditBox","mSubClass",menu,"InputBoxTemplate");
  mSubClass:SetWidth(100);
  mSubClass:SetHeight(20);
  mSubClass:SetPoint("LEFT",mSubClassTag,"LEFT",130,0);
  mSubClass:SetScript("OnShow",function(self) self:SetText("") end);
  mSubClass:SetScript("OnTabPressed",function(self) _G["mItem"]:SetFocus() end);
  mSubClass:SetScript("OnEnterPressed",function(self) Stocks:ExecQuery() end);
  mSubClass:SetAutoFocus(false);
  local panel = CreateFrame("Frame","mOutput",menu);
  panel:SetWidth(590);
  panel:SetHeight(250);
  panel:SetBackdrop(menu:GetBackdrop());
  panel:SetBackdropColor(0.15,0.15,0.15);
  panel:SetBackdropBorderColor(0.0,1.0,1.0,1);
  panel:Hide();
  panel:SetPoint("TOP",menu,"BOTTOM",0,-5);
  local list = CreateFrame("ScrollFrame","mList",panel,"FauxScrollFrameTemplateLight");
  list:SetWidth(500);
  list:SetHeight(180);
  list:SetPoint("TOPLEFT",panel,"TOPLEFT",20,-30);
  for i = 1, 10 do
    local f = CreateFrame("Button","mListLine"..i,panel,"PanelListTemplate");
    if i == 1 then
      f:SetPoint("TOPLEFT",list,"TOPLEFT",2,-2);
    else
      f:SetPoint("TOPLEFT","mListLine"..(i-1),"BOTTOMLEFT",0,-2);
    end
  end
  list:SetScript("OnVerticalScroll",function(self,offset)
    FauxScrollFrame_OnVerticalScroll(self, offset, 16, Stocks.ScrollBar_Update);
  end);
  list:SetScript("OnShow",function(self) Stocks:ScrollBar_Update() end);
  local header = CreateFrame("Button","mHeader",panel,"PanelListTemplate");
  local headerText = {"소유자","위치","수량","대분류","소분류","아이템"};
  header:SetPoint("BOTTOMLEFT",list,"TOPLEFT",0,5);
  for i = 1, 6 do
    _G["mHeader"..fieldName[i]]:SetText(headerText[i]);
    _G["mHeader"..fieldName[i]]:SetTextColor(1,1,1);
    _G["mHeader"]:SetScript("OnClick",nil);
    _G["mHeader"]:EnableMouse(false);
  end
  local summary = panel:CreateFontString("mResult","OVERLAY","GameFontHighlight");
  summary:SetPoint("TOPLEFT",list,"BOTTOMLEFT",0,-10);
  local mOKBtn = CreateFrame("Button","mQuery",menu,"OptionsButtonTemplate");
  mOKBtn:SetPoint("LEFT",mSubClass,"RIGHT",20,0);
  mOKBtn:SetText("검색");
  mOKBtn:SetScript("OnClick",function(self) Stocks:ExecQuery() end);
  local mClsBtn = CreateFrame("Button","mClear",menu,"OptionsButtonTemplate");
  mClsBtn:SetPoint("LEFT",mOKBtn,"RIGHT",10,0);
  mClsBtn:SetText("검색초기화");
  mClsBtn:SetScript("OnClick",function(self)
    mName:SetText("");
    mID:SetText("");
    mClass:SetText("");
    mSubClass:SetText("");
    wipe(tDisplayData);
    summary:SetText("");
    FauxScrollFrame_SetOffset(mList,0);
    _G["mListScrollBar"]:SetValue(0);
    Stocks:ScrollBar_Update();
    mOutput:Hide();
  end);
  local mCloseBtn = CreateFrame("Button","mClose",menu,"OptionsButtonTemplate");
  mCloseBtn:SetPoint("LEFT",mClsBtn,"RIGHT",10,0);
  mCloseBtn:SetText("닫기");
  mCloseBtn:SetScript("OnClick",function(self)
    self:GetParent():Hide();
  end);
  menu:SetScript("OnHide", function(self) panel:Hide() end);
  local mMoney = CreateFrame("Frame","mMoneyFrame",menu);
  mMoney:SetWidth(220);
  mMoney:SetHeight(30);
  mMoney:SetPoint("LEFT",mName,"RIGHT",50,-20);
  mMoney:SetBackdrop(ChatConfigBackgroundFrame:GetBackdrop());
  mMoney:SetBackdropColor(0.15,0.15,0.15,0.15);
  mMoney:SetBackdropBorderColor(1.0,0.82,0,1);
  mMoney:EnableMouse(true);
  local moneyTag = mMoney:CreateFontString(nil,"OVERLAY","GameFontNormal");
  moneyTag:SetPoint("LEFT",mMoney,"LEFT",15,0);
  moneyTag:SetText("총 보유 골드: ");
  local amountMoney = mMoney:CreateFontString(nil,"OVERLAY","GameFontNormal");
  amountMoney:SetPoint("LEFT",moneyTag,"RIGHT",5,0);
  mMoney:SetScript("OnShow",function(self)
    amountMoney:SetText(GetTotalMoney());
  end);
  mMoney:SetScript("OnEnter",function(self)
    GameTooltip:SetOwner(self,"ANCHOR_BOTTOMRIGHT",5,30);
    for name,money in pairs(MyMoney) do
      GameTooltip:AddLine(name.." : "..GetTotalMoney(name));
    end
    GameTooltip:Show();
  end);
  mMoney:SetScript("OnLeave",function(self)
    GameTooltip:Hide();
  end);
end

function Stocks.ExecQuery(self)
  local sname = _G["mItem"]:GetText();
  if sname == "" then sname = nil end;
  local sid = _G["mID"]:GetText();
  if sid == "" then sid = nil end;
  local sclass = _G["mClass"]:GetText();
  if sclass == "" then sclass = nil end;
  local ssubclass = _G["mSubClass"]:GetText();
  if ssubclass == "" then ssubclass = nil end;
  wipe(tDisplayData);
  _G["mResult"]:SetText("");
  Stocks:SearchItems(sname,sid,sclass,ssubclass);
  FauxScrollFrame_SetOffset(mList,0);
  _G["mListScrollBar"]:SetValue(0);
  Stocks:ScrollBar_Update();
  _G["mResult"]:SetText(format("검색된 항목:%d 건, 수량 합계: %d",numFind,sum));
  mOutput:Show();
end

local function CheckStocks(id)
  local stocks = {};
  local owner = 0;
  for p, v in pairs(MyStocks) do
    if ( cs.realm == v.realm ) then
      for l, v2 in pairs(v) do
        if ( type(v2) == "table" ) and ( v2[id] ) then
          if not ( stocks[p] ) then
            stocks[p] = v2[id].count;
            owner = owner + 1;
          else
            stocks[p] = stocks[p] + v2[id].count;
          end
        end
      end
    end
  end
  return owner,stocks;
end

Stocks:OnLoad(self);

local lineAdded, isRecipe;
local exceptList = {["귀환석"]=1};
local function OnTooltipSetItem(self)
  if ( not StocksOption.showtooltip ) or ( lineAdded ) then return end;
  local name,link = self:GetItem();
  if ( name ) and ( exceptList[name] ) then return end;
  if ( link ) then
    local itemType = select(6,GetItemInfo(link));
    if ( itemType=="제조법" ) and ( not isRecipe ) then
      isRecipe = 1;
      return;
    end
    local id = GetItemID(link);
    local numStocks,stockItem = CheckStocks(id);
    if ( numStocks ) and ( numStocks > 0 ) then
      local prevGuild = "";
      for k,v in pairs(stockItem) do
        local gc = MyStocks[k]["GUILD"][id] and MyStocks[k]["GUILD"][id].count;
        local nMine = gc and (v-gc) or v;
        if ( k ~= player ) and ( StocksOption.guildList[k] ) and ( StocksOption.guildList[k] == StocksOption.guildList[player] ) and ( nMine == 0 ) then
          -- skip
        else
          self:AddLine(k..":"..nMine.."개 보유"..(StocksOption.includeGuildBank and gc and "(길드:"..gc..")" or ""),0,1,1);
          prevGuild = StocksOption.guildList[k] ;
        end
      end
      lineAdded = true;
    end
  end
end

GameTooltip:HookScript("OnTooltipSetItem", OnTooltipSetItem)
GameTooltip:HookScript("OnTooltipCleared", function(self) lineAdded=nil;isRecipe=nil; end);

local function ShowNumTokens(tooltip)
  tokenName = _G[tooltip:GetName().."TextLeft1"]:GetText();
  tokenIndex = currencyIndex[tokenName];
  if not ( tokenIndex ) then return end;
  local numStocks,stockItem = CheckStocks(tokenIndex);
  if ( numStocks ) and ( numStocks > 0 ) then
    for k,v in pairs(stockItem) do
      local nMine = v;
      if ( k ~= player ) and ( nMine == 0 ) then
          -- skip
      else
        tooltip:AddLine(k..":"..nMine.."개 보유",0,1,1);
      end
    end
  end
  tooltip:Show();
end

local SetBackpackToken = GameTooltip.SetBackpackToken;
GameTooltip.SetBackpackToken = function(self,...)
  SetBackpackToken(self,...);
  ShowNumTokens(self);
end

local SetCurrencyToken = GameTooltip.SetCurrencyToken;
GameTooltip.SetCurrencyToken = function(self,...)
  SetCurrencyToken(self,...)
  ShowNumTokens(self);
end

StaticPopupDialogs["STOCKS_DATA_RESET"] = {
  text = "모든 자료를 초기화합니다.",
  button1 = OKAY,
  button2 = CANCEL,
  OnAccept = function(self)
    Stocks:Reset();
  end,
  timeout = 60,
  exclusive = 1,
  whileDead = 1,
  showAlert = 1,
  hideOnEscape = 1
};
