#include "field.h"

#include <qwhatsthis.h>
#include <qlayout.h>
#include <qlabel.h>
#include <qpushbutton.h>

#include <klocale.h>
#include <kcanvasrootpixmap.h>

#include "generic/gsettings.h"
#include "generic/gmisc_ui.h"

#include "factory.h"
#include "board.h"


const char *BaseField::BUTTON_TEXTS[NB_BUTTON_TYPE] = {
    I18N_NOOP("Start"), I18N_NOOP("Resume"), I18N_NOOP("Proceed")
};

BaseField::BaseField(QWidget *w)
    : _widget(w)
{
	top = new QGridLayout(w, 3, 5, 10);

    lcds = new QGridLayout(7, 1, 5);
    top->addLayout(lcds, 1, 0);
    lcds->setRowStretch(1, 0);

    board = bfactory->createBoard(true, w);
    _boardRootPixmap = new KCanvasRootPixmap(board);
    _boardRootPixmap->start();
	top->addWidget(board, 1, 2);

// board layout
	QVBoxLayout *btop = new QVBoxLayout(board);
	btop->addStretch(3);

	_label = new QLabel(board);
	_label->setAlignment(Qt::AlignCenter);
	_label->setFrameStyle( QFrame::Panel | QFrame::Sunken );
	btop->addWidget(_label, 0, Qt::AlignCenter);
	_label->hide();
	btop->addStretch(1);

    // #### the string is dummy : it seems necessary to have the "good" size !?
	_button = new QPushButton(" ", board);
	btop->addWidget(_button, 0, Qt::AlignCenter);
    _button->hide();
	btop->addStretch(3);
}

BaseField::~BaseField()
{}

void BaseField::init(bool AI, bool multiplayer, bool server, bool first,
                     const QString &name)
{
    _flags.AI = AI;
    _flags.multiplayer = multiplayer;
    _flags.server = server;
    _flags.first = first;
	QString text = (AI ? i18n("%1\n(AI player)").arg(name)
                    : (multiplayer ? i18n("%1\n(Human player)").arg(name)
                       : QString::null));
	if ( first && !server ) text += i18n("\nWaiting for server");
	setMessage(text, StartButton);
    showScore->resetColor();
    board->init(false);
}

void BaseField::setArcade()
{
    board->init(true);
    setMessage(i18n("Stage #1"), StartButton);
}

bool BaseField::isArcade() const
{
    return board->isArcade();
}

void BaseField::setMessage(const QString &label, ButtonType type)
{
	if ( label.isEmpty() ) _label->hide();
    else {
        _label->show();
        QString str =
            (isArcade() ? i18n("Arcade game") + '\n' : QString::null) + label;
        _label->setText(str);
    }

    if ( type==NoButton ) {
        _button->hide();
        _button->disconnect(SIGNAL(clicked()));
    } else {
        _button->show();
        _button->setText(i18n(BUTTON_TEXTS[type]));
        _button->setFocus();
        const char *slot = (type==ResumeButton ? SLOT(pause())
                            : SLOT(start()));
		_widget->connect(_button, SIGNAL(clicked()), _widget->parent(), slot);
    }
}

void BaseField::start(const GTInitData &data)
{
    _firstScore = KExtHighscores::firstScore();
    _lastScore = KExtHighscores::lastScore();
    hideMessage();
	board->start(data);
}

void BaseField::pause(bool pause)
{
	if (pause) {
		board->pause();
        setMessage(i18n("Game paused"), ResumeButton);
	} else {
		board->unpause();
        hideMessage();
	}
}

void BaseField::stop(bool gameover)
{
	board->stop();
    ButtonType button = StartButton;
    QString msg = (gameover ? i18n("Game over") : QString::null);
    if ( board->isArcade() && board->arcadeStageDone() ) {
        if ( board->arcadeStage()==bfactory->bbi.nbArcadeStages )
            msg = i18n("The End");
        else {
            msg = i18n("Stage #%1 done").arg(board->arcadeStage());
            button = ProceedButton;
        }
    }
    setMessage(msg, button);
}

void BaseField::scoreUpdated(int score)
{
    showScore->display(score);
    if (_flags.multiplayer) return;

    QColor color;
    if ( _firstScore<currentScore() ) color = Qt::red;
    else if ( _lastScore<currentScore() ) color = Qt::blue;
    showScore->setColor(color);
}

void BaseField::settingsChanged()
{
    board->settingsChanged();
    QColor color = KConfigCollection::configValue("fade color").toColor();
    double s = KConfigCollection::configValue("fade intensity").toDouble();
    _boardRootPixmap->setFadeEffect(s, color);
    board->canvas()->setBackgroundColor(color);
}
