#include <stdio.h>

#include <qcolor.h>
#include <qpainter.h>
#include <qpixmap.h>
#include <qbitmap.h>
#include <qrect.h>
#include <qstring.h>

#include <kapplication.h>
#include <kglobal.h>
#include <kstandarddirs.h>
#include <kiconloader.h>

#include "pixServer.h"
#include "board.h"
#include <klocale.h>
#include <kconfig.h>
#include <kdebug.h>

PixServer::PixServer( Board *b, QWidget *parent)
{
    board = b;
    initPixmaps();
    initBrickPixmap();
    initbackPixmaps();
    initRoomPixmap();
    w = parent;
}

void PixServer::erase(int pos)
{
    if (!board->isEmpty(pos))
	return;

    QRect rect = board->rect(pos);
    bitBlt( &cachePix, rect.x(), rect.y(), &backPix,
	    rect.x(), rect.y(), rect.width(), rect.height());
}

void PixServer::restore(int pos)
{
    QRect rect = board->rect(pos);
    bitBlt( &cachePix, rect.x(), rect.y(), &roomPix,
			rect.x(), rect.y(), rect.width(), rect.height());
}

void PixServer::draw(int pos, PixMap pix, int i)
{
    QPixmap p;
    p.resize(BRICKSIZE, BRICKSIZE);

    QRect rect = board->rect(pos);

    if (! plainColor)
	bitBlt( &p, 0, 0, &backPix,
		rect.x(), rect.y(), rect.width(), rect.height());
    else
	p.fill(backgroundColor);

    switch (pix) {
    case SamyPix:        bitBlt(&p ,0,0, &samyPix[i]);
	break;
    case CompuSnakePix:  bitBlt(&p ,0,0, &compuSnakePix[i]);
	break;
    case ApplePix:       bitBlt(&p ,0,0, &applePix[i]);
	break;
    case BallPix:        bitBlt(&p ,0,0, &ballPix[i]);
	break;
    default:
	break;
    }

    bitBlt(&cachePix, rect.x(), rect.y(), &p);
}

void PixServer::initPixmaps()
{

    QPixmap pm = BarIcon("snake1");
    QImage qi = pm.convertToImage();
    qi=qi.smoothScale(BRICKSIZE*18,BRICKSIZE);
    pm.convertFromImage(qi,QPixmap::AvoidDither);
    for (int x = 0 ; x < 18; x++){
		compuSnakePix[x].resize(BRICKSIZE, BRICKSIZE);
		bitBlt(&compuSnakePix[x] ,0,0, &pm,x*BRICKSIZE, 0, BRICKSIZE, BRICKSIZE, Qt::CopyROP, TRUE);
		compuSnakePix[x].setMask(compuSnakePix[x].createHeuristicMask());
    }

    pm = BarIcon("snake2");
    qi = pm.convertToImage();
    qi=qi.smoothScale(BRICKSIZE*18,BRICKSIZE);
    pm.convertFromImage(qi,QPixmap::AvoidDither);
    for (int x = 0 ; x < 18; x++){
		samyPix[x].resize(BRICKSIZE, BRICKSIZE);
		bitBlt(&samyPix[x] ,0,0, &pm,x*BRICKSIZE, 0, BRICKSIZE, BRICKSIZE, Qt::CopyROP, TRUE);
		samyPix[x].setMask(samyPix[x].createHeuristicMask());
    }

    pm = BarIcon("ball");
    qi = pm.convertToImage();
    qi=qi.smoothScale(BRICKSIZE*4,BRICKSIZE);
    pm.convertFromImage(qi,QPixmap::AvoidDither);
    for (int x = 0 ; x < 4; x++){
	ballPix[x].resize(BRICKSIZE, BRICKSIZE);
	bitBlt(&ballPix[x] ,0,0, &pm,x*BRICKSIZE, 0, BRICKSIZE, BRICKSIZE, Qt::CopyROP, TRUE);
	ballPix[x].setMask(ballPix[x].createHeuristicMask());
    }

    pm = BarIcon("apples");
    qi = pm.convertToImage();
    qi=qi.smoothScale(BRICKSIZE*2,BRICKSIZE);
    pm.convertFromImage(qi,QPixmap::AvoidDither);
    for (int x = 0 ; x < 2; x++){
	applePix[x].resize(BRICKSIZE, BRICKSIZE);
	bitBlt(&applePix[x] ,0,0, &pm,x*BRICKSIZE, 0, BRICKSIZE, BRICKSIZE, Qt::CopyROP, TRUE);
	applePix[x].setMask(applePix[x].createHeuristicMask());
    }
}

void PixServer::initbackPixmaps()
{
    QString path;
    plainColor = FALSE;

    KConfig *conf = kapp->config();
    conf->setGroup("General");

    if(conf != NULL) {
	int i = conf->readNumEntry("Background", 2);
	if(i == 1) {
	    backgroundColor = conf->readColorEntry("BackgroundColor");
	    plainColor = TRUE;
	} else if(i == 2) {
	    path = locate("appdata", "backgrounds/Green_Carpet.png");
	    path = conf->readEntry("BackgroundPixmap", path );
	}
    }

    QPixmap PIXMAP;
    int pw, ph;

    backPix.resize(MAPWIDTH, MAPHEIGHT);

    if (! plainColor) {

	PIXMAP = QPixmap(path);

	if (!PIXMAP.isNull()) {
	    pw = PIXMAP.width();
	    ph = PIXMAP.height();

	    for (int x = 0; x <= MAPWIDTH; x+=pw)     //Tile BG Pixmap onto backPix
		for (int y = 0; y <= MAPHEIGHT; y+=ph)
		    bitBlt(&backPix, x, y, &PIXMAP);
	}
	else  {
	    kdDebug() << "error loading background image :" << path << endl;
	    backgroundColor = (QColor("black"));
	    plainColor = TRUE;
	}
    }
    if ( plainColor)
	backPix.fill(backgroundColor);
}

void PixServer::initBrickPixmap()
{
    QPixmap pm = BarIcon("brick");
    if (pm.isNull()) {
	kdFatal() << i18n("error loading %1, aborting\n").arg("brick.png");
    }
    int pw = pm.width();
    int ph = pm.height();

    offPix.resize(MAPWIDTH, MAPHEIGHT);
    for (int x = 0; x <= MAPWIDTH; x+=pw)
	for (int y = 0; y <= MAPHEIGHT; y+=ph)
	    bitBlt(&offPix, x, y, &pm);
}

void PixServer::initRoomPixmap()
{
    QPainter paint;

    roomPix.resize(MAPWIDTH, MAPHEIGHT);
    bitBlt(&roomPix,0,0, &backPix);
    paint.begin(&roomPix);

    for (unsigned int x = 0; x < board->size(); x++) {
	if (board->isBrick(x))
	    drawBrick(&paint, x);
    }
    paint.end();
    
    cachePix.resize(MAPWIDTH, MAPHEIGHT);
    bitBlt(&cachePix,0,0, &roomPix);
}

void PixServer::drawBrick(QPainter *p ,int i)
{
    //Note, ROOMPIC IS OUR 'TARGET'
    QColor light(180,180,180);
    QColor dark(100,100,100);

    int topSq   = board->getNext(N, i);  //find 'address' of neighbouring squares
    int botSq   = board->getNext(S, i);
    int rightSq = board->getNext(E ,i);
    int leftSq  = board->getNext(W, i);

    QRect rect = board->rect(i); //get our square's rect

    int x = rect.x();
    int y = rect.y();      //Get x,y location of square???

    int width, height;

    int highlight = 2;    //Highlighting Distance (pixels)?

    width = height = rect.width();

    p->fillRect(x, y, width, height, light); //By default, fill square w/ Light? no.  use dark!!!!

    bitBlt(&roomPix, x, y, &offPix, x, y, width, height ); //Copy the brick pattern onto the brick

    if (!board->isBrick(rightSq)) p->fillRect(x + width - highlight, y, highlight, height, dark);  //highlight if its an end-brick.
    if (!board->isBrick(leftSq)) p->fillRect(x, y, highlight, height, light);
    if (!board->isBrick(botSq)) p->fillRect(x, y + height - highlight, width, highlight, dark);
    if (!board->isBrick(topSq)) p->fillRect(x, y, width, highlight, light);

}
