
#ifdef GNU
#define std
#include <iostream.h>
#else
#include <iostream>
#endif
 
#include "Animal.h"
#include "Cage.h"


//  The constructor's main job is to record that the cage is empty for
//  each day.
Cage::Cage( int min_weight, int max_weight )
  : min_weight_(min_weight), max_weight_(max_weight)
{
  for ( int i=1; i<MaxDays; i++ )
    filled_[i] = false;;
}


Cage::~Cage()
{ }


bool
Cage::InWeightRange( const Animal & animal ) const
{
  return min_weight_ <= animal.Weight() && animal.Weight() <= max_weight_;
}


//  Schedule an animal.  First check the weight range and then go
//  through the desired days to see if the cage is empty for each.  If
//  so, fill in the schedule for these days.
//
bool
Cage::Schedule( const Animal& animal )
{
  if ( ! InWeightRange( animal ) ) return false;

  bool room=true;
  int min_julian = animal.StartDate().JulianDay();
  int max_julian = min_julian+animal.NumDays()-1;
  if ( max_julian >= MaxDays ) max_julian = MaxDays;
  for ( int d=min_julian; d<=max_julian && room; d++ )
    room = !(filled_[d]);
  
  if ( room ) {
    for ( int d=min_julian; d<=max_julian && room; d++ ) {
      filled_[d] = true;
      schedule_[d] = animal;
    }
    return true;
  }
  else
    return false;
}


// Cancel from the schedule.  Erase for each day.
//
void
Cage::Cancel( const Animal& animal )
{
  int min_julian = animal.StartDate().JulianDay();
  int max_julian = min_julian + animal.NumDays() - 1;
  if ( max_julian > MaxDays ) max_julian = MaxDays;
  
  //  check if the animal is really there
  bool there=true;
  for ( int d=min_julian; d<=max_julian && there; d++  ) 
    there = (schedule_[d] == animal) && filled_[d];
  if ( there )
    for ( int d=min_julian; d<=max_julian; d++ ) filled_[d] = false;
  else
    std::cerr << "Cage::Cancel:  animal is not scheduled for the cage.\n";
}


//  What animal, if any is scheduled for the given day?
//
bool
Cage::OnDay( const Date& day, Animal& animal ) const
{
  int julian = day.JulianDay();
  if ( filled_[julian] ) {
    animal = schedule_[julian];
    return true;
  }
  else
    return false;
}


  
