// File: DadContract.sol



// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;
import "./Son.sol";

contract DadContract{

    //Other contracts
    PPtoken private pptoken;
    constructor(){
        pptoken = PPtoken(0x0144B7e66993C6BfaB85581e8601f96BFE50c9Df);
    }


    function getVote(uint256 tokenId, address delegatee) public{
        Son current = new Son();
        pptoken.transferFrom(msg.sender, address(current), tokenId);
        current.claDelTra(tokenId, delegatee);
    }


    function getMultipleVotes(uint256[] memory tokenIds, address delegatee) public{
        for(uint i = 0; i < tokenIds.length; i++){
            getVote(tokenIds[i], delegatee);
        }
    }

 
}
// File: Son.sol



// SPDX-License-Identifier: MIT


// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC721/IERC721Receiver.sol)

pragma solidity ^0.8.0;

/**
 * @title ERC721 token receiver interface
 * @dev Interface for any contract that wants to support safeTransfers
 * from ERC721 asset contracts.
 */
interface IERC721Receiver {
    /**
     * @dev Whenever an {IERC721} `tokenId` token is transferred to this contract via {IERC721-safeTransferFrom}
     * by `operator` from `from`, this function is called.
     *
     * It must return its Solidity selector to confirm the token transfer.
     * If any other value is returned or the interface is not implemented by the recipient, the transfer will be reverted.
     *
     * The selector can be obtained in Solidity with `IERC721Receiver.onERC721Received.selector`.
     */
    function onERC721Received(
        address operator,
        address from,
        uint256 tokenId,
        bytes calldata data
    ) external returns (bytes4);
}


contract Son is IERC721Receiver {

    //Other contracts
    DAOtoken private immutable daotoken;
    DelegationContract private immutable delegationcontract;
    PPtoken private immutable pptoken;
    constructor(){
        daotoken = DAOtoken(0xa3aFb35a7d1155A141417707eB9Aac3522087659);
        delegationcontract = DelegationContract(0x1755b682CfF797ee083FAf3F3e1C3e1015586c60);
        pptoken = PPtoken(0x0144B7e66993C6BfaB85581e8601f96BFE50c9Df);
    }


    function claDelTra(uint256 tokenId, address delegatee) external {
            daotoken.claim(tokenId);
            delegationcontract.delegate(delegatee);
            pptoken.transferFrom(address(this), tx.origin, tokenId);
    }


    function onERC721Received(address, address, uint256, bytes memory) public pure override returns (bytes4) {
        return IERC721Receiver.onERC721Received.selector;
    }

}

abstract contract DAOtoken {
    function claim(uint256 _tokenId) public virtual;
}
abstract contract DelegationContract {
    function delegate(address _delegatee) public virtual;
}
abstract contract PPtoken {
      function transferFrom(address _from, address _to, uint256 _tokenId) public virtual;
}