//  This is -*- c++ -*- code

#ifndef __PLAYER_H__
#define __PLAYER_H__
#include <sys/time.h>
#include <time.h>

#include <6170.h>
#include "board.h"
#include <ps5/normal_response.h>
#include <sys/types.h>
#include <time.h>

class move;
class http_response;

class player : public web_node {
    // Overview: A player is a participant in a game, played upon a board.
public:
    

    // Constructors:

    player(string name, long total_time);
    // Requires: name not be blank.
    // Checks: total_time >= 0;
    // Effects:  Creates a new player of the given name, not associated with
    // any game.
    // Player will have have up total_time seconds to complete all moves.

    // Methods:

    virtual bool is_associated() const;
    // Effects: Returns true if this board is associated with a game.

    string get_name() const;
    // Effects: Returns the name of this player.

    bool get_position (string &p) const;
    // Modifies: p
    // Effects: If this has a position, returns true and sets p to the
    // position; else p is unmodified and returns false.

    virtual void set_position (string p);
    // Modifies: this
    // Effects: If this has a position, returns true and sets p to the
    // position; else p is unmodified and returns false.

    virtual void set_name (string n);
    // Checks: name is non-empty
    // Effects: The name of the player becomesn.
    long get_time() const;
    // Effects: Returns amount of time this player has left.

    virtual void set_time(long time);
    // Modifies: this.
    // Checks: time is non-negative
    // Effects: Changes the time remaining for this player to time, expressed in miliseconds.

    virtual void display(extensions *ext, ostream &body) const = 0;
    // Effects: Returns a html-formatted string describing player
    // name, position, and time remaining.


    virtual http_response *get(string request, extensions *ext); 
    // Modifies: this 
    // Effects: Modifies the field according to a TBD
    // protocol for the request.

    virtual void you_moved (move &m);
    // Modifies: this, possibly other game state
    // Effects: notifys this that it has made a move.  The clock for
    // time taken for the current move should be stopped.

    virtual void opponent_moved (move &m, int player_num);
    //modifies: this, possibly other game state
    // Effects: This method is called by game when an opponent of this
    // player applies move m.  The player applying the move is p.

    virtual void state_changed(void);
    // Modifies: this or other game state
    // Effects: This method is called by game when game state changes in
    // response to a non-move event such as initialization.

    virtual void consider_forfeiting();
    // Modifies: this and possibly game 
    // Effects: if time is run out, or other conditions imposed by suptypes
    // are true,  forfeits.  Else do nothing.

protected:
    virtual void start_clock();
    // Modifies: this
    // Checks: That clock was previously in stopped state.
    // Effects: starts counting time against this

    virtual void stop_clock();
    // Modifies: this, possibly game state Effects: Stops the clock of
    // this.  If the time is out, forfeits the game, else game state
    // is unchanged. It is acceptable to stop a stopped clock.

    virtual void associate( game *gm);
    // Modifies: this 
    // Effects: Associates this with a particular game.
    // This method should only be called by game::game or overiding subclasses, and never by
    // using code.  A player that is not associated with a particular
    // game can be used, but no web requests can be sent to it.
    // Associate will not call any non-const methods of game.

    game * get_game() const;
    // Effects returns the game this is associated with or null.
    
    friend game::game(board *b, player *p1, player *p2, string uri,
		      string image_base, bool player1_is_default);
    //friendship-extent: game::game is a friend of player so it can
    //call player::associate.  game::game shall not access other
    //private or protected methods or state of player.
    
private:

    player();
    // Disable default constructor

    void operator= (player &);
    // Disable equality operator

    string player_name;
    // The name of this player; Initialized in constructor.

    string player_position;
    // The position of this player


    long player_time;
    // The amount of time this player has left.  Initialized in constructor.

    bool clock_is_running;
    // Used to track state of clock.  Initialized in constructor to false.
    struct timeval clock_started_when;// When did the clock start

    // Rep invariant: If g is non-null, g->get_board() == this
    game *g;

};


inline string player::get_name() const {
    return player_name;
}

inline long player::get_time() const {
    player *tempplayer = (player *)this;
    if (clock_is_running) {
	tempplayer->stop_clock();
	tempplayer->start_clock();
  }
  return player_time;
}

inline game * player::get_game() const {return g;}

#endif



