/*
  Copyright (C) 2005 Dan Alcantara (dfalcantara@ucdavis.edu, http://wwwcsif.cs.ucdavis.edu/~alcantar)
  Based on the board game "Blokus" by Educational Insights, Inc.
  
  This program is free software; you can redistribute 
  it and/or modify it under the terms of the GNU General 
  Public License as published by the Free Software Foundation; 
  either version 2 of the License, or (at your option) any later version.
  
  This program is distributed in the hope that it will be useful, but 
  WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 
  or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for 
  more details.
  
  You should have received a copy of the GNU General Public License along 
  with this program; if not, write to the Free Software Foundation, Inc., 
  59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  
  Full license visible at http://www.opensource.org/licenses/gpl-license.php
*/

#ifndef PLAYER_H
#define PLAYER_H

#include "base.h"
#include "piece.h"

class Player
{
public:
  Player()
  {
    
  }

  Player(BlokishID player)
  {
    mBlokishID = player;
    Reset();
  }

  void SetID(BlokishID player)
  {
    mBlokishID = player;
    Reset();
  }

  void Reset()
  {
    DeleteAll();
  
    mnScore = 0;
    
    mvPieces.push_back(new SingleSquare(mBlokishID));
    mvPieces.push_back(new TwoSquares(mBlokishID));
    mvPieces.push_back(new ThreeSquares(mBlokishID));
    mvPieces.push_back(new BentThreeSquares(mBlokishID));
    mvPieces.push_back(new SquareFourSquares(mBlokishID));

    mvPieces.push_back(new FourSquares(mBlokishID));
    mvPieces.push_back(new FiveSquares(mBlokishID));
    mvPieces.push_back(new PFiveSquares(mBlokishID));
    mvPieces.push_back(new BentFourSquares(mBlokishID));
    mvPieces.push_back(new BentFiveSquares(mBlokishID));
    
    mvPieces.push_back(new LFiveSquares(mBlokishID));
    mvPieces.push_back(new StairsFiveSquares(mBlokishID));
    mvPieces.push_back(new TeeFourSquares(mBlokishID));
    mvPieces.push_back(new TeeFiveSquares(mBlokishID));
    mvPieces.push_back(new CrossFiveSquares(mBlokishID));

    mvPieces.push_back(new UFiveSquares(mBlokishID));
    mvPieces.push_back(new GunFiveSquares(mBlokishID));
    mvPieces.push_back(new SkewedFourSquares(mBlokishID));
    mvPieces.push_back(new SkewedFiveSquares(mBlokishID));
    mvPieces.push_back(new ZeeFiveSquares(mBlokishID));

    mvPieces.push_back(new BatonFiveSquares(mBlokishID));
  }

  ~Player()
  {
    DeleteAll();
  }

  Player(const Player &second)
  {
    mnScore = second.mnScore;
    for(unsigned nPiece = 0; nPiece < second.mvPieces.size(); nPiece++)
    {
      mvPieces.push_back(new BlokishPiece(*(second.mvPieces[nPiece])));
    }
  }

  void DeleteAll()
  {
    mnScore = 0;
    for(unsigned nPiece = 0; nPiece < mvPieces.size(); nPiece++)
    {
      delete mvPieces[nPiece];
    }
   
    mvPieces.clear();
  }

  int GetScore()
  {
    int value = 0;
    
    for(unsigned nPiece = 0; nPiece < mvPieces.size(); nPiece++)
    {
      value -= mvPieces[nPiece]->Value();
    }

    if(value == 0)
    {
      value = 15;
    }

    return mnScore + value;
  }

  std::vector<BlokishPiece*>& GetUnplayedPieces()
  {
    return mvPieces;
  }

  void DeletePiece(BlokishPiece *piece)
  {
    for(std::vector<BlokishPiece*>::iterator itr = mvPieces.begin(); itr != mvPieces.end(); itr++)
    {
      if(**itr == *piece)
      {
        if(mvPieces.size() == 1 && piece->GetSquares().size() == 1)
        {
          mnScore += 5;
        }
        
        mvPieces.erase(itr);
        return;
      }
    }

    std::cerr << "Could not find the piece to delete.\n";
  }

  void Write(std::ofstream &out)
  {
    int numPieces = mvPieces.size();

    out.write((char*) &mnScore,   sizeof(mnScore));
    out.write((char*) &numPieces, sizeof(numPieces));
    out.write((char*) &mBlokishID, sizeof(mBlokishID));

    for(int i = 0; i < numPieces; i++)
    {
      mvPieces[i]->Write(out);
    }
  }

  void Read(std::ifstream &in)
  {
    int numPieces;

    in.read((char*) &mnScore,   sizeof(mnScore));
    in.read((char*) &numPieces, sizeof(numPieces));
    in.read((char*) &mBlokishID, sizeof(mBlokishID));

		DeleteAll();
    mvPieces.resize(numPieces);
    for(int i = 0; i < numPieces; i++)
    {
      mvPieces[i] = new BlokishPiece(none);
      mvPieces[i]->Read(in);
    }
  }

protected:
  int                       mnScore;
  std::vector<BlokishPiece*> mvPieces;
  BlokishID                  mBlokishID;
};

#endif
