// ****************************************************
// *                                                  *
// *  simsys.C (MP3)                                  *
// *                                                  *
// *  Implemenation for a simulated run-time          * 
// *      environment (i.e. a simulated "system")     *
// *                                                  *
// *  Written 14 February 1999 by Jason Zych          *
// *   Revised 1:45pm 14 February -- added init lines *
// *              after SetBounds in SystemWouldKnow  *
// *                                                  *
// ****************************************************


#include <stddef.h>
#include "simsys.h"
#include "point.h"


// System
//    - default constructor
//    - initializes object to have default values
System::System()
{
   compArray.SetBounds(1, 10);
   for (int i = 1; i<=10; i++)
      compArray[i] = NULL; 
   usedSoFar = 0;
} 


// System
//    - copy constructor
//    - parameters : origVal - previously allocated System object 
//    - initializes object to be a coy of origVal
System::System(const System& origVal)
{
   compArray.SetBounds(origVal.compArray.Lower(), origVal.compArray.Upper());
   for (int i = compArray.Lower(); i<=compArray.Upper(); i++)
   {
      if (origVal.compArray[i] == NULL)
         compArray[i] = NULL; 
      else
         compArray[i] = origVal.compArray[i]->Clone(); 
   }
}


// ~System
//    - destructor
//    - deletes dynamically allocated memory
System::~System()
{
   for (int i = compArray.Lower(); i<=usedSoFar; i++)
      delete compArray[i];
}


// operator=
//    - parameters : origVal - previously allocated System object 
//    - return value : reference to this object
//    - sets object to be a coy of origVal
System& System::operator=(const System& origVal)
{
   int i;
   if (this!=&origVal)
   {
      for (i = compArray.Lower(); i<=usedSoFar; i++)
         delete compArray[i];

      compArray.SetBounds(origVal.compArray.Lower(), origVal.compArray.Upper());
      for (i = compArray.Lower(); i<=compArray.Upper(); i++)
      {
         if (origVal.compArray[i] == NULL)
            compArray[i] = NULL; 
         else
            compArray[i] = origVal.compArray[i]->Clone(); 
      }
   }
   return *this; 
}


// Draw
//    - "draws" the object collection to the screen 
//             (just their text-based descriptions)
void System::DrawAll()
{
   for (int i = compArray.Lower(); i<=usedSoFar; i++)
      compArray[i]->Draw();
}



// SystemWouldKnow 
//    - parameters : addingComp - pointer to new component to add
//    - adds this top-level object to the system collection of
//       objects 
void System::SystemWouldKnow(Component* addingComp)
{
   if (usedSoFar == compArray.Upper())
   {
      compArray.SetBounds(compArray.Lower(), 
                        compArray.Lower() + 2*compArray.Size() - 1);

      // *** CHANGED CODE
      // Must also make sure to initialize all new cells.  
      //  Hence, these two lines. 
      for (int i = usedSoFar; i<=compArray.Upper(); i++)
         compArray[i] = NULL; 
   }
   usedSoFar++; 
   compArray[usedSoFar] = addingComp;
}



// UserClicksWithMouse 
//    - parameters : xLoc - x-coordinate of mouse click
//                 : yLoc - y-coordinate of mouse click
//    - processes the "mouse click" event on the internal
//        objects. If mouse click is on an object that does 
//        not support any mouse-click-activated operations, 
//        or if is not on an object, then nothing will happen.
void System::UserClicksWithMouse(int xLoc, int yLoc)
{
   for (int i = compArray.Lower(); i<=usedSoFar; i++)
      compArray[i]->HandleMouseClick(Point(xLoc, yLoc));
}

