contract NewUserBonusDistributor is CardMintingFacilitator {
    mapping(address => bool) private claimedAddresses; // You only get one free card for 'signing up'
    bool public newUserBonusCardTradable = true; // If people abuse new user bonus they will be made untradable (but unlocked via battle)
    
    address[] public referals; // Array to store all unpaid referal cards
    
    function claimFreeFirstCard(address referer) external {
        require(!claimedAddresses[msg.sender]);
        
        uint8[14] memory newCard = generateRandomCard(uint32(msg.sender));
        if (!newUserBonusCardTradable) {
            newCard[13] = 1;
        }
        claimedAddresses[msg.sender] = true;
        storageContract.mintCard(msg.sender, newCard);
        allocateReferalBonus(referer);
    }
    
    function hasAlreadyClaimed() external constant returns (bool) {
        return claimedAddresses[msg.sender];
    }
    
    function allocateReferalBonus(address referer) internal {
        // To save new players gas, referals will be async and payed out manually by our team
        if (referer != address(0) && referer != msg.sender) {
            referals.push(referer);
            referals.push(msg.sender);
        }
    }
    
    function awardReferalBonus() external {
        // To save new players gas, referals are payed out below manually (by our team + kind gas donors)
        require(referals.length > 0);
        address recipient = referals[referals.length - 1];
        uint8[14] memory newCard = generateRandomCard(uint32(storageContract.totalSupply() * now));
        newCard[13] = 1; // Referal cards untradable to prevent abuse (unlocked via battle)
        
        delete referals[referals.length - 1];
        referals.length--;
        storageContract.mintCard(recipient, newCard);
    }
    
    function setNewUserBonusCardTradable(bool tradable) external {
        require(msg.sender == owner);
        newUserBonusCardTradable = tradable;
    }
    
}
//// Card Promotion + Referrals
function claimFreeFirstCard(address referer) external {
    require(!claimedAddresses[msg.sender]);
        
    uint8[14] memory newCard = generateRandomCard(uint32(msg.sender));
    if (!newUserBonusCardTradable) {
        newCard[13] = 1;
    }
    claimedAddresses[msg.sender] = true;
    storageContract.mintCard(msg.sender, newCard);
    allocateReferalBonus(referer);
}

// Array to store all unpaid referal cards