/*------------------------------------------------------------------------------
Description: Officer Class for Detail Scheduler
Author: Chris Huyler, Tim Cross
Language: C++
Name: Officer.h
Date: March 22, 2000
------------------------------------------------------------------------------*/

class Officer
{
	public:
      Officer();
      Officer(char *N,int B,char *P,char *A);
      void Set_Init_Officer();        // initialize an officer

   	void Set_Name();
      void Set_BadgeNum();
      void Set_PhoneNum();
      void Set_AltPhoneNum();
      char* Get_Name();
      int& Get_BadgeNum();
      char* Get_PhoneNum();
      char* Get_AltPhoneNum();

      void Add_RegularShift();         // create and add regular shift to schedule
      bool Add_Shift(Shift *s);        // add shift to officer's schedule
      Shift* Get_RegularShift();       // returns shift to edit
      Shift* Find_RegularShift(string s);	// finds shift and returns
      void Remove_RegularShift();		// remove a regular shift
      bool Remove_Shift(Shift *s);    	// remove shift from officer's schedule
      void List_Details();					// list details for a day or days
      void List_Shifts(); 					// list all shifts for a day or days
      void Print();							// prints officers stats
      bool Conflict(Shift *s);      	// checks to see if shift conflicts with schedule

      Shift* Return_Next_Shift();		// function to return and remove shifts for saving
      void Set_Iterator();             // used when returning shifts for saving

      bool operator== (Officer& O);
   private:
   	char Name[25];
      int BadgeNum;
      char PhoneNum[14];
      char AltPhoneNum[14];
      Shift *Schedule[366][5];         // five shifts can be inserted on each day
      int d,c;                         // counters for iterator
};

Officer::Officer()
{
   for(int i=0;i<365;i++)   // initialize shifts to NULL
   	for(int j=0;j<5;j++)
      	Schedule[i][j]= NULL;
}
Officer::Officer(char *N,int B,char *P,char *A)
{
   for(int i=0;i<365;i++)
   	for(int j=0;j<5;j++)
      	Schedule[i][j]= NULL;
   strcpy(Name,N);
   BadgeNum = B;
   strcpy(PhoneNum,P);
   strcpy(AltPhoneNum,A);
}

void Officer::Set_Init_Officer()
{
	Set_Name();
   Set_BadgeNum();
   Set_PhoneNum();
   Set_AltPhoneNum();
}

void Officer::Set_Name()
{
   textcolor(WHITE);
   cprintf("\nPlease enter the officer's full name: ");
   textcolor(LIGHTGRAY);
   gets(Name);
}

void Officer::Set_BadgeNum()
{
	textcolor(WHITE);
	cprintf("\nPlease enter the officer's badge number: ");
   textcolor(LIGHTGRAY);
   cin >> BadgeNum;
}

void Officer::Set_PhoneNum()
{
   textcolor(WHITE);
	cprintf("\nPlease enter the officer's phone number: ");
   textcolor(LIGHTGRAY);
   gets(PhoneNum);
}

void Officer::Set_AltPhoneNum()
{
   textcolor(WHITE);
	cprintf("\nPlease enter the officer's alternate phone number: ");
   textcolor(LIGHTGRAY);
   gets(AltPhoneNum);
}

char* Officer::Get_Name()
{
	return(Name);
}

int& Officer::Get_BadgeNum()
{
	return(BadgeNum);
}

char* Officer::Get_PhoneNum()
{
	return(PhoneNum);
}

char* Officer::Get_AltPhoneNum()
{
	return(AltPhoneNum);
}

void Officer::Add_RegularShift()
{
	RegularShift *R = new RegularShift;
   R->Set_Init_Regular();
	if(!Conflict(R))   // cannot add a shift that conflicts with a current shift
   	Add_Shift(R);
   else
   {
   	textcolor(RED+BLINK);
      cprintf("                       There is a conflict.                     ");
      sleep(5.0);
      textcolor(LIGHTGRAY);
   }
}

bool Officer::Add_Shift(Shift *s)
{
	int day = s->Get_Day(), counter = 0;
   bool done = false;
   while(!done && counter<5)
   	if(Schedule[day][counter] == NULL)
      {
      	Schedule[day][counter] = s;
      	done = true;
      }
      else counter++;
   return(counter<5);
}

void Officer::Remove_RegularShift()
{
	textcolor(YELLOW);
   cprintf("\nEnter information to remove a shift -\r\n");
   textcolor(LIGHTGRAY);
	Shift *s = Get_RegularShift();
   clrscr();
   s->Print();
   textcolor(WHITE);
   cprintf("\nDelete this Shift?\n");
   plist pl(2);
   pl.insert(" Yes ");
   pl.insert(" No  ");
   if(pl.printList() == " Yes ")
   	Remove_Shift(s);
}

bool Officer::Remove_Shift(Shift *s)
{
   int day = s->Get_Day(), counter = 0;
   bool done = false;
   while(!done && counter<5)
   	if(Schedule[day][counter] == s)
      {
      	delete Schedule[day][counter];
         Schedule[day][counter] = NULL;
      	done = true;
      }
      else counter++;
   return(done);
}

void Officer::List_Details()
{
	for(int i=0;i<365;i++)
   	for(int j=0;j<5;j++)
         if(Schedule[i][j] != NULL)
      		if(Schedule[i][j]->Identify() == "DetailShift")
         		Schedule[i][j]->Print();
}

void Officer::List_Shifts()
{
	for(int i=0;i<365;i++)
   	for(int j=0;j<5;j++)
      	if(Schedule[i][j] != NULL)
         	Schedule[i][j]->Print();
}

void Officer::Print()
{
	cout << endl << "Name        : " << Name
        << endl << "Badge #     : " << BadgeNum
        << endl << "Phone #     : " << PhoneNum
        << endl << "Alt Phone # : " << AltPhoneNum << endl;
}

bool Officer::operator== (Officer& O)
{
	return(Name == O.Get_Name());
}

bool Officer::Conflict(Shift *s)
{
   bool conflict = false;
   int c = 0;
   int st = s->Get_StartTime();
   int et = s->Get_EndTime();
   int d = s->Get_Day();
   while(Schedule[d][c]!=NULL && c<5)
   {
// if start time is between current shift's start and end time there is a conflict
   	if(st>=Schedule[d][c]->Get_StartTime() && st<Schedule[d][c]->Get_EndTime())
      	conflict = true;
// if end time is between current shift's start and end time there is a conflict
      if(et>Schedule[d][c]->Get_StartTime() && et<=Schedule[d][c]->Get_EndTime())
      	conflict = true;
// if start time is before current start and end time is after current end
		if(st<Schedule[d][c]->Get_StartTime() && et>Schedule[d][c]->Get_EndTime())
      	conflict = true;
      c++;
	}
	return(conflict);
}

Shift* Officer::Get_RegularShift(){
	clrscr();
   DayConverter dc;
   int d = dc.create_day();
   clrscr();
   textcolor(WHITE);
   cprintf("\nChoose a Shift from the list: \n");
   textcolor(LIGHTGRAY);
   plist pl(6);
   int c = 0;
   while(c<5 && Schedule[d][c]!=NULL){
   	if(Schedule[d][c]->Identify() == "RegularShift")
      	pl.insert(Schedule[d][c]->Get_Description());
      c++;
   }
   return(Find_RegularShift(pl.printList()));
}

Shift* Officer::Find_RegularShift(string s){
   // searches for regular shift by description
   Shift *sh;
	int d=1,c;
   bool found = false;
   while(!found && d<365){
   	c = 0;
      while(!found && c<5 && Schedule[d][c]!=NULL){
      	if(Schedule[d][c]->Get_Description() == s){
            sh = Schedule[d][c];
         	found = true;
         }
         c++;
      }
      d++;
   }
	return(sh);
}

void Officer::Set_Iterator()
{
	d=0;
   c=0;
}
Shift* Officer::Return_Next_Shift()
{
   Shift *temp = NULL;
   bool found = false;
	while(d<366 && !found)
   {
   	if(c>=5) c = 0;
   	while(c<5 && !found)
      {
      	if(Schedule[d][c])
         {
         	temp = Schedule[d][c];
          	found = true;
         }
      	c++;
      }
   	if(!found)d++;
   }
   return(temp);
}

