contract BasicToken is ERC20Basic, Ownable {
    using SafeMath for uint256;

    struct WalletData {
        uint256 tokensAmount;
        uint256 freezedAmount;
        bool canFreezeTokens;
    }
   
    mapping(address => WalletData) wallets;

    function transfer(address to, uint256 value)
        public
        notSender(to)
        returns(bool)
    {    
        require(to != address(0) 
        && wallets[msg.sender].tokensAmount >= value 
        && (wallets[msg.sender].canFreezeTokens && checkIfCanUseTokens(msg.sender, value)));

        uint256 amount = wallets[msg.sender].tokensAmount.sub(value);
        wallets[msg.sender].tokensAmount = amount;
        wallets[to].tokensAmount = wallets[to].tokensAmount.add(value);
        
        emit Transfer(msg.sender, to, value);
        return true;
    }

    function balanceOf(address owner)
        public
        view
        returns(uint256 balance)
    {
        return wallets[owner].tokensAmount;
    }
    // Check wallet on unfreeze tokens amount
    function checkIfCanUseTokens(
        address owner,
        uint256 amount
    ) 
        internal
        view
        returns(bool) 
    {
        uint256 unfreezedAmount = wallets[owner].tokensAmount - wallets[owner].freezedAmount;
        return amount <= unfreezedAmount;
    }
}
function checkIfCanUseTokens(
    address owner,
    uint256 amount
) 
    internal
    view
    returns(bool) 
{
    uint256 unfreezedAmount = wallets[owner].tokensAmount - wallets[owner].freezedAmount;
    return amount <= unfreezedAmount;
}

// Check wallet on unfreeze tokens amount