#include <stdlib.h>

#include <qobject.h>
#include <qdatastream.h>
#include <qstring.h>
#include <qframe.h>
#include <qlabel.h>
#include <qlayout.h>
#include <qgroupbox.h>
#include <qdatetime.h>

#include <kdialog.h>
#include <klineedit.h>
#include <kglobal.h>
#include <kglobalsettings.h>
#include <kstandarddirs.h>
#include <kpushbutton.h>
#include <kstdguiitem.h>

#include "score.h"
#include <klocale.h>


Score::Score( QWidget *parent, const char *name )
    :QObject( parent, name )
{
    file.setName( locateLocal("appdata", "highScores"));
    playerName = getenv("LOGNAME");
    read();
}

void Score::display(int newHall, int newToday)
{
    KDialog *dlg = new KDialog(0, "Hall Of Fame", true);
    dlg->setPlainCaption(i18n("Snake Race High Scores"));
    QVBoxLayout *lay = new QVBoxLayout(dlg, KDialog::marginHint(), KDialog::spacingHint());

    ScoreBox *sb1 = new ScoreBox(dlg, 0, newHall);
    sb1->setTitle(i18n("Hall of Fame"));
    lay->addWidget(sb1);

    ScoreBox *sb2 = new ScoreBox(dlg, 0, newToday);
    sb2->setTitle(i18n("Today's High Scores"));
    lay->addWidget(sb2);

    QPushButton *b = new KPushButton(KStdGuiItem::ok(), dlg);
    b->setAutoDefault(true);
    b->setFocus();
    lay->addWidget(b, 0, Qt::AlignHCenter);
    connect( b, SIGNAL(clicked()),dlg, SLOT(accept()) );

    for ( int x = 0; x < 5; x++) {
	QString s = KGlobal::locale()->formatDate(hall[x].date);
	sb1->setScore(x, hall[x].points, hall[x].player, s);
	sb2->setScore(x, today[x].points, today[x].player, "");
    }

    dlg->exec();
    delete dlg;
}

QString Score::getPlayerName() {
    KDialog *dlg = new KDialog(0, "Hall Of Fame", true);
    dlg->setPlainCaption(i18n("Snake Race High Scores"));
    QVBoxLayout *lay = new QVBoxLayout(dlg, KDialog::marginHint(), KDialog::spacingHint());
    QLabel *label  = new QLabel(i18n("You have achieved a high score!\nPlease enter your name"),
				dlg);
    label->setAlignment(AlignCenter);
    QFont f = KGlobalSettings::generalFont();
    f.setWeight(QFont::Bold);
    f.setPointSize(14);
    label->setFont(f);
    lay->addWidget(label);

    KLineEdit *le = new KLineEdit(dlg);
    le->setText(playerName);
    le->selectAll();
    lay->addWidget(le);

    QFrame *sep = new QFrame(dlg);
    sep->setFrameStyle( QFrame::HLine | QFrame::Sunken );
    lay->addWidget(sep);

    QPushButton *b = new KPushButton(KStdGuiItem::ok(), dlg);
    b->setDefault(true);
    b->setAutoDefault(true);
    lay->addWidget(b, 0, Qt::AlignHCenter);
    connect(b, SIGNAL(released()), dlg, SLOT(accept()));
    connect(le, SIGNAL(returnPressed()), dlg, SLOT(accept()));

    dlg->exec();

    QString s = le->text();
    delete dlg;
    return s;
}

void Score::setScore(int s)
{
    read();

    bool checkHall = false;
    bool checkToday = false;
    int x, xx;

    for ( x = 0; x < 5; x++)
	if ( s > hall[x].points) {
	    checkHall = true;
	    break;
	}

    for ( xx = 0; xx < 5; xx++)
	if ( s > today[xx].points) {
	    checkToday = true;
	    break;
	}

    if (checkHall || checkToday) {

	playerName  = getPlayerName();

	if (checkHall) {
	    for (int i = 4; i > x && i > 0; i--)
		hall[i] = hall[i-1];

	    hall[x].points = s;
	    hall[x].player = playerName ;
	    hall[x].date = QDate::currentDate();
	} else
	    x = -1;

	if (checkToday) {
	    for (int i = 4; i > xx && i > 0; i--)
		today[i] = today[i-1];

	    today[xx].points = s;
	    today[xx].player =  playerName;
	    today[xx].date = QDate::currentDate();
	} else
	    xx = -1;

	display(x, xx);
	write();
    }
}

void Score::read()
{

    if ( file.exists() ) {
	if (file.open( IO_ReadOnly )) {
	    QDataStream s( &file );
	    for ( int x = 0; x < 5; x++)
		s >> hall[x].points >> hall[x].player >> hall[x].date;
	    for ( int x = 0; x < 5; x++) {
		s >> today[x].points >> today[x].player >> today[x].date;
		if ( today[x].date != QDate::currentDate())
		    today[x].points = 0;
	    }
	    file.close();
	}
    } else {
	for( int x = 0; x < 5; x++) {
	    hall[x].points = 0;
	    hall[x].player = "";
	    hall[x].date = QDate::currentDate();

	    today[x].points = 0;
	    today[x].player = "";
	    today[x].date = QDate::currentDate();
	}

	write();
    }
}

void Score::write()
{

    if (file.open( IO_WriteOnly )) {
	QDataStream s( &file );
	for ( int x = 0; x < 5; x++)
	    s << hall[x].points << hall[x].player << hall[x].date;
	for ( int x = 0; x < 5; x++)
	    s << today[x].points << today[x].player << today[x].date;
	file.close();
    }
}

ScoreBox::ScoreBox( QWidget *parent, const char *name , int current)
    : QWidget( parent, name )
{
    QVBoxLayout *lay = new QVBoxLayout(this, KDialog::marginHint(), KDialog::spacingHint());

    label = new QLabel(this);
    label->setFrameStyle( QFrame::Panel   | QFrame::Raised );
    QFont f = KGlobalSettings::generalFont();
    f.setWeight(QFont::Bold);
    f.setPointSize(14);
    label->setFont(f);
    label->setAlignment( AlignCenter );
    label->setMargin( KDialog::marginHint() );
    lay->addWidget(label, 0, Qt::AlignHCenter);

    box = new QGroupBox(this);
    lay->addWidget(box);
    QGridLayout *lay2 = new QGridLayout(box, 5, 3, KDialog::marginHint(), KDialog::spacingHint());

    for ( int x = 0; x < 5; x++) {

	QLabel *l = new QLabel(box);
	Q_CHECK_PTR(l);
	QFont f1 = KGlobalSettings::generalFont();
	f1.setPointSize(10);
	l->setFont(f1);
	l->setAlignment( AlignRight );
	date[x] = l;
	lay2->addWidget(l, x, 0);

	QLabel *l1 = new QLabel(box);
	Q_CHECK_PTR(l1);
	QFont f2 = KGlobalSettings::generalFont();
	f2.setPointSize(14);
	l1->setFont(f2);
	l1->setAlignment( AlignRight );
	points[x] = l1;
	lay2->addWidget(l1, x, 1);

	QLabel *l2 = new QLabel(box);
	Q_CHECK_PTR(l2);
	l2->setFont(f2);
	l2->setAlignment( AlignLeft );
	player[x] = l2;
	lay2->addWidget(l2, x, 2);
    }

    if (current >= 0) {
	QColorGroup colgrp(black, backgroundColor(), black,
			   black, black, blue, black);
	date[current]->setPalette( QPalette(colgrp,colgrp,colgrp) );
	points[current]->setPalette( QPalette(colgrp,colgrp,colgrp) );
	player[current]->setPalette( QPalette(colgrp,colgrp,colgrp) );
    }
}

void ScoreBox::setTitle( const QString & s )
{
    label->setText( s );
}

void ScoreBox::setScore( int x, int p, const QString &pl, const QString &dt)
{
    if (x > 5)
	return;

    if (p == 0) {
	points[x]->clear();
	player[x]->clear();
    }
    else {
	QString s;
	s.setNum(p);
	date[x]->setText(dt);
	points[x]->setText(s);
	player[x]->setText(pl);
    }
}

#include "score.moc"
