// Bonsai.cpp (implementation file).
// Object Model Demonstration using Bonsai. A bonsai is a non-empty set of trees
// in a bonsai pot. The term "bonsai" is both singular and plural.
// Version 1.12.
// Copyright 1999 by Rick Wagner, all rights reserved. Authorized use with
// attribution for educational purposes only.
// Created September 25, 1999.
// Last edited November 5, 1999.

#include "Bonsai.h"

// Class function implementations:
// Class Tree member functions:
Tree::Tree(const char* name, const char* species, Bonsai* partOf) // Constructor
{
  _name = new char[strlen(name) + 1];
  strcpy(_name, name);
  _species = new char[strlen(species) + 1];
  strcpy(_species, species);
  _partOf = partOf;
}

Tree::~Tree()                                       // Destructor
{
  if (_partOf != NULL)
  {
    _partOf->removeTree(this);
  }
  delete [] _name;
  delete [] _species;
}

char* Tree::getName() const                         // Accessors
{
  return _name;
}

char* Tree::getSpecies() const
{
  return _species;
}

Bonsai* Tree::getPartOf() const
{
  return _partOf;
}

void Tree::setName(char* name)                       // Mutators.
{
  if (_name != NULL) delete [] _name;
  _name = new char[strlen(name) + 1];
  strcpy(_name, name);
}
void Tree::setSpecies(char* species)
{
  if (_species != NULL) delete [] _species;
  _species = new char[strlen(species) + 1];
  strcpy(_species, species);
}

void Tree::setPartOf(Bonsai* bonsai)
{
  _partOf = bonsai;
}


// Pot class member functions:
Pot::Pot(float size, const char* style, const char* color, // Constructor.
         const char* country, Bonsai* partOf)
{
  _size = size;
  _style = new char[strlen(style) + 1];
  strcpy(_style, style);
  _color = new char[strlen(color) + 1];
  strcpy(_color, color);
  _countryOfOrigin = new char[strlen(country) + 1];
  strcpy(_countryOfOrigin, country);
  _partOf = partOf;
}

Pot::~Pot()                                         // Destructor.
{
  if (_partOf != NULL)
  {
    _partOf->setPot(NULL);
  }
  delete [] _style;
  delete [] _color;
  delete [] _countryOfOrigin;
}

float Pot::getSize() const                          // Accessors
{
  return _size;
}

char* Pot::getStyle() const
{
  return _style;
}

char* Pot::getColor() const
{
  return _color;
}

char* Pot::getCountry() const
{
  return _countryOfOrigin;
}

Bonsai* Pot::getPartOf() const
{
  return _partOf;
}

void Pot::setSize(float size)                      // Mutators
{
  _size = size;
}

void Pot::setStyle(char* style)
{
  if (_style != NULL) delete [] _style;
  _style = new char[strlen(style) + 1];
  strcpy(_style, style);
}

void Pot::setColor(char* color)
{
  if (_color != NULL) delete [] _color;
  _color = new char[strlen(color) + 1];
  strcpy(_color, color);
}

void Pot::setCountry(char* country)
{
  if (_countryOfOrigin != NULL) delete [] _countryOfOrigin;
  _countryOfOrigin = new char[strlen(country) + 1];
  strcpy(_countryOfOrigin, country);
}

void Pot::setPartOf(Bonsai* bonsai)
{
  _partOf = bonsai;
}

// Class Bonsai member functions:
Bonsai::Bonsai(const char* label)                    // Constructor
{
  int i = 0;
  _label = new char[strlen(label) + 1];
  strcpy(_label, label);
  _pot = NULL;
  _numTrees = 0;
  _tree = new Tree*[100];
  for (i = 0; i < 100; i++)
  {
    _tree[i] = NULL;                                 // For good housekeeping.
  }
}


Bonsai::~Bonsai()                                    // Destructor.
{
  int i = 0;
  for (i = 0; i < _numTrees; i++)
  {
    _tree[i]->setPartOf(NULL);                       // Unhook the trees.
  }
  if (_pot != NULL) _pot->setPartOf(NULL);           // Unhook the pot.
  delete [] _label;
  delete [] _tree;
  cout << " *Kaboom* ";
}

char* Bonsai::getLabel() const                       // Accessors.
{
  return _label;
}

Pot* Bonsai::getPot() const
{
  return _pot;
}

int Bonsai::getNumTrees() const 
{
  return _numTrees;
}

Tree* Bonsai::getTree(int i) const
{
  return _tree[i];
}

void Bonsai::setPot(Pot* pot)                        // Mutators
{
  _pot = pot;
  pot->setPartOf(this);
}

void Bonsai::addTree(Tree* tree)
{
  _tree[_numTrees] = tree;
  _numTrees++;
  tree->setPartOf(this);
}

void Bonsai::removeTree(Tree* tree)
{
  int i = 0;
  int j = 0;

  for (i = 0; i < _numTrees; i++)
  {
    if (_tree[i] == tree)                            // Comparing pointers.
    {
      _numTrees--;                                   // Straighten out the bookkeeping.
      tree->setPartOf(NULL);                         // Let the tree know it's no longer
                                                     // part of a bonsai.
      for (j = i; j < _numTrees; j++)
      {
        _tree[j] = _tree[j+1];                       // Compact the array.
      }
      break;                                         // Break out of for().
    }
  }
}

// Class Collection member functions:
Collection::Collection()                             // Constructor
{
  int i = 0;
  _numTrees = 0;
  _tree = new Tree*[giMaxTrees];
  for (i = 0; i < giMaxTrees; i++)
  {
    _tree[i] = NULL;                                 // For good housekeeping.
  }
  _numPots = 0;
  _pot = new Pot*[giMaxPots];
  for (i = 0; i < giMaxPots; i++)
  {
    _pot[i] = NULL;                                   // For good housekeeping.
  }
  _numBonsai = 0;
  _bonsai = new Bonsai*[giMaxBonsai];
  for (i = 0; i < giMaxBonsai; i++)
  {
    _bonsai[i] = NULL;                                // For good housekeeping.
  }
}

Collection::~Collection()                             // Destructor.
{
  delete [] _bonsai;
}

int Collection::getNumTrees() const                   // Accessors.
{
  return _numTrees;
}

Tree* Collection::getTree(int i) const
{
  return _tree[i];
}

int Collection::getNumPots() const                 
{
  return _numPots;
}

Pot* Collection::getPot(int i) const
{
  return _pot[i];
}

int Collection::getNumBonsai() const
{
  return _numBonsai;
}

Bonsai* Collection::getBonsai(int i) const
{
  return _bonsai[i];
}

void Collection::addTree(Tree* tree)                    // Mutators.
{
  _tree[_numTrees] = tree;
  _numTrees++;
}

void Collection::addPot(Pot* pot)
{
  _pot[_numPots] = pot;
  _numPots++;
}

void Collection::addBonsai(Bonsai* bonsai)
{
  _bonsai[_numBonsai] = bonsai;
  _numBonsai++;
}
