// ==========================================================================
// $Id: amphibus_vehicle.cpp,v 1.3 2010/12/06 15:30:48 jlang Exp $
// CSI2372 example Code for lecture 14
// ==========================================================================
// (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: amphibus_vehicle.cpp,v $
// Revision 1.3  2010/12/06 15:30:48  jlang
// Added compiler switch, address printing, comments
//
// Revision 1.2  2007/09/18 00:24:49  jlang
// Added comments
//
// Revision 1.1  2006/11/20 04:52:11  jlang
// Check-in for lecture 13
//
//
// ==========================================================================
#include <iostream>
#include <string>

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

// Use compiler switch VIRTUAL

/** 
 * Parent class of all vehicles
 */
class Vehicle {
  string d_engine;
public:
  Vehicle(string _engine = "Default" );
  ~Vehicle();
  const string& getEngine();
};


/** 
 * Boat is a vehicle
 */
#ifdef VIRTUAL
class Boat : virtual public Vehicle {
#else
class Boat : public Vehicle {
#endif
  float d_displacement;
public:
  Boat( float _displacement = 0.0, string _engine = "Marine Diesel" );
  ~Boat();
};


/** 
 * Bus is a vehicle
 */
#ifdef VIRTUAL
class Bus : virtual public Vehicle {
#else
class Bus : public Vehicle {
#endif
  int d_noPassengers;
public:
  Bus( int _noPassengers = 0, string _engine = "Green Diesel" );
  ~Bus();
};

/** 
 * AmphiBus is a Boat and a Bus, both are Vehicles
 */
class AmphiBus : public Boat, public Bus {
  int d_tChange;
public: 
  AmphiBus(int _tChange, int _noPassengers, float _displacement );
  ~AmphiBus();
};

//------------------------------------------------------
// Functions -- just report construction and destruction
//------------------------------------------------------

/*
 * Boat functions
 */
Boat::Boat( float _displacement, string _engine ) 
  : Vehicle( _engine ), d_displacement( _displacement )
{ 
  cout << "Boat::Boat( " << _displacement << " )" << endl;
}

Boat::~Boat() {
  cout << "Boat::~Boat() " << endl; 
}

/*
 * Bus functions
 */
Bus::Bus( int _noPassengers, string _engine ) 
  : Vehicle( _engine ), d_noPassengers( _noPassengers ) 
{ 
  cout << "Bus::Bus( " << _noPassengers << " )" << endl;
}

Bus::~Bus() {
  cout << "Bus::~Bus()" << endl;
}

/*
 * Amphibus functions
 */
AmphiBus::AmphiBus(int _tChange, int _noPassengers, float _displacement ) :   
#ifdef VIRTUAL
  Vehicle( "multi-purpose Diesel" ), 
#endif
  Boat( _displacement ), 
  Bus( _noPassengers ), d_tChange( _tChange ) 
{ 
  cout << "AmphiBus::AmphiBus( " << _tChange <<
    ", " << _noPassengers << ", " << _displacement << " )" << endl;
} 

AmphiBus::~AmphiBus() {
  cout << "AmphiBus::~AmphiBus() " << endl;
}

/*
 * Vehicle functions
 */
Vehicle::Vehicle(string _engine) : d_engine( _engine )
{
  cout << "Vehicle::Vehicle( " << _engine << " )" << endl;
}

Vehicle::~Vehicle() {
  cout << "Vehicle::~Vehicle()" << endl;
}

const string& Vehicle::getEngine() {
  return d_engine;
}


/** 
 * Construct an amphibus and print its engine
 */
int main() 
{
  AmphiBus ab( 60, 32, 7.5 );
  const string& engBus = ab.Bus::getEngine();
  const string& engBoat = ab.Boat::getEngine();
  cout << "Bus::Vehicle.d_engine: " << engBus << " at " 
       << std::hex << reinterpret_cast<const int*>(&engBus) << endl;
  cout << "Boat::Vehicle.d_engine: " << engBoat << " at " 
       << std::hex << reinterpret_cast<const int*>(&engBoat) << endl;
  return 0;
}
