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

#ifndef _SQUARE_H
#define _SQUARE_H

#include "types.h"
#include "color.h"
#include <afxwin.h>

class Square;

class Square
{
    public:	
	
    friend Square operator +( const Square &sq, const int i);
    friend Square operator -( const Square &sq, const int i);

    enum {InvalidSquare = 127};

    Square()
    {
       my_location = InvalidSquare;
    }

    Square( const int location )
    {
       my_location = location;
    }
    
    Square( const int file, const int rank, const ColorType side );
    
    operator int() const
    {
       return my_location;	 
    }
    
    Square &operator +=( const int i)
    {
        my_location += i;
	return *this;
    }
    
    Square &operator -=( const int i)
    {
        my_location -= i;
	return *this;
    }

    Square &operator ++()
    {
        my_location++;
	return *this;
    }

    Square &operator --()
    {
        my_location--;
	return *this;
    }

    // returns "rank" from the perspective of "side".  1 = 1st
    // rank for side, 8 = last rank.	    
    int Rank( const ColorType side = White) const
    {
       ASSERT(OnBoard());
       return (side == Black) ? Ranks[my_location] : 9-Ranks[my_location];
   }

    int File() const
    {
       return Files[my_location];
    }
    // returns file.  Queen rook file = 1, King rook file = 8.
	    
    BOOL OnBoard() const
    {
      return (my_location & ~0x3f) == 0;
    }
    
    BOOL OnEdge() const
    {
      return Edge[my_location];	    
    }
    
    BOOL InCenter() const
    {
      return Center[my_location];	    
    }
    
    BOOL InCorner() const
    {
       return Corners[my_location];
    }
    
    // invalid value, used as delimiter
    static const Square &Invalid();

    BOOL IsInvalid() const
    {
       return my_location == InvalidSquare;	    
    }
    
    void SetInvalid()
    {
       my_location = InvalidSquare;
    }
    
    ColorType Color() const
    {
       return (ColorType)Colors[my_location];
    }
    
    static Square Value( char *p);
    // Parse a square value in algebraic notation (e.g. "g7") and
    // return a corresponding Square type.
    
    char FileImage() const;

    char RankImage() const;

    private:
	    
    byte my_location;
    static const int Files[64];
    static const int Ranks[64];
    static const int Edge[64];
    static const int Colors[64];
    static const int Center[64];
    static const int Corners[64];
};

inline Square operator +( const Square &sq, const int i)
{
    return Square(sq.my_location + i);
}

inline Square operator -( const Square &sq, const int i)
{
    return Square(sq.my_location-i);
}

#endif

