#
# CONSTANTS
# =========

TORRENT_VERSION=1;

#
# VARIABLES
# =========

# Deck name mapping.
deck_name=(,);
deck_name{"deck"}="library";
deck_name{"discard pile"}="graveyard";
deck_name{"sideboard"}="sideboard";
deck_name{"exile"}="exile";
deck_name{"command"}="command zone";
deck_name{"planes"}="planar deck";
deck_name{"schemes"}="scheme deck";
deck_name{"opponent deck"}="library";
deck_name{"opponent discard pile"}="graveyard";
deck_name{"opponent sideboard"}="sideboard";
deck_name{"opponent exile"}="exile";
deck_name{"opponent command"}="command zone";
deck_name{"opponent planes"}="planar deck";
deck_name{"opponent schemes"}="scheme deck";

#
# RuleCountBiggestPopulation(list of card numbers) - Count the biggest number of creatures having the same type.
#
def RuleCountBiggestPopulation
{
  push(t);
  push(e);
  t=select('find("Creature",Attr("type",#))!=NULL',ARG);
  t=forall('Attr("subtype",#)',t)-("",);
  t=flatten(forall('split(#," ")',t));
  deck_rulecheck.info="found: "+join(forall('count(#,t)+" x "+#',unique(sort(t))),", ");
  return(max(forall('count(#,t)',unique(sort(t)))));
  e=pop();
  t=pop();
}

#
# RuleCountColors(list of card numbers) - Return the list of total numbers of each color (black,blue,green,red,white).
#
def RuleCountColors
{
  push(t);
  t=forall('Attr("color",#)',ARG);
  return(count("Black",t),count("Blue",t),count("Green",t),count("Red",t),count("White",t));
  t=pop();  
}

#
# TribalLegal(card number) - Return 1 if card is a tribal legal creature.
#
def TribalLegal
{
  if(find("Creature",Attr("type",ARG))==NULL)
    return(0);
  else
  {
    if(!isdict(TRIBAL_COUNT))
    {
      TRIBAL_COUNT=(,);
  
      for(t)(flatten(forall("split(#,' ')",Attr('subtype',cards())-("",))))
      {
          if(!has_entry(t,TRIBAL_COUNT))
            TRIBAL_COUNT{t}=1;
          else
            TRIBAL_COUNT{t}=TRIBAL_COUNT{t}+1;
      }
  
      TRIBAL_COUNT{""}=0;
    }

    return(max(forall("TRIBAL_COUNT{#}",split(Attr('subtype',ARG)," ")))>=5);
  }
}

#
# CreateTypeLegalTable(type) - Fill table TYPE_LEGAL, if not already filled.
#
def CreateTypeLegalTable
{
  lasttype=ARG;
  if(!isdict(TYPE_LEGAL))
    TYPE_LEGAL=(,);
  if(!has_entry(ARG,TYPE_LEGAL))
  {
    push(r);
    push(s);
    push(d);
    TYPE_LEGAL{ARG}=copy(-1,last(cards())+1);
    genlimit = 0;
    d=(,);
    for(r)(keys(deck_rules{ARG}))
      if(r=="" || find("deck",r) != NULL)
        d=d+deck_rules{ARG}{r};
    for(r)(d)
    {
      if(r[0]=="RuleCardSet" || r[0]=="RuleCardSetReprint")
      {
        s=set_data(r[1][0]);
        for(c)(seq(s[1],s[2]))
          TYPE_LEGAL{ARG}[c]=r[1][1];
      }
      if(r[0]=="RuleCardSets" || r[0]=="RuleAllowedSetsReprint")
      {
        s=(,);
  
        for(c)(head(r[1]))
        {
          s=s+seq(tail(set_data(c)));
        }
        
        for(c)(s)
          TYPE_LEGAL{ARG}[c]=last(r[1]);
      }
      else if(r[0]=="RuleCardLimitSingle")
      {
        for(c)(images(r[1][0]))
          TYPE_LEGAL{ARG}[c]=r[1][1];
      }
      else if(r[0]=="RuleCardLimitEach")
      {
        for(c)(flatten(images(head(r[1]))))
          TYPE_LEGAL{ARG}[c]=last(r[1]);
      }
      else if(r[0]=="RuleCardLimitAny")
      {
        for(c)(images(r[1]))
          TYPE_LEGAL{ARG}[c]=999;
      }
      else if(r[0]=="RuleLimitEachByExpression")
# || (r[0]=="RuleLimitByExpression" && r[1][0] < 2))
      {
        for(c)(select(r[1][1],cards()))
          TYPE_LEGAL{ARG}[c]=r[1][0];
      }
      else if(r[0]=="RuleCardLimitGeneral")
      {
        genlimit = r[1];
      }
    }
    if(genlimit)
    {
      for(c)(cards())
      {
        if(TYPE_LEGAL{ARG}[c] < 0)
          TYPE_LEGAL{ARG}[c]=genlimit;
      }
    }
    d=pop();
    s=pop();
    r=pop();
  }
}

#
# TypeLegal(rule set,card number) - Return 1 if a card is a legal in the type.
#
def TypeLegal
{
  if(lasttype != ARG[0]) CreateTypeLegalTable(ARG[0]);
  return(TYPE_LEGAL{ARG[0]}[ARG[1]] > 0);
}

#
# TypeRestricted(rule set,card number) - Return 1 if a card is limited to one in the type.
#
def TypeRestricted
{
  if(lasttype != ARG[0]) CreateTypeLegalTable(ARG[0]);
  return(TYPE_LEGAL{ARG[0]}[ARG[1]]==1);
}
