contract WorldCupPlayerToken is ERC721Token("WWWorld Cup", "WWWC"), Ownable {

  string constant public PLAYER_METADATA = "ipfs://ipfs/QmNgMeQT62pnUkkFcz4y59cQTmTZHBVFKmQ7Y7HQjh7tRw";
  uint256 constant DISTINCT_LEGENDARY_LIMIT = 1;
  uint256 constant DISTINCT_RARE_LIMIT = 2;
  uint256 constant DISTINCT_COMMON_LIMIT = 3;
  uint256 constant LEGENDARY_MAX_ID = 32;
  uint256 constant RARE_MAX_ID = 96;
  uint256 constant COMMON_MAX_ID = 736;
  mapping (uint256 => uint256) public playerCount;
  mapping (uint256 => uint256) internal tokenPlayerIds;

  /** @dev Enforces a scaricity of unique player cards by limiting.
    * @param playerId Player Id to enforce limit on.
    * @param limit Maximum number of tokens for that player id that can exist.
    */
  modifier enforcePlayerScarcity(uint256 playerId, uint256 limit) {
    require(playerCount[playerId] < limit, "Player limit reached.");
    _;
  }

  /** @dev Validates that the playerId is in the correct rarity range.
    * @param playerId Player Id to validate.
    * @param min Minimum playerId of range.
    * @param max Maximum playerId of range.
    */
  modifier validatePlayerIdRange(uint256 playerId, uint256 min, uint256 max) {
    require(playerId > min, "Player ID must be greater than the rarity minimum.");
    require(playerId <= max, "Player ID must be less than or equal to rarity maximum.");
    _;
  }

  /** @dev Creates a new token.
    * @param playerId Player Id to be created.
    */
  function _mintToken(uint256 playerId, string tokenURI, address owner) internal {
    
    // Mint new token:
    uint256 tokenId = allTokens.length + 1;
    super._mint(owner, tokenId);

    // Set metadata
    _setTokenURI(tokenId, tokenURI);
    _setPlayerId(tokenId, playerId);
  }

  /** @dev Internal function to set player Id for a given token.
    * @param tokenId Id of the token to set its playerId.
    * @param playerId Player Id to assign.
    */
  function _setPlayerId(uint256 tokenId, uint256 playerId) internal {
    require(exists(tokenId), "Token does not exist.");
    tokenPlayerIds[tokenId] = playerId;
  }

  /** @dev Returns player Id for a given token.
    * @param tokenId Id of the token to query player Id.
    * @return playerId for given token.
    */
  function playerId(uint256 tokenId) public view returns (uint256) {
    require(exists(tokenId), "Token does not exist.");
    return tokenPlayerIds[tokenId];
  }

}
function _setPlayerId(uint256 tokenId, uint256 playerId) internal {
  require(exists(tokenId), "Token does not exist.");
  tokenPlayerIds[tokenId] = playerId;
}

/** @dev Internal function to set player Id for a given token.
 * @param tokenId Id of the token to set its playerId.
 * @param playerId Player Id to assign.
 */