contract SUPRPrintRegistryMinter  {
    using SafeMath for uint256;

    ///////////////
    // Variables //
    ///////////////


    ArtPrintRegistryInterface public aprContract;
    SUPR1Interface public supr1Contract;
    SUPR2Interface public supr2Contract;

    address public owner1;
    address payable public printerAddress;

    mapping(uint256 => uint256) public artIdToCreditsToSpend;
    mapping(address => uint256) public addressToCreditsToSpend;
    mapping(address => uint256) public managerAddressToCreditsToGive;





    /////////////////
    // Constructor //
    /////////////////

    constructor(address payable _printerAddress, address _registryContract, address _artContractV1, address _artContractV2) public {

        aprContract = ArtPrintRegistryInterface(_registryContract);
        supr1Contract = SUPR1Interface(_artContractV1);
        supr2Contract = SUPR2Interface(_artContractV2);
        owner1 = msg.sender;
        printerAddress = _printerAddress;

    }

    //////////////////////////////
    // Minting Function         //
    //////////////////////////////

    function mint(uint256 _artId, string memory _contactMethodAndType) public returns (uint256 _tokenId) {
        uint256 artCreditBalance = artIdToCreditsToSpend[_artId];
        uint256 addressCreditBalance = addressToCreditsToSpend[msg.sender];
        if (_artId<4435){
        require(msg.sender == supr1Contract.ownerOf(_artId), "You must own artwork.");
        } else {
        require(msg.sender == supr2Contract.ownerOf(_artId), "You must own artwork.");
        }
        require(artCreditBalance>0 || addressCreditBalance >0 , "Must have a credit!");
        uint256 mintedToken = aprContract.mint(_artId, _contactMethodAndType);
        if (artCreditBalance >0) {
        artIdToCreditsToSpend[_artId] --;
        } else {
        addressToCreditsToSpend[msg.sender] --;
        }
        return mintedToken;
    }

    //////////////////////////////
    // Manager Function         //
    //////////////////////////////

    function giveArtCredit(uint256 _artId) public payable {
        uint creditsToGive = managerAddressToCreditsToGive[msg.sender];
        require(creditsToGive>0 || msg.sender==owner1 || msg.sender==printerAddress || msg.value==aprContract.pricePerPrintIntlShipInWei(), "You must have permission!");
        artIdToCreditsToSpend[_artId] ++;
        
        if (msg.value>0) {
                printerAddress.transfer(msg.value);
            } else {
                if (msg.sender==owner1 || msg.sender==printerAddress){
                    return;
                } else {
                    managerAddressToCreditsToGive[msg.sender] --;
                }
            }
    }

    function giveAddressCredit(address _recipient) public payable {
        uint creditsToGive = managerAddressToCreditsToGive[msg.sender];
        require(creditsToGive>0 || msg.sender==owner1 || msg.sender==printerAddress || msg.value==aprContract.pricePerPrintIntlShipInWei(), "You must have permission!");
        addressToCreditsToSpend[_recipient] ++;
       
        if (msg.value>0) {
                printerAddress.transfer(msg.value);
            } else {
                if (msg.sender==owner1 || msg.sender==printerAddress){
                    return;
                } else {
                    managerAddressToCreditsToGive[msg.sender] --;
                }
            }
    }
    
    
    function removeArtCredit(uint256 _artId) public {
        uint creditsToSpend = artIdToCreditsToSpend[_artId];
        require(creditsToSpend>0, "There must be a credit to remove!");
        require(msg.sender==owner1 || msg.sender==printerAddress , "You must have permission!");
        artIdToCreditsToSpend[_artId] --;
    }
    
    function removeAddressCredit(address _recipient) public {
        uint creditsToSpend = addressToCreditsToSpend[_recipient];
        require(creditsToSpend>0, "There must be a credit to remove!");
        require(msg.sender==owner1 || msg.sender==printerAddress , "You must have permission!");
        addressToCreditsToSpend[_recipient] --;
    }

    //////////////////////////////
    // Owner Functions          //
    //////////////////////////////
    
    function updatePrinterAddress(address payable _printerAddress) public returns (bool) {
        require(msg.sender == owner1 || msg.sender == printerAddress);
        printerAddress = _printerAddress;
        return true;
    }

    function setManagerCredits(address _manager, uint _credits) public returns (bool) {
        require(msg.sender == owner1 || msg.sender == printerAddress);
        managerAddressToCreditsToGive[_manager]=_credits;
        return true;
    }

}
function giveArtCredit(uint256 _artId) public payable {
    uint creditsToGive = managerAddressToCreditsToGive[msg.sender];
    require(creditsToGive>0 || msg.sender==owner1 || msg.sender==printerAddress || msg.value==aprContract.pricePerPrintIntlShipInWei(), "You must have permission!");
    artIdToCreditsToSpend[_artId] ++;
        
    if (msg.value>0) {
            printerAddress.transfer(msg.value);
        } else {
            if (msg.sender==owner1 || msg.sender==printerAddress){
                return;
            } else {
                managerAddressToCreditsToGive[msg.sender] --;
            }
        }
}

//////////////////////////////