contract Zooethereum is INFT, ERC721Tradable {

	uint public lastTokenId;
	
	string public contractURI;
	string internal _baseTokenURI;

	mapping(address => bool) public operators;

	mapping(string => uint) public tokenTypeAmount;
	mapping(string => uint) public tokenTypeMinted;
	mapping(string => uint) public tokenTypePrice;

	constructor(
		address _proxyRegistryAddress,
		string memory _name,
		string memory _symbol,
		string memory _contractURI,
		string memory __baseTokenURI,
		address[] memory _operators
	) ERC721Tradable(_name, _symbol, _proxyRegistryAddress)
	{
		contractURI = _contractURI;
		_baseTokenURI = __baseTokenURI;

		tokenTypeAmount["arctic"] = 250;
		tokenTypeAmount["robotic"] = 200;
		tokenTypeAmount["cemetery"] = 150;
		tokenTypeAmount["oriental"] = 100;
		tokenTypeAmount["island"] = 90;
		tokenTypeAmount["mayan"] = 45;
		tokenTypeAmount["galactic"] = 30;
		tokenTypeAmount["ocean"] = 20;
		tokenTypeAmount["egyptian"] = 15;
		
		lastTokenId = 900;

		tokenTypePrice["arctic"] = 0.2 ether;
		tokenTypePrice["robotic"] = 0.3 ether;
		tokenTypePrice["cemetery"] = 0.4 ether;
		tokenTypePrice["oriental"] = 0.5 ether;
		tokenTypePrice["island"] = 0.6 ether;
		tokenTypePrice["mayan"] = 0.7 ether;
		tokenTypePrice["galactic"] = 0.8 ether;
		tokenTypePrice["ocean"] = 0.9 ether;
		tokenTypePrice["egyptian"] = 1 ether;

		for(uint i = 0; i < _operators.length; i++) {
			operators[_operators[i]] = true;
		}
	}

	// Public read-only methods
	
	function baseTokenURI() public view override returns(string memory) {
	    	// write base URI here
	    	// e.g. https://api.lympo.io/pools/assets/62 - without token index
        	return _baseTokenURI;
	}
	
	function _baseURI() internal view override returns(string memory) {
	    	// write base URI here
	    	// e.g. https://api.lympo.io/pools/assets/62 - without token index
        	return _baseTokenURI;
    	}

	function tokenTypeAndPrice(uint _tokenId) public pure override returns (string memory _tokenType, uint _price) {
		uint sum = 0;
		
		if (_tokenId > sum && _tokenId <= sum + 250) {
			_tokenType = "arctic";
			return (_tokenType, 0.2 ether);
		} else {
			sum += 250;
		}
		
		if (_tokenId > sum && _tokenId <= sum + 200) {
			_tokenType = "robotic";
			return (_tokenType, 0.3 ether);
		} else {
			sum += 200;
		}
		
		if (_tokenId > sum && _tokenId <= sum + 150) {
			_tokenType = "cemetery";
			return (_tokenType, 0.4 ether);
		} else {
			sum += 150;
		}
		
		if (_tokenId > sum && _tokenId <= sum + 100) {
			_tokenType = "oriental";
			return (_tokenType, 0.5 ether);
		} else {
			sum += 100;
		}
		
		if (_tokenId > sum && _tokenId <= sum + 90) {
			_tokenType = "island";
			return (_tokenType, 0.6 ether);
		} else {
			sum += 90;
		}
		
		if (_tokenId > sum && _tokenId <= sum + 45) {
			_tokenType = "mayan";
			return (_tokenType, 0.7 ether);
		} else {
			sum += 45;
		}
		
		if (_tokenId > sum && _tokenId <= sum + 30) {
			_tokenType = "galactic";
			return (_tokenType, 0.8 ether);
		} else {
			sum += 30;
		}
		
		if (_tokenId > sum && _tokenId <= sum + 20) {
			_tokenType = "ocean";
			return (_tokenType, 0.9 ether);
		} else {
			sum += 20;
		}
		
		if (_tokenId > sum && _tokenId <= sum + 15) {
			_tokenType = "egyptian";
			return (_tokenType, 1 ether);
		} else {
			revert("token does not exist");
		}
	}

	// onlyOwner methods

    function updateBaseURI(string memory __baseURI) public onlyOwner {
    	_baseTokenURI = __baseURI;
    }

	function updateOperator(address _operatorAddress, bool _status) public onlyOwner {
		operators[_operatorAddress] = _status;
	}

	function mintTo(address _to) public override onlyOwner {
		_safeMint(_to, 1);
        tokenTypeMinted["arctic"]++;
	}

	// Mint method
	
	function mint(address _to, uint _tokenId) public override {
		require(_tokenId > 0 && _tokenId <= lastTokenId, "token does not exist");
		require(operators[msg.sender], "only operators");
		_safeMint(_to, _tokenId);
		(string memory tokenType, ) = tokenTypeAndPrice(_tokenId);
		tokenTypeMinted[tokenType]++;
	}
}
function baseTokenURI() public view override returns(string memory) {
    	// write base URI here
    	// e.g. https://api.lympo.io/pools/assets/62 - without token index
       	return _baseTokenURI;
}

// Public read-only methods