/***************************************************************************
 *   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 "boardwidget.h"

#include "utilities.h"
#include "siterow.h"
#include "tickrow.h"
#include "sitemanager.h"
#include "tickmanager.h"
#include "pionsrc.h"
#include "marksrc.h"

#include <qlayout.h>
#include <qframe.h>
#include <qhbox.h>

BoardWidget::BoardWidget( int row, int col, int n, QWidget* parent, const char* name )
    :  QWidget( parent, name ), nb_row(row), nb_col(col), nb_choice(n)
{
    mainBoardLayout = new QVBoxLayout( this, 4, 6, "boardLayout" );

    white_mark = black_mark = 0;

    setupSolution();
    setupBoard();
    setupChoices();
    setupMarks();

    // adding widgets to layout
    mainBoardLayout->addWidget( theAnswer );
    mainBoardLayout->addWidget( boardBox );
    mainBoardLayout->addWidget( markFrame );
    mainBoardLayout->addWidget( choiceFrame );
}


BoardWidget::~BoardWidget()
{
    pChoiceList->erase( pChoiceList->begin(), pChoiceList->end() );
    delete pChoiceList; pChoiceList = 0;

    delete answer_row;
    delete pion_row;
    delete mark_row;

    delete theAnswer;
    delete theSites;
    delete theTicks;
}

void BoardWidget::setupSolution()
{
    theAnswer = new AnswerManager( nb_col, this, "sitemanager" );
    theAnswer->createRows();
    theAnswer->setFrameStyle( QFrame::Raised | QFrame::StyledPanel );
    theAnswer->setSizePolicy( QSizePolicy( (QSizePolicy::SizeType) 5,
                                (QSizePolicy::SizeType) 0, 0, 0,
                                theAnswer->sizePolicy().hasHeightForWidth() ) );
}

void BoardWidget::setupBoard()
{
    boardBox = new QHBox( this, "boardBox" );
    boardBox->setSpacing( 4 );

    theSites = new SiteManager( nb_row, nb_col, boardBox, "sitemanager" );
    theSites->createRows();

    theSites->setFrameStyle( QFrame::Sunken | QFrame::WinPanel );

    theTicks = new TickManager( nb_row, nb_col, boardBox, "tickmanager" );
    theTicks->createRows();

    theTicks->setFrameStyle( QFrame::Raised | QFrame::StyledPanel );
    theTicks->setSizePolicy( QSizePolicy( QSizePolicy::Fixed,
                                QSizePolicy::Preferred ) );

    answer_row = new SiteRow( 0, nb_col );
    answer_row->createCells();
    pion_row = new SiteRow( 0, nb_col );
    pion_row->createCells();
    mark_row = new TickRow( 0, nb_col );
    mark_row->createCells();
}

void BoardWidget::setupMarks()
{
    markFrame = new QFrame( this, "markFrame" );
    markFrame->setSizePolicy( QSizePolicy( (QSizePolicy::SizeType) 5,
                              (QSizePolicy::SizeType) 0, 0, 0,
                              markFrame->sizePolicy().hasHeightForWidth() ) );

    markLayout = new QHBoxLayout( markFrame, 4 );
//     markSpacer = new QSpacerItem( 20, 20, QSizePolicy::Expanding, QSizePolicy::Minimum );

    white_mark = new MarkSrc( 0, choiceFrame );
    black_mark = new MarkSrc( 1, choiceFrame );
    white_mark->setState( MISPLACED );
    black_mark->setState( PLACED );

//     markLayout->addItem( markSpacer );
    choiceLayout->addWidget( white_mark );
    choiceLayout->addWidget( black_mark );
}

void BoardWidget::setupChoices()
{
    choiceFrame = new QFrame( this, "choiceFrame" );
    choiceFrame->setFrameStyle( QFrame::Raised | QFrame::StyledPanel );
    choiceFrame->setSizePolicy( QSizePolicy( (QSizePolicy::SizeType) 5,
                                (QSizePolicy::SizeType) 0, 0, 0,
                                choiceFrame->sizePolicy().hasHeightForWidth() ) );

    /* setup of the pionsrc */
    choiceLayout = new QHBoxLayout( choiceFrame, 4 );
    choiceSpacer = new QSpacerItem( 20, 20, QSizePolicy::Expanding, QSizePolicy::Minimum );

    pChoiceList = new std::vector<PionSrc*>();

    for ( int i = 0; i < MAXCOLORS; i++ )
    {
      PionSrc* srcDrop = new PionSrc( i, choiceFrame );
      srcDrop->setColor( i );
      pChoiceList->push_back( srcDrop );

      choiceLayout->addWidget( srcDrop );
      if ( i >= nb_choice )
        srcDrop->hide();
    }
    choiceLayout->addItem( choiceSpacer );
}

void
BoardWidget::changeChoicesBy( int rz )
{
    int i;
    if ( rz < 0 )
    {
      for ( i=0; i < -rz; i++ )
        pChoiceList->at(nb_choice-i-1)->hide();
    }
    else if ( rz > 0 )
    {
      for ( i=0; i < rz; i++ )
        pChoiceList->at(nb_choice+i)->show();
    }
    nb_choice += rz;
}

/******************************************************************
 *  This function is used to resize all the rows in the same time
 */
void
BoardWidget::changeCellsBy( int rz )
{
    if ( rz > 0 )
    {
      theAnswer->appendCells( rz );
      theSites->appendCells( rz );
      theTicks->appendCells( rz );

      answer_row->appendCells( rz );
      pion_row->appendCells( rz );
      mark_row->appendCells( rz );
    }
    else if( rz < 0 )
    {
      theAnswer->removeCells( -rz );
      theSites->removeCells( -rz );
      theTicks->removeCells( -rz );

      answer_row->removeCells( -rz );
      pion_row->removeCells( -rz );
      mark_row->removeCells( -rz );
    }
}

/***************************************************************
 *  Changes the number of rows in each manager of the gameboard
 */
void
BoardWidget::changeRowsBy( int rz )
{
    if ( rz > 0 )
    {
      theSites->appendCellRow( rz );
      theTicks->appendCellRow( rz );
    }
    else if( rz < 0 )
    {
      theSites->removeCellRow( -rz );
      theTicks->removeCellRow( -rz );
    }
}

void
BoardWidget::reset()
{
    theSites->resetAll();  theSites->setReadMode( TRUE );
    theAnswer->resetAll(); theAnswer->setReadMode( TRUE );
    theTicks->resetAll();  theTicks->setReadMode( TRUE );

    theAnswer->hideMe( TRUE );

    answer_row->reset();
    pion_row->reset();
    mark_row->reset();
}

void
BoardWidget::updateMe()
{
    theSites->updateMe();
    theTicks->updateMe();
    theAnswer->updateMe();

    white_mark->updateMe();
    black_mark->updateMe();
    for ( int k=0; k < MAXCOLORS; k++ )
      pChoiceList->at(k)->updateMe();
}
