contract HbeToken is CanReclaimToken, SnapshotToken {
    /* solhint-disable */
    string public constant name = "healthbank Token";
    string public constant symbol = "HBE";
    uint8 public constant decimals = 0;
    /* solhint-enable */

    address public hbeMembership;
    address public hbeMemberVault;

    bool private _lockContracts;

    /** MODIFIERS **/
    modifier onlyHbeMembership() {
        require(msg.sender == hbeMembership, "not a member");
        _;
    }

    /**
     * @dev Constructor of HbeToken that instantiates a new Mintable Pauseable Burnable Token
     */
    constructor() public {
        // token should not be transferrable until after all tokens have been issued
        paused = true;
    }

    /** 
    * @dev allows onlyHbeMembership to release the tokens of an existing member, effective cancelling their membership
    * @param _address address of the ex HBE member
    * @param _currentlyLocked amount of HBE tokens locked owned by member
    */
    function releaseMembershipFee(address _address, uint256 _currentlyLocked) external onlyHbeMembership {
        doTransfer(hbeMemberVault, _address, _currentlyLocked);
    }

    /**
    * @dev updates the member's locked HBE balance to reflect the current HBE Membership price
    * @param _address address of the HBE member
    * @param _currentlyLocked amount of HBE tokens locked owned by member
    * @param _currentMemberFee current membership fee pricing
    * @return bool, bool, uint256 
    */
    function updateMemberBalance(address _address, uint256 _currentlyLocked, uint256 _currentMemberFee) 
        external 
        onlyHbeMembership 
        returns (bool, bool, uint256) {
            uint256 currentBalance = balanceOf(_address);
            uint256 difference;

            // balance due from _address
            if (_currentlyLocked < _currentMemberFee) {
                difference = _currentMemberFee.sub(_currentlyLocked);

                if (difference <= currentBalance) {
                    doTransfer(_address, hbeMemberVault, difference);
                    // mark successful, no refund, N balance chance
                    return(true, false, difference);
                } else {
                    revert("insufficent HBE funds");
                }
            }

            // refund due to _address
            if (_currentlyLocked > _currentMemberFee) {
                difference = _currentlyLocked.sub(_currentMemberFee);
        
                doTransfer(hbeMemberVault, _address, difference);

                // mark successful, yes refund, N balance change
                return(true, true, difference);
            }
            // mark successful, no refund, 0 balance change Eg. already an active member
            return (true, false, 0);
        }

    /**
    * @notice allows onlyOwner to set the address of the HBE membership contracts
    * @dev onlyOwner to set the contracts once. Afterwards, the contracts' addresses are locked and cannot be updated
    * @param _membershipContract address of membership management
    * @param _membershipVault address of the membe HBE token vault
    */
    function setMembershipContracts(address _membershipContract, address _membershipVault) external onlyOwner {
        require(!_lockContracts);
        require(_membershipContract != address(0), "invalid membership address");
        require(_membershipVault != address(0), "invalid vault address");

        _lockContracts = true;

        hbeMembership = _membershipContract;
        hbeMemberVault = _membershipVault;
    }
}
function setMembershipContracts(address _membershipContract, address _membershipVault) external onlyOwner {
    require(!_lockContracts);
    require(_membershipContract != address(0), "invalid membership address");
    require(_membershipVault != address(0), "invalid vault address");

    _lockContracts = true;

    hbeMembership = _membershipContract;
    hbeMemberVault = _membershipVault;
}

/**
 * @notice allows onlyOwner to set the address of the HBE membership contracts
 * @dev onlyOwner to set the contracts once. Afterwards, the contracts' addresses are locked and cannot be updated
 * @param _membershipContract address of membership management
 * @param _membershipVault address of the membe HBE token vault
 */