Module:FocusList

From Fire Emblem Heroes Wiki
Jump to: navigation, search

Documentation for this module may be created at Module:FocusList/doc

local p = {}
local cargo = mw.ext.cargo
local Util = require 'Module:Util'

--Function to create the list of current summoning focus
function p._currentFocusList(args)
  local date = os.date('%Y-%m-%d', os.time() - 25200)
  -- Cargo queries
  local focustables = "SummoningFocuses"
  local focusfields = "_pageName,Name,StartDate,EndDate,FocusHeroes"
  local focusquery = {
    where = 'DATEDIFF(EndDate,"' .. date .. '")>0 AND DATEDIFF(StartDate,"' .. date .. '")<=0',
    groupBy = "_pageName",
    orderBy = 'StartDate DESC'
  }
  local focusQueryResult = cargo.query(focustables,focusfields,focusquery)

  if focusQueryResult == nil then
    return '(no values)'
  end

  -- Sort table by start date (More recent banners come first)
  -- table.sort(focusQueryResult.results, dateCompare)

  -- Initialize the content string we'll be returning
  local content = ''

  -- Iterate through all the summoning focus results and create Template:Focus tables for them
  if type( focusQueryResult ) == 'table' then
    for key,focus in ipairs( focusQueryResult ) do
      -- Initialize the table
      local tbl = mw.html.create('table')
        :addClass('wikitable default')
        :css('text-align','center')
        :css('width','100%')

      -- Header - Name of Summoning Focus
      tbl:tag('th')
        :wikitext('<b>' .. focus.Name .. '</b>' )
        :attr('colspan', '3')

      -- Image of Summoning Focus Banner and text link to focus page
      tbl:tag('tr'):tag('td')
        :wikitext( '[[File:Banner Focus ' .. Util.mf(mw.ustring.gsub( focus._pageName, " %(Focus%)", "" ))  .. '.png|275px|link=' .. focus._pageName .. ']]<br/>[[' .. focus._pageName .. '|' .. focus.Name .. ']]')
        :css('text-align','center')
        :css('width','33%')
        :attr('rowspan','4')

      -- Table Cell w/ Summoning Focus Featured Units Label
      local heroTR = tbl:tag('tr')
      heroTR:tag('td')
        :wikitext( '<b>Featured Units</b>' )
        :css('width','12%')

      -- Table Cell w/ Hero Icons of the Featured Units
      local heroIconTD = heroTR:tag('td'):css('width','55%'):css('height','50%')

      -- Loop through all the focus heroes and create icon for each
      local heroset = Util.strsplit(";",focus.FocusHeroes)
      for _, focusHero in ipairs(heroset) do
        if focusHero == '' or focusHero == nil then --Do nothing for empty fields
        else
          -- We need to query to get the hero's weapon and move type
          local heroQuery = cargo.query("Heroes","WeaponType,MoveType",{ where = '_pageName=\'' .. Util.escq(focusHero) .. '\'', groupBy = "_pageName" })
          local weapon = heroQuery[1].WeaponType
          local move = heroQuery[1].MoveType

          -- Image Overlay of the Hero Icon, Weapon Type Icon, and Move Type Icon
          -- See Template:Image Overlay
          -- This is a LUA/CSS rendition of Template:HeroIcon with Type and Name
          local heroIconDiv = heroIconTD:tag('div')
            :css('display','inline-block')
            :css('padding','5px')
            :css('vertical-align','top')

          local heroIcon = heroIconDiv:tag('div')
            :css('position','relative')
            :css('top','0px')
            :css('left','0px')

          -- Hero Icon
          local bottomImg = heroIcon:tag('div')
          bottomImg:wikitext(Util.getHeroIcon(focusHero, '90px'))
            :css('position','relative')
            :css('top','0px')
            :css('left','0px')

          -- Weapon Type Icon
          local topImg = heroIcon:tag('div')
          topImg:wikitext( '[[File:Icon Class ' .. weapon .. '.png|22px|link=]]')
            :css('position','absolute')
            :css('top','2px')
            :css('left','2px')
            :css('z-index','3')

          -- Move Type Icon
          local topImg2 = heroIcon:tag('div')
          topImg2:wikitext( '[[File:Icon Move ' .. move .. '.png|20px|link=]]')
            :css('position','absolute')
            :css('top','65px')
            :css('left','67px')
            :css('z-index','3')
          
          -- Text Link to Hero page
          heroIcon:tag('div'):wikitext('[[' .. focusHero .. ']]')
            :css('width','100px')
        end
      end

      -- Start Date of Summoning Focus
      local startDateTR = tbl:tag('tr')
      startDateTR:tag('td')
        :wikitext('<b>Start Date</b>')
      startDateTR:tag('td')
        :wikitext(focus.StartDate)

      -- End Date of Summoning Focus
      local endDateTR = tbl:tag('tr')
      endDateTR:tag('td')
        :wikitext('<b>End Date</b>')
      endDateTR:tag('td')
        :wikitext(focus.EndDate)

      content = content .. tostring(tbl)
    end
    return tostring(content)
  end
end

function p._getCurrentBannerSlideshowList()
  local date = os.date('%Y-%m-%d', os.time() - 25200)
  -- Cargo queries
  local focustables = "SummoningFocuses"
  local focusfields = "_pageName,StartDate,EndDate,FocusHeroes,Name"
  local focusquery = {
    where = 'DATEDIFF(EndDate,"' .. date .. '")>0 and DATEDIFF(StartDate,"' .. date .. '")<=0',
	groupBy = "_pageName",
	orderBy = 'StartDate DESC'
  }
  local focusQueryResult = cargo.query(focustables,focusfields,focusquery)

  if focusQueryResult == nil then
    return '(no values)'
  end

  -- Sort table by start date (More recent banners come first)
  --table.sort(focusQueryResult.results, dateCompare)

  -- Initialize the bannerList string we'll be returning
  local bannerList = ''

  -- Iterate through all the summoning focus results and create Template:Focus tables for them
  if type(focusQueryResult) == 'table' then
    for key,focus in ipairs( focusQueryResult ) do
      -- Get the banner name from Name field
      local bannerName = focus.Name

      -- Get countdown text
      local countdown = ''
      local timediff = os.time{year=focus.EndDate:match("^[^-]+"), month=focus.EndDate:match("-([^-]+)-"), day=focus.EndDate:match("[^-]+$"), hour=6, min=59, sec=59} - os.time()
      if timediff > 172800 then
      	countdown = 'Ends in ' .. math.floor(timediff / 86400) .. ' day(s).'
      elseif timediff > 86400 then
      	countdown = '<b>Ends in ' .. math.floor(timediff / 86400) .. ' day(s).</b>'
  	  elseif timediff > 3600 then
  	  	countdown = '<b>Ends in ' .. math.floor(timediff / 3600) .. ' hr(s).</b>'
  	  else
  	  	countdown = '<b>Ends in ' .. math.floor(timediff / 60) .. ' min(s).</b>'
  	  end

      -- Add the banner in the format we need.
      -- Example format below
      -- File:Banner Focus Choose Your Legends Top 8 Block B.png|[[Choose Your Legends Top 8 Block B (Focus)]]|[[Choose Your Legends Top 8 Block B (Focus)|Choose Your Legends Top 8 Block B]]
      bannerList = bannerList .. "File:Banner Focus " .. Util.mf(mw.ustring.gsub( focus._pageName, " %(Focus%)", "" )).. ".png|[[" .. focus._pageName .. "|" .. bannerName .. "]]|[[" .. focus._pageName .. "|" .. bannerName .. "]]<br>" .. countdown .. "\n"
    end
    return bannerList
  end
end

-- Function that gets banners between a specific start and end date
function getBannersForMonth(startDateLowerLimit, startDateUpperLimit)
  -- Cargo queries
  local focustables = "SummoningFocuses"
  local focusfields = "_pageName,StartDate,EndDate,FocusHeroes,Name"
  local focusquery = {
    where = 'DATEDIFF(StartDate,"' .. startDateLowerLimit .. '")>=0 and DATEDIFF(StartDate,"' .. startDateUpperLimit .. '")<=0',
	groupBy = "_pageName",
	orderBy = 'StartDate DESC'
  }
  local focusQueryResult = cargo.query(focustables,focusfields,focusquery)

  if focusQueryResult == nil then
    return '(no values)'
  end

  -- Sort table by start date (More recent banners come first)
  --table.sort(focusQueryResult.results, dateCompare)

  -- Initialize the content string we'll be returning
  local content = ''

  -- Iterate through all the summoning focus results and create Template:Focus tables for them
  if type( focusQueryResult ) == 'table' then
    for key,focus in ipairs( focusQueryResult ) do

      -- Initialize the table
      local tbl = mw.html.create('table')
        :addClass('wikitable default')
        :css('text-align','center')
        :css('width','100%')

      -- Header - Name of Summoning Focus
      tbl:tag('th')
        :wikitext('<b>' .. focus.Name .. '</b>' )
        :attr('colspan', '3')

      -- Image of Summoning Focus Banner and text link to focus page
      tbl:tag('tr'):tag('td')
        :wikitext( '[[File:Banner Focus ' .. Util.mf(mw.ustring.gsub( focus._pageName, " %(Focus%)", "" ))  .. '.png|275px|link=' .. focus._pageName .. ']]<br/>[[' .. focus._pageName .. '|' .. focus.Name .. ']]')
        :css('text-align','center')
        :css('width','33%')
        :attr('rowspan','4')

      -- Table Cell w/ Summoning Focus Featured Units Label
      local heroTR = tbl:tag('tr')
      heroTR:tag('td')
        :wikitext( '<b>Featured Units</b>' )
        :css('width','12%')

      -- Table Cell w/ Hero Icons of the Featured Units
      local heroIconTD = heroTR:tag('td'):css('width','55%'):css('height','50%')

      -- Loop through all the focus heroes and create icon for each
		local heroset = Util.strsplit(";",focus.FocusHeroes)
        for _, focusHero in ipairs(heroset) do
		  if focusHero == '' or focusHero == nil then --Do nothing for empty fields
	      else
            -- We need to query to get the hero's weapon and move type
            local heroQuery = cargo.query("Heroes","WeaponType,MoveType",{ where = '_pageName=\'' .. Util.escq(focusHero) .. '\'', groupBy = "_pageName" })
            local weapon = heroQuery[1].WeaponType
            local move = heroQuery[1].MoveType

            -- Image Overlay of the Hero Icon, Weapon Type Icon, and Move Type Icon
            -- See Template:Image Overlay
            -- This is a LUA/CSS rendition of Template:HeroIcon with Type and Name
            local heroIconDiv = heroIconTD:tag('div')
              :css('display','inline-block')
              :css('padding','5px')
              :css('vertical-align','top')

            local heroIcon = heroIconDiv:tag('div')
              :css('position','relative')
              :css('top','0px')
              :css('left','0px')

            -- Hero Icon
            local bottomImg = heroIcon:tag('div')
            bottomImg:wikitext(Util.getHeroIcon(focusHero, '90px'))
              :css('position','relative')
              :css('top','0px')
              :css('left','0px')

            -- Weapon Type Icon
            local topImg = heroIcon:tag('div')
            topImg:wikitext( '[[File:Icon Class ' .. weapon .. '.png|22px|link=]]')
              :css('position','absolute')
              :css('top','2px')
              :css('left','2px')
              :css('z-index','3')

            -- Move Type Icon
            local topImg2 = heroIcon:tag('div')
            topImg2:wikitext( '[[File:Icon Move ' .. move .. '.png|20px|link=]]')
              :css('position','absolute')
              :css('top','65px')
              :css('left','67px')
              :css('z-index','3')
            
            -- Text Link to Hero page
            heroIcon:tag('div'):wikitext('[[' .. focusHero .. ']]')
              :css('width','100px')
		  end
        end

        -- Start Date of Summoning Focus
        local startDateTR = tbl:tag('tr')
        startDateTR:tag('td')
          :wikitext('<b>Start Date</b>')
        startDateTR:tag('td')
          :wikitext(focus.StartDate)

        -- End Date of Summoning Focus
        local endDateTR = tbl:tag('tr')
        endDateTR:tag('td')
          :wikitext('<b>End Date</b>')
        endDateTR:tag('td')
          :wikitext(focus.EndDate)

        content = content .. tostring(tbl)
    end
    return tostring(content .. '<br/>')
  end
end

-- Function to create the list of previous summoning focus
function p._archiveFocusList()
  local content = ''

  -- Setting initial date. Game was released on February 2017
  -- To grab all banners for a month, we're going to be setting the date limit to the first of each month.
  -- For example, February 2017 banners have a date limit of March 1, 2017.
  local month = 2
  local year = 2017
  local day = 1

  -- Grab the current date. We need to loop through the months and years until this date.
  local currMonth = tonumber( os.date( '%m' ) )
  local currYear = tonumber( os.date( '%Y' ) )

  -- If there is more than one year, we need to a way to keep track of the months year-to-year.
  -- So we keep track of total number of months there are between current date and game release date
  local yearDiff = currYear - year
  local totalMonths = currMonth
  if yearDiff ~= 0 then
    totalMonths = totalMonths + yearDiff * 12
  end
  local monthTracker = month

  -- Loop through each year
  while year <= currYear do

    -- Loop through each month up and not including the current month
    while monthTracker < totalMonths do

      -- We need to get the actual month number, so mod the total months by 12.
      -- (Modding by 12 will get us 0 for December)
      local modMonth = monthTracker % 12

      -- A modMonth of 0 is actually December, so manually set it.
      if modMonth == 0 then modMonth = 12 end

      -- Set the start date limits and then get the banners with start dates in that range.
      local startDateLowerLimit = os.date( '%Y-%m-%d' , os.time{year=year, month=modMonth, day=day, hour=0} )
      local startDateUpperLimit = ''

      -- If it's December then we need the need to set the upperlimit to the next year
      if modMonth == 12 then
        startDateUpperLimit = os.date( '%Y-%m-%d' , os.time{year=year+1, month=1, day=day, hour=0} - 86400 )
      else
        startDateUpperLimit = os.date( '%Y-%m-%d' , os.time{year=year, month=modMonth+1, day=day, hour=0} - 86400 )
      end
      local subcontent = '<h1>' .. tostring(os.date( '%B %Y' , os.time{year=year, month=modMonth, day=day+1, hour=0}) .. '</h1>') .. getBannersForMonth(startDateLowerLimit, startDateUpperLimit)
      content = subcontent .. content

      -- Increment monthTracker
      monthTracker = monthTracker + 1
      
      -- Break from this loop after we did December because we need to increment year now 
      if monthTracker % 12 == 1 then break end
    end

    -- Increment year
    year = year + 1
  end

  -- Get the final month of banners up to the current date
  local startDateLowerLimit = os.date( '%Y-%m-%d', os.time{year=currYear, month=currMonth, day=day, hour=0} )
  local startDateUpperLimit = os.date( '%Y-%m-%d', os.time() )
  local subcontent = '<h1>' .. tostring(os.date( '%B %Y' ) ) .. '</h1>' .. getBannersForMonth(startDateLowerLimit, startDateUpperLimit)
  content = subcontent .. content

  return tostring(content)
end

-- Compares two summon focus banners by start date descending (More recent dates come first)
function dateCompare(a,b)
  return os.time({year=a[1].StartDate:match("^[^-]+"), month=a[1].StartDate:match("-([^-]+)-"), day=a[1].StartDate:match("[^-]+$"), hour=0}) > os.time({year=b[1].StartDate:match("^[^-]+"), month=b[1].StartDate:match("-([^-]+)-"), day=b[1].StartDate:match("[^-]+$"), hour=0})
end
    
function p.currentFocusList(frame)
  return p._currentFocusList()
end

function p.getCurrentFocusSlideshow(frame)
  return frame:extensionTag('gallery', p._getCurrentBannerSlideshowList(), { mode = 'slideshow', widths = '300px', heights = '300px' } )
end

function p.archiveFocusList(frame)
  return p._archiveFocusList()
end

return p