contract JABBAFORMS is ERC721, Ownable {
    using SafeMath for uint256;
    uint public constant MAX_JABBAS = 4849;
    bool public hasSaleStarted = false;
    
    // THE IPFS HASH OF ALL TOKEN DATAS WILL BE ADDED HERE WHEN ALL JABBA FORMS ARE FINALIZED.
    string public METADATA_PROVENANCE_HASH = "";
    
    
    constructor() ERC721("J48BAFORMS","JABBA")  {
        setBaseURI("https://j48baforms.io/api/");
        
		//Givaways
        _safeMint(address(0x79004C1a3aCe472d75358ceCeB1d7E47Ef98BF10), 0);
        _safeMint(address(0x79004C1a3aCe472d75358ceCeB1d7E47Ef98BF10), 1);
        _safeMint(address(0x79004C1a3aCe472d75358ceCeB1d7E47Ef98BF10), 2);
        _safeMint(address(0x79004C1a3aCe472d75358ceCeB1d7E47Ef98BF10), 3);
		_safeMint(address(0x79004C1a3aCe472d75358ceCeB1d7E47Ef98BF10), 4);
		_safeMint(address(0x79004C1a3aCe472d75358ceCeB1d7E47Ef98BF10), 5);
		_safeMint(address(0x79004C1a3aCe472d75358ceCeB1d7E47Ef98BF10), 6);
		_safeMint(address(0x79004C1a3aCe472d75358ceCeB1d7E47Ef98BF10), 7);
		_safeMint(address(0x79004C1a3aCe472d75358ceCeB1d7E47Ef98BF10), 8);
		_safeMint(address(0x79004C1a3aCe472d75358ceCeB1d7E47Ef98BF10), 9);
		_safeMint(address(0x79004C1a3aCe472d75358ceCeB1d7E47Ef98BF10), 10);
		_safeMint(address(0x79004C1a3aCe472d75358ceCeB1d7E47Ef98BF10), 11);
		_safeMint(address(0x79004C1a3aCe472d75358ceCeB1d7E47Ef98BF10), 12);
		_safeMint(address(0x79004C1a3aCe472d75358ceCeB1d7E47Ef98BF10), 13);
		_safeMint(address(0x79004C1a3aCe472d75358ceCeB1d7E47Ef98BF10), 14);
		_safeMint(address(0x79004C1a3aCe472d75358ceCeB1d7E47Ef98BF10), 15);
		_safeMint(address(0x79004C1a3aCe472d75358ceCeB1d7E47Ef98BF10), 16);
		_safeMint(address(0x79004C1a3aCe472d75358ceCeB1d7E47Ef98BF10), 17);
		_safeMint(address(0x79004C1a3aCe472d75358ceCeB1d7E47Ef98BF10), 18);
		_safeMint(address(0x79004C1a3aCe472d75358ceCeB1d7E47Ef98BF10), 19);

		//sudoscum
		_safeMint(address(0xaA9f066554e18d3a6b660786aaFEA8e9a8630555), 20);
		_safeMint(address(0xaA9f066554e18d3a6b660786aaFEA8e9a8630555), 21);
		_safeMint(address(0xaA9f066554e18d3a6b660786aaFEA8e9a8630555), 22);
		_safeMint(address(0xaA9f066554e18d3a6b660786aaFEA8e9a8630555), 23);
		_safeMint(address(0xaA9f066554e18d3a6b660786aaFEA8e9a8630555), 24);
		
		//PM
		_safeMint(address(0x8af39F909679793D2FA5A78e2766E6EF131ECDE2), 25);
		_safeMint(address(0x8af39F909679793D2FA5A78e2766E6EF131ECDE2), 26);
		_safeMint(address(0x8af39F909679793D2FA5A78e2766E6EF131ECDE2), 27);
		
		//BERK
		_safeMint(address(0xc5E08104c19DAfd00Fe40737490Da9552Db5bfE5), 28);
		
		//Justin
		_safeMint(address(0x84F5DE49Bf77dEC3D6b6D69dc05fa80207262D5A), 29);
		_safeMint(address(0x84F5DE49Bf77dEC3D6b6D69dc05fa80207262D5A), 30);
        
    }
    

    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_JABBAS, "Sale has already ended");

        uint currentSupply = totalSupply();
        require(currentSupply < MAX_JABBAS, "Sale has already ended");

        if (currentSupply <= 500) {
            return 80000000000000000; // 0.08 ETH
        } else if (currentSupply <= 1600) {
            return 140000000000000000; // 0.14 ETH
        } else if (currentSupply <= 2648) {
            return 250000000000000000; // 0.25 ETH
        } else if (currentSupply <= 3648) {
            return 330000000000000000; // 0.33 ETH
        } else if (currentSupply <= 4148) {
            return 400000000000000000; // 0.4 ETH
        } else if (currentSupply <= 4648) {
            return 500000000000000000; // 0.5 ETH
        } else if (currentSupply <= 4847) {
            return 600000000000000000; // 0.6 ETH
        } else {
            return 1000000000000000000; // 1 ETH
        }
        
    }

     function calculatePriceTest(uint _id) public view returns (uint256) {


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

        if (_id <= 500) {
            return 80000000000000000; // 0.08 ETH
        } else if (_id <= 1600) {
            return 140000000000000000; // 0.14 ETH
        } else if (_id <= 2648) {
            return 250000000000000000; // 0.25 ETH
        } else if (_id <= 3648) {
            return 330000000000000000; // 0.33 ETH
        } else if (_id <= 4148) {
            return 400000000000000000; // 0.4 ETH
        } else if (_id <= 4648) {
            return 500000000000000000; // 0.5 ETH
        } else if (_id <= 4847) {
            return 600000000000000000; // 0.6 ETH
        } else {
            return 1000000000000000000; // 1 ETH
        }
        
    }
    
   function adoptJABBA(uint256 numJabbas) public payable {
        require(totalSupply() < MAX_JABBAS, "Sale has already ended");
        require(numJabbas > 0 && numJabbas <= 20, "You can adopt minimum 1, maximum 20 jabba forms");
        require(totalSupply().add(numJabbas) <= MAX_JABBAS, "Exceeds MAX_JABBAS");
        require(msg.value >= calculatePrice().mul(numJabbas), "Ether value sent is below the price");

        for (uint i = 0; i < numJabbas; 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