/***************************************************************************
 *   Copyright (C) 2005 by Tavarez Arnaud Bakoula                          *
 *   tbakoula@yahoo.fr                                                     *
 *                                                                         *
 *   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.             *
 ***************************************************************************/
#include "combinaison.h"

/*!
 *  \class Combinaison
 *  \brief The Combinaison class stores the pieces that we submit.
 *
 *  It stores pieces with specified colors and in particular places.
 *  The stored elements are abstract representation of a piece. They are
 *  managed with a std::vector, pPionList.
 */

/*!
 *  \brief Default constructor
 *
 *  It constructs a empty combination.
 */
Combinaison::Combinaison()
{
    dim   = 0;
    count = 0;
    pPionsList = 0;       // initialisation du tableau de pPionsList Ã  NULL
}

/*!
 *  Constructs a combination that contains \a nb elements which are pieces
 *  of type Pion.
 */
Combinaison::Combinaison( uint nb )
    : dim( nb )
{
    count = 0;  count = new int[ MAXCOLORS ];
    pPionsList = new std::vector<Pion>();
    for ( uint i=0; i < dim; i++ )
      pPionsList->push_back( Pion(i) );
}

/*!
 *  \brief Copy constructor.
 *
 *  Creates a combination from another.
 */
Combinaison::Combinaison( const Combinaison& cmb )
{
    if ( cmb.dim )
    {
      dim = cmb.dim;
      pPionsList = 0;  count = 0;
      pPionsList = new std::vector<Pion>();
      count = new int[ MAXCOLORS ];

      std::vector<Pion>::iterator it = cmb.pPionsList->begin();
      for ( ; it != cmb.pPionsList->end(); ++it )
      {
        pPionsList->push_back( (*it) );
      }
    }
    else
    {
      dim = 0; count = 0;
      pPionsList = 0;
    }
}

/*!
 *  \brief Destructor.
 *
 *  Destructs the combination and restores the allocated ressources
 */
Combinaison::~Combinaison()
{
    if ( pPionsList )  delete pPionsList;
    pPionsList = 0;
    if ( count )       delete [] count;
    count = 0;
}

/*!
 *  This operator compares the current combination to \a cmb.
 *  It returns TRUE if the stored pieces in each combination are
 *  the same.
 *  \sa Pion::operator==()
 */
bool
Combinaison::operator==( Combinaison& cmb ) const
{
    if ( dim != cmb.dim )
      return false;

    std::vector<Pion>::iterator it1, it2;
    for ( it1 = pPionsList->begin(), it2 = cmb.pPionsList->begin();
          it1 != pPionsList->end(); ++it1, ++it2 )
    {
      if ( (*it1) != (*it2) )
        return false;
    }
    return true;
}

/*!
 *  This operator compares the current combination to \a cmb.
 *  It returns TRUE if one of the stored pieces in each combination
 *  is different.
 *  \sa Pion::operator!=()
 */
bool
Combinaison::operator!=( Combinaison& cmb ) const
{
    return !( *this == cmb );
}

/*!
 *  Affectation operator.
 */
Combinaison&
Combinaison::operator=( const Combinaison& cmb )
{
    if ( this != &cmb )
    {
      dim = cmb.dim;
      delete pPionsList;  pPionsList = 0;
      delete [] count;    count = 0;
      pPionsList = new std::vector<Pion>();
      count = new int[ MAXCOLORS ];

      std::vector<Pion>::iterator it = cmb.pPionsList->begin();
      for ( ; it != cmb.pPionsList->end(); ++it )
      {
        pPionsList->push_back( (*it) );
      }
    }
    return *this;
}

/*!
 *  This function determines the number of occurences of each color
 *  in the combination.
 */
void
Combinaison::doCount()
{
    if ( pPionsList==0 )
      return;

    /* Comptage des pPionsList d'une mÃªme couleur */
    std::vector<Pion>::iterator it = pPionsList->begin();
    for ( ; it != pPionsList->end(); ++it )
      count[ static_cast<int>( (*it).getColor() ) ]++;
}

/*!
 *  Resets the contents of the color occurences array.
 */
void
Combinaison::resetCount()
{
    if ( count==0 )
      return;

    for ( int i=0; i < MAXCOLORS; i++ )
      count[i] = 0;
}

/*!
 *  Adds \a nb pieces to the combination.
 */
void
Combinaison::addPions( uint nb )
{
    if ( pPionsList )
    {
      for ( uint i=0; i < nb; i++ )
        pPionsList->push_back( Pion( dim + i ) );
      dim += nb;
    }
}

/*!
 *  Removes \a nb pieces from the combination.
 */
void
Combinaison::removePions( uint nb )
{
    if ( pPionsList && !pPionsList->empty() )
    {
      for ( uint i=0; i < nb; i++ )
        pPionsList->pop_back();
      dim -= nb;
    }
}

/*!
 *  Resets the content of the combination. So the color of all the
 *  Pion objects are put to the value Pion::None.
 */
void
Combinaison::reset()
{
    if ( pPionsList==0 )
      return;

    std::vector<Pion>::iterator it = pPionsList->begin();
    for ( ; it != pPionsList->end(); it++ )
      (*it).setColor( None );
    resetCount();
}
