/*
 * Minimal BankAccount class in C, version 1.
 * CSE 374 demo, 12/07-12/15, HP
 *
 * This file contains both declarations and implementations for the 
 * BankAccount class.
 *
 * Abstraction: An object consists of both data and (pointers to) function 
 * members.  The function code is not replicated in each object, but each 
 * object is a self-contained collection of data and pointers.
 */

#include <stdio.h>
#include <stdlib.h>

/* BAccount type declaration and object layout */

typedef struct bank_account BAccount;

struct bank_account {
  /* "public" function pointers.  All contain a "this" first parameter */
  int (*get_account)(BAccount*);
  int (*get_balance)(BAccount*);
  void (*deposit)(BAccount*, int);
	
  /* "private" data members */
  int number;	   /* account number */
  int balance;	   /* account balance */
};


/* BAccount implementation */

/* member function prototypes */
int  BAccount_get_account(BAccount*);
int  BAccount_get_balance(BAccount*);
void BAccount_deposit(BAccount*, int);


/* Combination "new" and "constructor" method for BAccount objects */
/* Return a new BAccount object with given account number and initial balance */
BAccount * new_BAccount(int number, int balance) {
  /* allocate object */
  BAccount * this = (BAccount *)malloc(sizeof(BAccount));
	
  /* initialize method pointers */
  this->get_account = &BAccount_get_account;
  this->get_balance = &BAccount_get_balance;
  this->deposit     = &BAccount_deposit;
	
  /* initialize data */
  this->number  = number;
  this->balance = balance;
	
  /* return reference to newly allocated and initialized object */
  return this;
}
	
/* Member functions (methods) */
/* Note that all contain a pointer to the receiver object they are */
/* associated with. We need to do this explicitly in C; it is done */
/* implicitly in C++, Java, etc. */

int BAccount_get_account(BAccount *this) { return this->number;  }

int BAccount_get_balance(BAccount *this) { return this->balance; }

void BAccount_deposit(BAccount *this, int amount) {
	this->balance += amount;
}

/* test program */
/* Notice explicit "this" parameters for member functions. */
/* In C++ these parameters are generated by the compiler   */
/* automatically behind the scenes. */
int main() {
  BAccount *one = new_BAccount(17,0);
  one->deposit(one,100);
  printf("balance is %d\n", one->get_balance(one));
 	
  BAccount *two = new_BAccount(42,500);
  printf("balance is %d\n", two->get_balance(two));
 	
  free(one);
  free(two);
  return 0;
}