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

#ifndef __CHESS_DISPLAY_BOARD_H__
#define __CHESS_DISPLAY_BOARD_H__

#include <6170.h>
#include "board.h"
class chess_capture_move;

class chess_display_board : public board {
 
    // Overview: This class is a subtype of class board, for those
    // games played on 8x8 square board between a black and white player,
    // with chess pieces.  It's initial state is always derived from a 
    // given stream.

  public:

    enum chess_piece {
	invalid,
	none,
	pawn,
	rook,
	knight,
	bishop,
	queen,
	king
	};

    enum color {
	blank,
	black,
	white
	};
        
    enum square_t {
	normal
	};
    
    struct square {
	chess_piece piece_type;
	color piece_color;
	color square_color;
	square_t square_type;
      };
    
    struct path {
	int x1;
	int y1;
	int x2;
	int y2;
    };
            
    // Constructors and Destructors

    chess_display_board(istream &initial_format);
    // Effects: Constructs a chess_display_board that is not
    // associated with any game.  If initial_format fails to
    // meet the description stated in the Design Document, will be
    // initialized to the empty board, and calls to
    // initialized_correctly will return false.  Otherwise, the board
    // will correspond to the description in initial_format, and
    // initialized_correctly will return true.

    virtual ~chess_display_board();
    // Effects: Frees any resources associated with the chess_display_board.
    // Because garbage collection is performed, calling this
    // destructor is not strictly necessary, but if it is known that a
    // board wil not be needed, destroying it may avoid heap
    // fragmentation.

    // Methods

    virtual bool initialized_correctly() const;
    // Effects: Returns true if board was loaded successfully by
    // constructor, else returns false.

    virtual void display(extensions *ext, ostream& body, int player_num) const;

    virtual http_response *get(string request, extensions *ext);
    
    int pieces_remaining(int player_num) const;
    //Effects: If this is a valid player, returns the number of pieces
    //the given player has left, else returns -1.

    virtual int starting_pieces() const;
    // Effects: Returns the total number of pieces that were available
    // at the beginning of the game.

    void place_piece(int x, int y, chess_piece piece, 
			     color piece_color);
    // Modifies: this
    // Checks: 0 <= x,y <= 7, the square at the given coordinates
    // has chess piece none.
    // Effects: Sets the square at the given coordinates to contain
    // the pice with given properties.

    void remove_piece(int x, int y);
    // Modifies: this
    // Checks: 0 <= x,y <= 7, the square at the given coordinates does
    // not have chess piece none.
    // Effects: Sets the square at the given coordinates to have chess
    // piece none.

    void move_piece(int x1, int y1, int x2, int y2);
    // Modifies: this
    // Checks: 0 <= x1,y2,x2,y2 <= 7, the square at the coordinates
    // x1,y1 does not have chess piece none.
    // Effects: Modifies the square at coordinates x1, y1 to be empty,
    // and fills the square at coordinates x2,y2 with the piece
    // previously in the first square.

    square fetch(int y, int x) const;
    // Checks: 0 <= x,y <= 7
    // Effects: Returns the square at the given coordinates.

    void save(ostream &out) const;
    // Effects: Saves the state of this board to the given stream.
    // The output format is as specified in the problem set.

    static typeinfo_t typeinfo;

    virtual void * force (typeinfo_t &t);
    // Effects: Returns this, if t equals typeinfo, else returns a
    // NULL pointer.

    square operator()(int y, int x) const;
    // Effects: returns the requested square of this board

    int current_player() const;
    // Effects: returns the player number of the player who whose turn it currently is.
    
  protected:

    void clone_part (chess_display_board &b) const;

    square ctosquare(char ch) const;
    // Checks: character corresponds to a chess piece.
    // Effects: returns a chess_piece with the piece_type and
    // piece_color corresponding to the given character (none for no
    // color) and the other field unspecified.

    char squaretoc(square sq) const;
    // Effects: Returns a char corresponding to the chess piece on the
    // given square, lower case for black, upper for white.

    bool move_validity(int player_num, path &p, chess_piece piece_taken) const;
    // Effects: Returns true if the given piece on the indicated starting 
    // square could move the path given according to chess rules and
    // take the piece indicated, else returns false.

    void update();
    // Modifies: this
    // Effects: Notifies board that the change in state was responded to.

    bool state_changed() const;
    // Effects: Returns true if board has changed since last call to
    // update, else returns false.
    
    void set_initialization_success(bool success);
    // Modifies: this
    // Effects: Sets initialization_success to the given value.

    chess_display_board();
    // Effects: Creates a new blank chess_display_board

  private:

    virtual void set_square(int x, int y, color square_color, square_t type);
    // Modifies: this
    // Checks:  0 <= x,y <= 7
    // Effects: Sets the square at the given coordinates to have the
    // given properties.

    chess_display_board(const chess_display_board &);
    void operator= (chess_display_board &);

    bool brd_state_changed;
    int white_pieces;
    int black_pieces;
    int total_pieces;
    int player_turn;
        
    typedef array<square> column;
    array<column> brd;
    bool initialization_success;
    bool square_selected;	// true if a square is currently selected; false otherwise.
    int sel_col, sel_row;	// Row and column of selected square.
    
    // Abstraction function: The squres of brd are the squares of the
    // chess board this represents.
  
    // Rep invariant: There are no invalid pieces on the board.
    // brd has dimensions 8x8.
};

inline bool chess_display_board::initialized_correctly() const {
    return initialization_success;
}

inline chess_display_board::square chess_display_board::fetch(int y, int x) const {
    return brd[y][x];
}

inline chess_display_board::square chess_display_board::operator()(int y, int x) const {
    return brd[y][x];
}

inline void chess_display_board::update(){
    brd_state_changed = false;
}

inline bool chess_display_board::state_changed() const {
    return brd_state_changed;
}
bool parse_square(string sq, int &row, int &col);
// Modifies: col, row 
// Effects: returns true and sets col and row to
// the correct values if sq is in the form letter digit, else returns
// false.

inline int chess_display_board::current_player() const {return player_turn;}

inline int chess_display_board::starting_pieces() const {
    return total_pieces;
}

#endif

bool stomove(string s, chess_capture_move &m, board *b);
// Modifies: m
// Effects: If s is of the format 
// <letter[a-h]><number[1-8]>-<letter[a-h]><number[1-8]>, returns true
// and sets m to the corresponding move on the given board, else
// returns false. Will not call any non-const methods on b.
