contract BGANPUNKSV2 is ERC721, Ownable {
    using SafeMath for uint256;
    uint public constant MAX_BASTARDS = 11305;
    bool public hasSaleStarted = false;
    
    // THE IPFS HASH OF ALL TOKEN DATAS WILL BE ADDED HERE WHEN ALL BASTARDS ARE FINALIZED.
    string public METADATA_PROVENANCE_HASH = "";
    
    
    constructor() ERC721("BASTARD GAN PUNKS V2","BGANPUNKV2")  {
        setBaseURI("https://bastardganpunks.club/api/");
        
        // TO BERK
        _safeMint(address(0xc5E08104c19DAfd00Fe40737490Da9552Db5bfE5), 0);
        _safeMint(address(0xc5E08104c19DAfd00Fe40737490Da9552Db5bfE5), 1);
        _safeMint(address(0xc5E08104c19DAfd00Fe40737490Da9552Db5bfE5), 2);
        _safeMint(address(0xc5E08104c19DAfd00Fe40737490Da9552Db5bfE5), 3);
        _safeMint(address(0xc5E08104c19DAfd00Fe40737490Da9552Db5bfE5), 4);
        _safeMint(address(0xc5E08104c19DAfd00Fe40737490Da9552Db5bfE5), 5);
        _safeMint(address(0xc5E08104c19DAfd00Fe40737490Da9552Db5bfE5), 6);
        _safeMint(address(0xc5E08104c19DAfd00Fe40737490Da9552Db5bfE5), 7);
        _safeMint(address(0xc5E08104c19DAfd00Fe40737490Da9552Db5bfE5), 8);
        _safeMint(address(0xc5E08104c19DAfd00Fe40737490Da9552Db5bfE5), 9);
        _safeMint(address(0xc5E08104c19DAfd00Fe40737490Da9552Db5bfE5), 10);
        _safeMint(address(0xc5E08104c19DAfd00Fe40737490Da9552Db5bfE5), 11);
        _safeMint(address(0xc5E08104c19DAfd00Fe40737490Da9552Db5bfE5), 12);
        _safeMint(address(0xc5E08104c19DAfd00Fe40737490Da9552Db5bfE5), 13);
        
        // CANER
        _safeMint(address(0xc5E5ec38de39c632f67EbF9795CD1d7D12331799), 14);
        _safeMint(address(0xc5E5ec38de39c632f67EbF9795CD1d7D12331799), 15);
        _safeMint(address(0xc5E5ec38de39c632f67EbF9795CD1d7D12331799), 16);
        
        // GOKHAN
        _safeMint(address(0x36de990133D36d7E3DF9a820aA3eDE5a2320De71), 17);
        _safeMint(address(0x36de990133D36d7E3DF9a820aA3eDE5a2320De71), 18);
        
        // HALE
        _safeMint(address(0x58615313079FdD02eb240a11fbBFf1dadb00007e), 19);
        
        // SEDA
        _safeMint(address(0xfCAD2eB79692c2Aa0BCBaf3D3E29615dDa94FE6d), 20);
        _safeMint(address(0xfCAD2eB79692c2Aa0BCBaf3D3E29615dDa94FE6d), 21);
        _safeMint(address(0xfCAD2eB79692c2Aa0BCBaf3D3E29615dDa94FE6d), 22);
        
        // SAJIDA
        _safeMint(address(0x61C4a38D7e9ea4095FA7D507CF72Bf61eb5e1556), 23);
        _safeMint(address(0x61C4a38D7e9ea4095FA7D507CF72Bf61eb5e1556), 24);
        _safeMint(address(0x61C4a38D7e9ea4095FA7D507CF72Bf61eb5e1556), 25);
        
        // SAMET
        _safeMint(address(0xd956c14c8016c55344B3429ccDF2cDf9cc4362DD), 26);
        _safeMint(address(0xd956c14c8016c55344B3429ccDF2cDf9cc4362DD), 27);
        
        // ISIK
        _safeMint(address(0xc5E08104c19DAfd00Fe40737490Da9552Db5bfE5), 28);
        _safeMint(address(0xc5E08104c19DAfd00Fe40737490Da9552Db5bfE5), 29);
        _safeMint(address(0xc5E08104c19DAfd00Fe40737490Da9552Db5bfE5), 30);
        
        // GIVEAWAY
        _safeMint(address(0xc5E08104c19DAfd00Fe40737490Da9552Db5bfE5), 31);
        _safeMint(address(0xc5E08104c19DAfd00Fe40737490Da9552Db5bfE5), 32);
        _safeMint(address(0xc5E08104c19DAfd00Fe40737490Da9552Db5bfE5), 33);
    }
    

   
    

    
    function tokensOfOwner(address _owner) external view returns(uint256[] memory ) {
        uint256 tokenCount = balanceOf(_owner);
        if (tokenCount == 0) {
            // Return an empty array
            return new uint256[](0);
        } else {
            uint256[] memory result = new uint256[](tokenCount);
            uint256 index;
            for (index = 0; index < tokenCount; index++) {
                result[index] = tokenOfOwnerByIndex(_owner, index);
            }
            return result;
        }
    }
    
    function calculatePrice() public view returns (uint256) {
        require(hasSaleStarted == true, "Sale hasn't started");

        require(totalSupply() < MAX_BASTARDS, "Sale has already ended");

        uint currentSupply = totalSupply();
        if (currentSupply == 11304) {
            return 10000000000000000000;
        } else if (currentSupply >= 11300) {
            return 3000000000000000000;
        } else if (currentSupply >= 11000) {
            return 854000000000000000 + (((currentSupply - 11000) / 50) * ((10 ** 16)));
        } else if (currentSupply >= 10000) {
            return 769000000000000000 + (((currentSupply - 10000) / 100) * ((10 ** 14) * 85));
        } else if (currentSupply >= 5000) {
            return 394000000000000000 + (((currentSupply - 5000) / 100) * ((10 ** 14) * 75));
        } else {
            return 69000000000000000 + ((currentSupply / 100) * ((10 ** 14) * 65));
        }
        
    }
    
     function calculatePriceTest(uint _id) public view returns (uint256) {


        require(_id < MAX_BASTARDS, "Sale has already ended");

        if (_id == 11304) {
            return 10000000000000000000;
        } else if (_id >= 11300) {
            return 3000000000000000000;
        } else if (_id >= 11000) {
            return 854000000000000000 + (((_id - 11000) / 50) * ((10 ** 16)));
        } else if (_id >= 10000) {
            return 769000000000000000 + (((_id - 10000) / 100) * ((10 ** 14) * 85));
        } else if (_id >= 5000) {
            return 394000000000000000 + (((_id - 5000) / 100) * ((10 ** 14) * 75));
        } else {
            return 69000000000000000 + ((_id / 100) * ((10 ** 14) * 65));
        }
        
    }
    
   function adoptBASTARD(uint256 numBastards) public payable {
        require(totalSupply() < MAX_BASTARDS, "Sale has already ended");
        require(numBastards > 0 && numBastards <= 20, "You can adopt minimum 1, maximum 20 bastards");
        require(totalSupply().add(numBastards) <= MAX_BASTARDS, "Exceeds MAX_BASTARDS");
        require(msg.value >= calculatePrice().mul(numBastards), "Ether value sent is below the price");

        for (uint i = 0; i < numBastards; i++) {
            uint mintIndex = totalSupply();
            _safeMint(msg.sender, mintIndex);
        }

    }
    
    // ONLYOWNER FUNCTIONS
    
    function setProvenanceHash(string memory _hash) public onlyOwner {
        METADATA_PROVENANCE_HASH = _hash;
    }
    
    function setBaseURI(string memory baseURI) public onlyOwner {
        _setBaseURI(baseURI);
    }
    
    function startDrop() public onlyOwner {
        hasSaleStarted = true;
    }
    function pauseDrop() public onlyOwner {
        hasSaleStarted = false;
    }
    
    
    function withdrawAll() public payable onlyOwner {
        require(payable(msg.sender).send(address(this).balance));
    }
    


}
function setProvenanceHash(string memory _hash) public onlyOwner {
        METADATA_PROVENANCE_HASH = _hash;
    }
// ONLYOWNER FUNCTIONS