Module:Pokémon matchup

local p={}
local TableTools = require('Module:TableTools')

function get_matchup(type)
  local out={immune={},weak={},res={}}

  if type=="normal" then out.weak={"fighting"} out.immune={"ghost"} end

  if type=="fire" then out.weak={"water","ground","rock"} out.res={"fire","grass","ice","bug","steel","fairy"} end

  if type=="water" then out.weak={"grass","electric"} out.res={"fire","water","ice","steel"} end

  if type=="grass" then out.weak={"fire","ice","poison","flying","bug"} out.res={"water","grass","electric","ground"} end

  if type=="electric" then out.weak={"ground"} out.res={"electric","flying","steel"} end

  if type=="ice" then out.weak={"fire","fighting","rock","steel"} out.res={"ice"} end

  if type=="fighting" then out.weak={"flying","psychic","fairy"} out.res={"bug","rock","dark"} end

  if type=="poison" then out.weak={"ground","psychic"} out.res={"grass","fighting","poison","bug","fairy"} end

  if type=="ground" then out.weak={"water","grass","ice"} out.res={"poison","rock"} out.immune={"electric"} end

  if type=="flying" then out.weak={"electric","ice","rock"} out.res={"grass","fighting","bug"} out.immune={"ground"} end

  if type=="psychic" then out.weak={"bug","ghost","dark"} out.res={"fighting","psychic"} end

  if type=="bug" then out.weak={"fire","flying","rock"} out.res={"grass","fighting","ground"} end

  if type=="rock" then out.weak={"water","grass","fighting","ground","steel"} out.res={"normal","fire","poison","flying"} end

  if type=="ghost" then out.weak={"ghost","dark"} out.res={"poison","bug"} out.immune={"normal","fighting"} end

  if type=="dragon" then out.weak={"ice","dragon","fairy"} out.res={"fire","water","grass","electric"} end

  if type=="dark" then out.weak={"fighting","bug","fairy"} out.res={"ghost","dark"} out.immune={"psychic"} end

  if type=="steel" then out.weak={"fire","fighting","ground"} out.res={"normal","grass","ice","flying","psychic","bug","rock","dragon","steel","fairy"} out.immune={"poison"} end

  if type=="fairy" then out.weak={"poison","steel"} out.res={"fighting","bug","dark"} out.immune={"dragon"} end

  return out
end

function get_colored_type(frame,v)
  local c={
   normal="#676767",
   fire="#fa280c",
   water="#309eee",
   grass="#12ed24",
   electric="#ede412",
   ice="#98fff3",
   fighting="#b0340e",
   poison="#9d0ebb",
   ground="#8e5410",
   flying="#13bbd6",
   psychic="#ee0e6c",
   bug="#9fee12",
   rock="#f0b886",
   ghost="#4c3aca",
   dragon="#212290",
   dark="#31313c",
   steel="#878791",
   fairy="#e389f3"
  }
  return frame:expandTemplate{
   title="color",
   args={c[v],v}
  }
end

function p.matchup(frame)
  local dat=get_matchup(frame.args.type1)
  -- Get matchups and combine them:
  for _,v in pairs(get_matchup(frame.args.type2).weak) do
    dat.weak[TableTools.size(dat.weak)+1]=v
  end
  for _,v in pairs(get_matchup(frame.args.type2).res) do
    dat.res[TableTools.size(dat.res)+1]=v
  end
  for _,v in pairs(get_matchup(frame.args.type2).immune) do
    dat.immune[TableTools.size(dat.immune)+1]=v
  end

 -- remove duplicate immunities
  dat.immune=TableTools.removeDuplicates(dat.immune)

  --categories
  local cats=""
  if #frame.args.type1>0 and #frame.args.type2>0 and frame.args.namespace=="" then


    if frame.args.type1>frame.args.type2 then cats="[[Category:Book:Pokémon/"..frame:expandTemplate{
      title="UpperCase first",
      args={frame.args.type1}
    }.."-"..frame:expandTemplate{
      title="UpperCase first",
      args={frame.args.type2}
    }.." Pokémon]]"


    else cats="[[Category:Book:Pokémon/"..frame:expandTemplate{
      title="UpperCase first",
      args={frame.args.type2}
    }.."-"..frame:expandTemplate{
      title="UpperCase first",
      args={frame.args.type1}
    }.." Pokémon]]"
    end
  end

  -- Remove cancelled out matchups
  for k1,v1 in pairs(dat.res) do
    for k2,v2 in pairs(dat.weak) do
      if v1==v2 then
         -- Matchups match: remove both
        dat.weak[k2]="removed"
        dat.res[k1]="removed"
        break
      end
      for _,v3 in pairs(dat.immune) do
        if v2==v3 then
          dat.res[k2]="removed"
        end if v1==v3 then
          dat.weak[k1]="removed"
          break
        end
      end
    end
  end

  -- Get x4 and x.25 bonuses
  local sweak={}
  local sres={}
  -- x4
  for k,v in pairs(dat.weak) do for k2,v2 in pairs(dat.weak) do if not(k==k2) and v==v2 and not(v=="removed") then
    sweak[TableTools.size(sweak)+1]=v
    dat.weak[k]="removed" dat.weak[k2]="removed" break
  end end end
  -- x.25
  for k,v in pairs(dat.res) do for k2,v2 in pairs(dat.res) do if not(k==k2) and v==v2 and not(v=="removed") then
    sres[TableTools.size(sres)+1]=v
    dat.res[k]="removed" dat.res[k2]="removed" break
  end end end

  -- Get output

  -- Super weak
  local output=""
  if #sweak>0 then
    output="Moves that deal 400% of their damage to "..frame.args.pagename..": "
    for k,v in pairs(sweak) do
      if not(k==1) then output=output..", " end
      output=output..get_colored_type(frame,v)
  end end
  -- Weak
  output=output.."<br>Moves that deal 200% of their damage to "..frame.args.pagename..": "
  local index=1
  for k,v in pairs(dat.weak) do if not(v=="removed") then
    if not(index==1) then output=output..", " end
    output=output .. get_colored_type(frame,v)
    index=index+1
  end end
  -- Resistance
  index=1
  if #dat.res>0 then
    output=output.."<br>Moves that deal 50% of their damage to "..frame.args.pagename..": "
    for k,v in pairs(dat.res) do if not(v=="removed") then
      if not(index==1) then output=output..", " end
      output=output..get_colored_type(frame,v)
      index=index+1
    end end
  end
  -- Super resistance
  if #sres>0 then
    output=output.."<br>Moves that deal 25% of their damage to "..frame.args.pagename..": "
    for k,v in pairs(sres) do
      if not(k==1) then output=output..", " end
      output=output..get_colored_type(frame,v)
    end
  end
  -- Immune
  if #dat.immune>0 then
    output=output.."<br>Moves that deal 0% of their damage to "..frame.args.pagename..": "
    for k,v in pairs(dat.immune) do
      if not(k==1) then output=output..", " end
      output=output..get_colored_type(frame,v)
    end
  end
  return output .. cats .. "<br>"
end

return p