// Contract: RolePlusLoot
// Target function: function encode(bytes memory data) internal pure returns (string memory)
-1.87h-.64a1.07,1.07,0,0,1,0-2.14h.64A1.88,1.88,0,0,0,24.2,13.4V12.2a1.07,1.07,0,0,1,1.06-1.06V7.49a1.05,1.05,0,0,0-.76.32L22,10.28a7.33,7.33,0,0,1-5.23,2.16,1.08,1.08,0,0,0-1.08,1.09V22a9.54,9.54,0,0,0,9.54,9.54V27.85Z"/><rect class="cls-6" y="265" width="18" height="42"/><line class="cls-7" x1="18" y1="265.5" x2="95.5" y2="265.5"/><line class="cls-7" x1="18" y1="306.5" x2="181.5" y2="306.5"/><g><rect class="cls-8" x="248" y="251" width="91" height="17"/></g><g><rect class="cls-8" x="248" y="270" width="91" height="17"/></g><g><rect class="cls-8" x="248" y="289" width="91" height="17"/></g><g><rect class="cls-8" x="248" y="308" width="91" height="17"/></g><g><rect class="cls-8" x="248" y="327" width="91" height="17"/></g><g><rect class="cls-8" x="11" y="152" width="88" height="17"/></g><g><rect class="cls-8" x="11" y="174" width="88" height="17"/></g><g><rect class="cls-8" x="11" y="196" width="88" height="17"/></g><g><rect class="cls-8" x="11" y="218" width="88" height="17"/></g><g><rect class="cls-8" x="11" y="240" width="88" height="17"/></g><rect class="cls-8" x="248" y="12" width="91" height="20"/><rect class="cls-8" x="248" y="36" width="91" height="20"/><rect class="cls-8" x="248" y="60" width="91" height="20"/><rect class="cls-8" x="248" y="84" width="91" height="20"/><rect class="cls-8" x="248" y="108" width="91" height="20"/><rect class="cls-8" x="248" y="132" width="91" height="20"/><rect class="cls-8" x="248" y="156" width="91" height="20"/><rect class="cls-8" x="248" y="180" width="91" height="20"/><path class="cls-5" d="M12.11,36.17l.5,64.53h-1l-.51-64.56Zm.49,63.45.32,42.16-1,0-.33-42.18Z"/><path class="cls-9" d="M292.12,227.66l40.42-.3,0,1-40.45.3Z"/></g></g><text class="cls-10" transform="translate(15.94 164.08)">';
        p[3] = Role(roleAddr).getAlignment(roleId);
        p[4] = '</text><text class="cls-10" transform="translate(254.2 24.56)">';
        p[5] = Loot(_lootAddr).getChest(lootId);
        p[6] = '</text><text class="cls-10" transform="translate(254.2 48.5)">';
        p[7] = Loot(_lootAddr).getFoot(lootId);
        p[8] = '</text><text class="cls-10" transform="translate(254.2 72.28)">';
        p[9] = Loot(_lootAddr).getHand(lootId);
        p[10] = '</text><text class="cls-10" transform="translate(254.2 97.22)">';
        p[11] = Loot(_lootAddr).getHead(lootId);
        p[12] = '</text><text class="cls-10" transform="translate(254.2 120.67)">';
        p[13] = Loot(_lootAddr).getNeck(lootId);
        p[14] = '</text><text class="cls-10" transform="translate(254.2 144.72)">';
        p[15] = Loot(_lootAddr).getRing(lootId);
        p[16] = '</text><text class="cls-10" transform="translate(254.2 169)">';
        p[17] = Loot(_lootAddr).getWaist(lootId);
		p[18] = '</text><text class="cls-10" transform="translate(254.2 193.05)">';
        p[19] = Loot(_lootAddr).getWeapon(lootId);
        p[20] = '</text><text class="cls-10" transform="translate(254.2 263.46)">';
        p[21] = Pets(petsAddr).getAlignment(tokenId);
        p[22] = '</text><text class="cls-10" transform="translate(254.2 281.13)">';
        p[23] = Pets(petsAddr).getSpecies(tokenId);
        p[24] = '</text><text class="cls-10" transform="translate(254.2 300.61)">';
        p[25] = Pets(petsAddr).getTrait(tokenId, 1);
        p[26] = '</text><text class="cls-10" transform="translate(254.2 319.26)">';
        p[27] = Pets(petsAddr).getTrait(tokenId, 2);
        p[28] = '</text><text class="cls-10" transform="translate(254.2 339.08)">';
        p[29] = Pets(petsAddr).getTrait(tokenId, 3);
        p[30] = '</text><text class="cls-10" transform="translate(15.94 185.66)">';
        p[31] = Role(roleAddr).getOccupation(roleId);
        p[32] = '</text><text class="cls-10" transform="translate(15.94 207.7)">';
        p[33] = Role(roleAddr).getTrait1(roleId);
        p[34] = '</text><text class="cls-10" transform="translate(15.94 229.94)">';
        p[35] = Role(roleAddr).getTrait2(roleId);
        p[36] = '</text><text class="cls-10" transform="translate(15.94 251.62)">';
        p[37] = Role(roleAddr).getTrait3(roleId);
        p[38] = '</text><text class="cls-11" transform="translate(136.13 303.28)">';
        p[39] = toString(roleId);
        p[40] = '</text><text class="cls-12" transform="translate(21.56 304.54)">Role</text><text class="cls-13" transform="translate(19.68 100.41) rotate(90)">';
        p[41] = toString(lootId);
        p[42] = '</text><text class="cls-14" transform="translate(19.32 35.87) rotate(90)">Loot</text><text class="cls-15" transform="translate(293.48 238.74)">';
        p[43] = toString(tokenId);
        p[44] = '</text><text class="cls-16" transform="translate(288.63 223.13)">Pet</text></svg>';

        string memory output = string(abi.encodePacked(p[0], p[1], p[2], p[3], p[4], p[5], p[6], p[7], p[8]));
        output = string(abi.encodePacked(output, p[9], p[10], p[11], p[12], p[13], p[14], p[15], p[16]));
        output = string(abi.encodePacked(output, p[17], p[18], p[19], p[20], p[21], p[22], p[23], p[24]));
        output = string(abi.encodePacked(output, p[25], p[26], p[27], p[28], p[29], p[30], p[31], p[32]));
        output = string(abi.encodePacked(output, p[33], p[34], p[35], p[36], p[37], p[38], p[39], p[40]));
        output = string(abi.encodePacked(output, p[41], p[42], p[43], p[44]));

        string memory atrrOutput = makeAttributeParts(lootId, roleId, tokenId);
        string memory json = Base64.encode(bytes(string(abi.encodePacked('{"name": "Role+Loot #', toString(tokenId), '", "description": "Combine Loot/mLoot, Role and Pet. Get Role+, the key to the New World.", "image": "data:image/svg+xml;base64,', Base64.encode(bytes(output)), '"', ',"attributes":', atrrOutput, '}'))));
        output = string(abi.encodePacked('data:application/json;base64,', json));
        return output;
    }
	
	function getUrl(uint tokenId, uint roleId) public view returns(string memory){
        string memory prefix = "https://ipfs.io/ipfs/QmSLhQXyNgNL6JCq1Vvy3Dhun9Ewar2fr7tfMNtwKX2qzh/";
        string memory suffix = ".svg";
        
        if(!stringCompare(tokenData[tokenId].url, "")){
            return tokenData[tokenId].url;
        }
        
        string memory race = Role(roleAddr).getRace(roleId);
        string memory gender = Role(roleAddr).getGender(roleId);
        
        string memory raceId;
        if(stringCompare(race, "Human")){
            raceId = "0";
        }else if(stringCompare(race, "Elf")){
            raceId = "1";
        }else if(stringCompare(race, "Orc")){
            raceId = "2";
        }else if(stringCompare(race, "Undead")){
            raceId = "3";
        }else if(stringCompare(race, "Demons")){
            raceId = "4";
        }else{
            raceId = "5";
        }
        
        string memory genderId;
        if(stringCompare(gender, "Female")){
            genderId = "1";
        }
        
        return  string(abi.encodePacked(prefix, raceId, genderId, suffix));
    }
	
    function makeAttributeParts(uint lootId, uint roleId, uint petId) internal view returns (string memory){
        address _lootAddr = lootAddr;
        if(lootId > 8000){
            _lootAddr = mlootAddr;
        }
        
        string[25] memory a;
        a[0] = '[{ "trait_type": "RoleAlignment", "value": "';
        a[1] = Role(roleAddr).getAlignment(roleId);
        a[2] = '" }, { "trait_type": "RoleOccupation", "value": "';
        a[3] = Role(roleAddr).getOccupation(roleId);
        a[4] = '" }, { "trait_type": "PetAlignment", "value": "';
        a[5] = Pets(petsAddr).getAlignment(petId);
        a[6] = '" }, { "trait_type": "PetSpecies", "value": "';
        a[7] = Pets(petsAddr).getSpecies(petId);
        
        a[8] = '" }, { "trait_type": "Chest", "value": "';
        a[9] = Loot(_lootAddr).getChest(lootId);
        a[10] = '" }, { "trait_type": "Foot", "value": "';
        a[11] = Loot(_lootAddr).getFoot(lootId);
        a[12] = '" }, { "trait_type": "Hand", "value": "';
        a[13] = Loot(_lootAddr).getHand(lootId);
        a[14] = '" }, { "trait_type": "Head", "value": "';
        a[15] = Loot(_lootAddr).getHead(lootId);
        a[16] = '" }, { "trait_type": "Neck", "value": "';
        a[17] = Loot(_lootAddr).getNeck(lootId);
        a[18] = '" }, { "trait_type": "Ring", "value": "';
        a[19] = Loot(_lootAddr).getRing(lootId);
        a[20] = '" }, { "trait_type": "Waist", "value": "';
        a[21] = Loot(_lootAddr).getWaist(lootId);
        a[22] = '" }, { "trait_type": "Weapon", "value": "';
        a[23] = Loot(_lootAddr).getWeapon(lootId);
        a[24] = '" }]';
        
        string memory output = string(abi.encodePacked(a[0], a[1], a[2], a[3], a[4], a[5], a[6], a[7], a[8]));
        output = string(abi.encodePacked(output, a[9], a[10], a[11], a[12], a[13], a[14], a[15], a[16]));
        output = string(abi.encodePacked(output, a[17], a[18], a[19], a[20], a[21], a[22], a[23], a[24]));
        return output;
    }
            
    
    function claim(uint lootId, uint petId, uint roleId, string memory imageUrl) public {
        require(!_exists(petId), "Token ID invalid");
        require(Pets(petsAddr).ownerOf(petId) == _msgSender(), "not pet owner");
        require(Role(roleAddr).ownerOf(roleId) == _msgSender(), "not role owner");
        if(lootId > 8000){
            require(Loot(mlootAddr).ownerOf(lootId) == _msgSender(), "not mloot owner");
        }else{
            require(Loot(lootAddr).ownerOf(lootId) == _msgSender(), "not loot owner");
        }
        _safeMint(_msgSender(), petId);
        tokenData[petId] = Data(roleId, lootId, imageUrl);
    }
    
    function setImageUrl(uint tokenId, string memory imageUrl) public{
        require(_exists(tokenId), "ID invalid");
        require(ownerOf(tokenId) == _msgSender(), "not owner");
        
        tokenData[tokenId].url = imageUrl;
    }
    

    function toString(uint value) public pure returns (string memory) {
    // Inspired by OraclizeAPI's implementation - MIT license
    // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol

        if (value == 0) {
            return "0";
        }
        uint temp = value;
        uint digits;
        while (temp != 0) {
            digits++;
            temp /= 10;
        }
        bytes memory buffer = new bytes(digits);
        while (value != 0) {
            digits -= 1;
            buffer[digits] = bytes1(uint8(48 + uint(value % 10)));
            value /= 10;
        }
        return string(buffer);
    }
}

library Base64 {
    bytes internal constant TABLE = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";