/*
 * Program to demonstrate simple use of struct (to represent bank account).
 */
#include <stdio.h>
#include <stdbool.h>

/* 
 * struct for simplified "bank account" object
 */
#define ACCT_ID_LENGTH 8
typedef struct {
    char acct_ID[ACCT_ID_LENGTH+1];
    unsigned long balance;
} account_t;

/* 
 * function to print account ID and balance
 * 
 * notice that we pass struct and not pointer -- mostly to illustrate
 * that this can work and is not bad if the struct is small and the 
 * function doesn't change it.
 */
void print_acct(FILE * outstream, account_t a) {
    fprintf(outstream, "ID %s, balance $%ld", a.acct_ID, a.balance);
}

/* 
 * function to deposit -- must pass pointer to struct
 */
void deposit(account_t * a, unsigned long amount) {
    a->balance += amount;
}

/*
 * function to (try to) withdraw -- must pass pointer to struct:
 *
 * if amount to withdraw is no more than balance, performs withdrawal
 *   and returns true
 * otherwise returns false
 */
bool withdraw(account_t * a, unsigned long amount) {
    if (a->balance >= amount) {
        a->balance -= amount;
        return true;
    } 
    else {
        return false;
    }
}

int main(void) {
    account_t acct1 = { "12341234", 1000 };
    printf("initially:  ");
    print_acct(stdout, acct1);
    putchar('\n');
    deposit(&acct1, 1200);
    printf("after deposit:  ");
    print_acct(stdout, acct1);
    putchar('\n');
    bool withdrawal_okay = false;
    do {
        withdrawal_okay = withdraw(&acct1, 1000);
        if (withdrawal_okay) {
            printf("after withdrawal:  ");
            print_acct(stdout, acct1);
            putchar('\n');
        }
        else {
            printf("insufficient funds for withdrawal\n");
        }
    } while (withdrawal_okay);
    return 0;
}