contract CSportsCore is CSportsMinting {

  /// @dev Used by other contracts as a sanity check
  bool public isCoreContract = true;

  // Set if (hopefully not) the core contract needs to be upgraded. Can be
  // set by the CEO but only when paused. When successfully set, we can never
  // unpause this contract. See the unpause() method overridden by this class.
  address public newContractAddress;

  /// @notice Class constructor creates the main CSportsCore smart contract instance.
  /// @param nftName The ERC721 name for the contract
  /// @param nftSymbol The ERC721 symbol for the contract
  /// @param nftTokenURI The ERC721 token uri for the contract
  constructor(string nftName, string nftSymbol, string nftTokenURI) public {

      // New contract starts paused.
      paused = true;

      /// @notice storage for the fields that identify this 721 token
      _name = nftName;
      _symbol = nftSymbol;
      _tokenURI = nftTokenURI;

      // All C-level roles are the message sender
      ceoAddress = msg.sender;
      cfoAddress = msg.sender;
      cooAddress = msg.sender;
      commissionerAddress = msg.sender;

  }

  /// @dev Reject all Ether except if it's from one of our approved sources
  function() external payable {
    /*require(
        msg.sender == address(saleClockAuctionContract)
    );*/
  }

  /// --------------------------------------------------------------------------- ///
  /// ----------------------------- PUBLIC FUNCTIONS ---------------------------- ///
  /// --------------------------------------------------------------------------- ///

  /// @dev Used to mark the smart contract as upgraded, in case there is a serious
  ///  bug. This method does nothing but keep track of the new contract and
  ///  emit a message indicating that the new address is set. It's up to clients of this
  ///  contract to update to the new contract address in that case. (This contract will
  ///  be paused indefinitely if such an upgrade takes place.)
  /// @param _v2Address new address
  function upgradeContract(address _v2Address) public onlyCEO whenPaused {
      newContractAddress = _v2Address;
      emit ContractUpgrade(_v2Address);
  }

  /// @dev Override unpause so it requires all external contract addresses
  ///  to be set before contract can be unpaused. Also require that we have
  ///  set a valid season and the contract has not been upgraded.
  function unpause() public onlyCEO whenPaused {
      require(leagueRosterContract != address(0));
      require(saleClockAuctionContract != address(0));
      require(newContractAddress == address(0));

      // Actually unpause the contract.
      super.unpause();
  }

  /// @dev Consolidates setting of contract links into a single call for deployment expediency
  function setLeagueRosterAndSaleAndTeamContractAddress(address _leagueAddress, address _saleAddress, address _teamAddress) public onlyCEO {
      setLeagueRosterContractAddress(_leagueAddress);
      setSaleAuctionContractAddress(_saleAddress);
      setTeamContractAddress(_teamAddress);
  }

  /// @dev Returns all the relevant information about a specific playerToken.
  ///@param _playerTokenID - player token ID we are seeking the full player token info for
  function getPlayerToken(uint32 _playerTokenID) public view returns (
      uint32 realWorldPlayerId,
      uint32 serialNumber,
      uint64 mintedTime,
      uint128 mostRecentPrice) {
    require(_playerTokenID < playerTokens.length);
    PlayerToken storage pt = playerTokens[_playerTokenID];
    realWorldPlayerId = pt.realWorldPlayerId;
    serialNumber = pt.serialNumber;
    mostRecentPrice = pt.mostRecentPrice;
    mintedTime = pt.mintedTime;
  }

  /// @dev Returns the realWorldPlayer MD5 ID for a given playerTokenID
  /// @param _playerTokenID - player token ID we are seeking the associated realWorldPlayer md5 for
  function realWorldPlayerTokenForPlayerTokenId(uint32 _playerTokenID) public view returns (uint128 md5Token) {
      require(_playerTokenID < playerTokens.length);
      PlayerToken storage pt = playerTokens[_playerTokenID];
      RealWorldPlayer memory _rwp;
      (_rwp.md5Token, _rwp.prevCommissionerSalePrice, _rwp.lastMintedTime, _rwp.mintedCount, _rwp.hasActiveCommissionerAuction, _rwp.mintingEnabled) = leagueRosterContract.realWorldPlayerFromIndex(pt.realWorldPlayerId);
      md5Token = _rwp.md5Token;
  }

  /// @dev Returns the realWorldPlayer Metadata for a given playerTokenID
  /// @param _playerTokenID - player token ID we are seeking the associated realWorldPlayer md5 for
  function realWorldPlayerMetadataForPlayerTokenId(uint32 _playerTokenID) public view returns (string metadata) {
      require(_playerTokenID < playerTokens.length);
      PlayerToken storage pt = playerTokens[_playerTokenID];
      RealWorldPlayer memory _rwp;
      (_rwp.md5Token, _rwp.prevCommissionerSalePrice, _rwp.lastMintedTime, _rwp.mintedCount, _rwp.hasActiveCommissionerAuction, _rwp.mintingEnabled) = leagueRosterContract.realWorldPlayerFromIndex(pt.realWorldPlayerId);
      metadata = leagueRosterContract.getMetadata(_rwp.md5Token);
  }

  /// --------------------------------------------------------------------------- ///
  /// ------------------------- RESTRICTED FUNCTIONS ---------------------------- ///
  /// --------------------------------------------------------------------------- ///

  /// @dev Updates a particular realRealWorldPlayer. Note that the md5Token is immutable. Can only be
  ///   called by the CEO and is used in development stage only as it is only needed by our test suite.
  /// @param _rosterIndex - Index into realWorldPlayers of the entry to change.
  /// @param _prevCommissionerSalePrice - Average of the 2 most recent sale prices in commissioner auctions
  /// @param _lastMintedTime - Time this real world player was last minted
  /// @param _mintedCount - The number of playerTokens that have been minted for this player
  /// @param _hasActiveCommissionerAuction - Whether or not there is an active commissioner auction for this player
  /// @param _mintingEnabled - Denotes whether or not we should mint new playerTokens for this real world player
  function updateRealWorldPlayer(uint32 _rosterIndex, uint128 _prevCommissionerSalePrice, uint64 _lastMintedTime, uint32 _mintedCount, bool _hasActiveCommissionerAuction, bool _mintingEnabled) public onlyCEO onlyUnderDevelopment {
    require(leagueRosterContract != address(0));
    leagueRosterContract.updateRealWorldPlayer(_rosterIndex, _prevCommissionerSalePrice, _lastMintedTime, _mintedCount, _hasActiveCommissionerAuction, _mintingEnabled);
  }

}
/// @notice This is the main contract that implements the csports ERC721 token.
/// @author CryptoSports, Inc. (http://cryptosports.team)
/// @dev This contract is made up of a series of parent classes so that we could
/// break the code down into meaningful amounts of related functions in
/// single files, as opposed to having one big file. The purpose of
/// each facet is given here:
///
///   CSportsConstants - This facet holds constants used throughout.
///   CSportsAuth -
///   CSportsBase -
///   CSportsOwnership -
///   CSportsAuction -
///   CSportsMinting -
///   CSportsCore - This is the main CSports constract implementing the CSports
///         Fantash Football League. It manages contract upgrades (if / when
///         they might occur), and has generally useful helper methods.
///
/// This CSportsCore contract interacts with the CSportsLeagueRoster contract
/// to determine which PlayerTokens to mint.
///
/// This CSportsCore contract interacts with the TimeAuction contract
/// to implement and run PlayerToken auctions (sales).
function upgradeContract(address _v2Address) public onlyCEO whenPaused {
      newContractAddress = _v2Address;
      emit ContractUpgrade(_v2Address);
  }
/// --------------------------------------------------------------------------- ///
/// ----------------------------- PUBLIC FUNCTIONS ---------------------------- ///
/// --------------------------------------------------------------------------- ///
/// @dev Used to mark the smart contract as upgraded, in case there is a serious
///  bug. This method does nothing but keep track of the new contract and
///  emit a message indicating that the new address is set. It's up to clients of this
///  contract to update to the new contract address in that case. (This contract will
///  be paused indefinitely if such an upgrade takes place.)
/// @param _v2Address new address