/* person.h
 */

#ifndef PERSON_H
#define PERSON_H

#include "main.H"
#include "floor.H"
#include "events.H"

class Elevator;
class Statistics;
class Event;

/* To add a new Person class, you must define the new derived class 
 * (see ImpatientPerson for an example), add a new field
 * for the new class of Person to PersonType, and add an element to 
 * Person_Distribution to determine what proportion of the people arriving 
 * in your system will be of this new type.
 *
 * NOTE: NUMTYPES must alway be the last element of PersonType.
 */
typedef enum { NORMAL, IMPATIENT, NUMTYPES } PersonType;

/* Person_Distribution is a parameter to the simulation and in a real 
 * simulation I would set it up to be a parameter that could be read in 
 * from input.
 */

/*NOTE: Person_Distribution must have one fewer element than
 * PersonType and the elements of Person_Distribution must add up to 1.
 * See PersonAppearance in events.C for how these two variables are used.
 */
const double Person_Distribution[] = {0.7, 0.3};


typedef enum { ON_FLOOR, IN_ELEVATOR } Status;// status of person


class Person {

public:
    
    virtual void signal_arrival( Elevator *elev, Floor *floor );
    virtual void handle_initial_appearance( Floor *start, Floor *dest );
    int  index();
    virtual void draw( float x, float y, float z );
    
    virtual void print();
    
    
    Person() {
	person_num = num_persons++;	// number the persons sequentially
    }
    
protected:

    friend class Statistics;
    // let the Statistics class see the private information
    
    static int num_persons;
    // number of persons created (static -> single copy of var)
    
    Floor *source_floor;	// floor started on
    Floor *dest_floor;		// destination floor
    float start_time;		// time of arrival on source_floor
    Status status;		// status of person
    int  person_num;		// index of person
};

class ImpatientPerson : public Person {
    
public:
    
    void signal_arrival( Elevator *elev, Floor *floor );
    void draw( float x, float y, float z );

    ImpatientPerson(Floor *floor);
    
private:
    
    float give_up_time;
    Event *leave_event;
};
    


#endif
