// Copyright 1992 by Jon Dart.  All Rights Reserved.

#ifndef _ATTACKS_H
#define _ATTACKS_H

#include "types.h"
#include "color.h"
#include "piece.h"
#include "square.h"
#include "atckentr.h"

class Board;

class Attacks
{
   // Maintains information about which pieces attack which squares
   // on the chessboard.  This information is updated after every move.	  

   public:
	   
   Attacks();

#if !defined(_WINDOWS) && defined(DEBUG_ATTACKS)
   void dump_attacks();
#endif
	
   void compute_attacks( const Board &board, const ColorType side );
   // Calculate initial attack info for "board".  This is fairly
   // expensive.	   

   void add_attacks( const Board &board, 
	   const Square &sq, const ColorType side);

   void add_discovered_attacks( const Board &board,
	   const Square &sq, const Square &dest_square );

   void remove_discovered_attacks( const Board &board,
	   const Square &sq, 
	   const Square &start_square);

   void remove_attacks( const Board &board,
	   const Square &sq, const ColorType side);

   void clear();

   BOOL any_attacks( const Square &sq, const ColorType side) const
   {
       return (sq.OnBoard()) ? my_attacks[sq][side].any_attacks() : 0;
   }
	   
   unsigned num_attacks( const Square &sq, const ColorType side ) const
   {
       return (sq.OnBoard()) ? my_attacks[sq][side].num_attacks() : 0;
   }

   // return the number of pawns of 'side' attacking or defending
   // 'sq'.
   unsigned pawn_attacks(const Square & sq, const ColorType side) const
   {
	return my_attacks[sq][side].num_attacks(Piece::Pawn);
   }

   const Attack_Entry &get_attacks( const Square sq, const ColorType side ) const
   { 
        return my_attacks[sq][side];	   
   }
   
   void set_attacks( const Attack_Entry &e, const int indx, const ColorType side)
   {
       my_attacks[indx][side] = e;
   }
   
#ifdef DEBUG_ATTACKS
   int operator == (const Attacks &) const;
#endif
   
   private:

   void add_attack( const Square &sq, const Piece &p, 
	   const ColorType side)
   {
       my_attacks[sq][side].add_attack(p.Type());
   }

   void remove_attack( const Square &sq, const Piece &p,
	   const ColorType side)
   {
       my_attacks[sq][side].remove_attack(p.Type());
   }
   
   Attack_Entry my_attacks[64][2]; // attack info for each square

};

#endif

