// ==========================================================================
// $Id: house_virt_func.cpp,v 1.3 2008/10/06 20:42:50 jlang Exp $
// CSI2372 example Code for lecture 7
// ==========================================================================
// (C)opyright:
//
//   Jochen Lang
//   SITE, University of Ottawa
//   800 King Edward Ave.
//   Ottawa, On., K1N 6N5
//   Canada. 
//   http://www.site.uottawa.ca
// 
// Creator: jlang (Jochen Lang)
// Email:   jlang@site.uottawa.ca
// ==========================================================================
// $Log: house_virt_func.cpp,v $
// Revision 1.3  2008/10/06 20:42:50  jlang
// Fixed whitespaces
//
// ==========================================================================
//
// Revision 1.1  2006/10/16 01:44:37  jlang
// small caps names
//
// Revision 1.1  2006/10/16 01:36:18  jlang
// Check in for lecture 7
//
//
// ==========================================================================
#include <iostream>

using std::cout;
using std::endl;

class Building {
  double d_sqft; int d_noRooms;
  float d_price;
public:
  Building( double _sqft = 1000.0, int _noRooms = 3 ) :
    d_sqft( _sqft ), d_noRooms( _noRooms ), d_price( 0 ) {}
  int getNoRooms() { return d_noRooms; }
  virtual ~Building() {   
    cout << "Building::~Building()" << endl;
  }
  void setPrice( float _price ) { d_price = _price; return; } 
  float getPrice() const { return d_price; }
  virtual float calculateTax() const { return d_price * 0.15f; }
protected:
  void setSqft( double _sqft ) { d_sqft = _sqft; }
};

class House : public Building {
  int d_noOccu;
public:
  House( int _noOccu = 2 ) :d_noOccu( _noOccu ) {}
  ~House() {
    cout << "House::~House()" << endl;
  }
  virtual float calculateTax() const { return getPrice() * 0.07f;}
  int getNoOccupants() { return d_noOccu; };	
  int getNoRooms();
  void setSqft( double _sqft );  
};

int House::getNoRooms(){ 
  // Kitchen and Bathroom do not count
  return Building::getNoRooms() - 2;
}

void House::setSqft( double _sqft ) { 
  // max 1500 per person
  if ( _sqft/d_noOccu > 1500.0 ) { _sqft = 1500.0 * d_noOccu; }
  Building::setSqft( _sqft ); 
}

float tax( const Building& _build ) {
  float res = _build.calculateTax();
  return res;
}

int main() 
{
  Building* buildingA = new Building();
  House* home = new House();
  buildingA->setPrice( 100000.0 );
  home->setPrice( 100000.0 );
  cout << "Tax for home: " << tax( *home ) << endl;
  cout << "Tax for building: " << tax( *buildingA ) << endl;
  delete buildingA;
  buildingA = home;
  cout << "Destructing a building which is a house: " << endl;
  delete buildingA;
}
