contract MonstroCitiesMounts is ERC721Enumerable, Ownable {  
  MONSTRO private monstro;

  uint constant public MAX_MOUNT_ADOPTION = 8000;
    uint constant public CURRENT_MINT = 2452;
        uint constant public MAX_MINT = 1;
  string public MonstroProvenance;
  bool public saleIsActive = false;
    bool public snapshot = false;
  uint256 public collectionStartingIndex;
  uint256 public collectionStartingIndexBlock;
  uint256 public maxMounts;
  uint256 public setBlockTimestamp;
  uint256 public revealTimestamp;
  string private baseURI;
   uint256 constant public PRICE = 0.01 ether;
  
  
uint256 public constant SNAPSHOT_TIME = 1630713600;

  constructor(
    string memory name,
    string memory symbol,
    uint256 maxNftSupply,
    uint256 saleStart,
    address dependentContractAddress
  ) ERC721(name, symbol) {
    maxMounts = maxNftSupply;
    revealTimestamp = saleStart + (86400 * 7);
    setBlockTimestamp = saleStart + (86400 * 6);
    monstro = MONSTRO(dependentContractAddress);
  }

  function setRevealTimestamp(uint256 revealTimeStamp) public onlyOwner {
    revealTimestamp = revealTimeStamp;
  }
  
      function getPrice() public view returns (uint256) {
       require(totalSupply() < MAX_MOUNT_ADOPTION, "Sale has already ended, no more Monsters left to sell.");
       
            return 10000000000000000;  //   0.01 ETH
 
    }
  

  function setStartingBlockTimestamp(uint256 startingBlockTimestamp) public onlyOwner {
    setBlockTimestamp = startingBlockTimestamp;
  }

  function setProvenanceHash(string memory provenanceHash) public onlyOwner {
    MonstroProvenance = provenanceHash;
  }

  function isMinted(uint256 tokenId) external view returns (bool) {
    require(tokenId < maxMounts, "tokenId outside collection bounds");

    return _exists(tokenId);
  }

  function _baseURI() internal view override returns (string memory) {
    return baseURI;
  }
  
  function setBaseURI(string memory uri) public onlyOwner {
    baseURI = uri;
  }

  function flipSaleState() public onlyOwner {
    saleIsActive = !saleIsActive;
  }
  
    function flipSnapshot() public onlyOwner {
    snapshot = !snapshot;
  }
  

  function trySetStartingIndexBlock() private {
    if (
      collectionStartingIndexBlock == 0 &&
      (totalSupply() == maxMounts || block.timestamp >= setBlockTimestamp)
    ) {
      collectionStartingIndexBlock = block.number;
    }
  }


  function mintMount(uint256 monstroTokenId) public {


    require(saleIsActive, "Sale must be active to mint a Mount");
    require(totalSupply() < maxMounts, "Purchase would exceed max supply of Mounts");
    require(monstroTokenId < CURRENT_MINT, "Requested tokenId exceeds upper bound");
    require(monstro.ownerOf(monstroTokenId) == msg.sender, "Must own the Monster for requested tokenId to mint a Mount");
    
    _safeMint(msg.sender, monstroTokenId);
    trySetStartingIndexBlock();
    }
  

  /**
    * Set the starting index for the collection
    */
  function setStartingIndex() public {
    require(collectionStartingIndex == 0, "Starting index is already set");
    require(collectionStartingIndexBlock != 0, "Starting index block must be set");
    require(
      block.timestamp >= revealTimestamp || totalSupply() == maxMounts, 
      "Must be on or after the reveal time to set starting index"
    );

    collectionStartingIndex = uint256(blockhash(collectionStartingIndexBlock)) % maxMounts;

    // Just a sanity case in the worst case if this function is called late (EVM only stores last 256 block hashes)
    if ((block.number - collectionStartingIndexBlock) > 255) {
      collectionStartingIndex = uint256(blockhash(block.number - 1)) % maxMounts;
    }

    // Prevent default sequence
    if (collectionStartingIndex == 0) {
      collectionStartingIndex = collectionStartingIndex + 1;
    }
  }

  /**
    * Set the starting index block for the collection, essentially unblocking
    * setting starting index
    */
  function emergencySetStartingIndexBlock() public onlyOwner {
    require(collectionStartingIndexBlock == 0, "Starting index block is already set");
    require(collectionStartingIndex == 0, "Starting index is already set");

    collectionStartingIndexBlock = block.number;
  }
}
function setStartingIndex() public {
  require(collectionStartingIndex == 0, "Starting index is already set");
  require(collectionStartingIndexBlock != 0, "Starting index block must be set");
  require(
    block.timestamp >= revealTimestamp || totalSupply() == maxMounts, 
    "Must be on or after the reveal time to set starting index"
  );

  collectionStartingIndex = uint256(blockhash(collectionStartingIndexBlock)) % maxMounts;

  // Just a sanity case in the worst case if this function is called late (EVM only stores last 256 block hashes)
  if ((block.number - collectionStartingIndexBlock) > 255) {
    collectionStartingIndex = uint256(blockhash(block.number - 1)) % maxMounts;
  }

  // Prevent default sequence
  if (collectionStartingIndex == 0) {
    collectionStartingIndex = collectionStartingIndex + 1;
  }
}

/**
 * Set the starting index for the collection
 */