#include <qimage.h>
#include <qpixmap.h>
#include <qpainter.h>
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <time.h>

#include "ai_player.h"
#include "blast.h"
#include "bomb.h"
#include "item.h"
#include "playcanvas.h"
#include "player.h"
#include "resource.h"
#include "rule.h"

#include <kdebug.h>
#include <klocale.h>
#include <kapplication.h>

#include <qvaluelist.h>
#include <qpoint.h>

PlayCanvas::PlayCanvas(QObject *parent, const char *name)
	: QCanvas(parent, name)
{
	m_x = 0;
	m_y = 0;

	m_level = NULL;
	m_away = false;
	m_enabled = false;
	m_localenabled = false;
	m_players = 3;

	weapon = NULL;
	weaponcounter = 0;

	currPlayer = NULL;

	srand(time(0) + getpid());

	resource = new Resource();

	bombList.setAutoDelete(true);
	blastList.setAutoDelete(true);
	playerList.setAutoDelete(true);
	itemList.setAutoDelete(true);
}

PlayCanvas::~PlayCanvas()
{
	playerList.remove(currPlayer);

	currPlayer = 0;
}

void PlayCanvas::setTheme(QString theme)
{
	if(theme.isNull()) return;

	resource->setTheme(theme);

	// reload everything
	if(m_level)
	{
		QPixmap background(resource->path("background"));
		QImage im = background.convertToImage();
		im = im.smoothScale(resource->tilesize() * m_level->width(), resource->tilesize() * m_level->height());
		background.convertFromImage(im);
		setBackgroundPixmap(background);

		resize(resource->tilesize() * m_level->width(), resource->tilesize() * m_level->height());
	}

	drawBackground();

	// greyed out
	if(m_enabled == false)
	{
		if(!backgroundPixmap().isNull())
		{
			QImage im = backgroundPixmap().convertToImage();

			for(int j = 0; j < im.height(); j += 2)
				for(int i = 0; i < im.width(); i += 2)
					im.setPixel(i, j, 0);

			QPixmap background;
			background.convertFromImage(im);

			/*QPainter p;
			QFont f(QString::null, 48, QFont::Black);
			p.begin(&background);
			p.setPen(QPen(QColor(255, 0, 0), 4));
			p.setFont(f);
			QFontMetrics m(f);
			p.drawText(im.width() / 2 - m.width(i18n("Loser!")) / 2, im.height() / 2 - 24, i18n("Loser!"));
			p.end();*/

			setBackgroundPixmap(background);
		}
	}

	// reload all items
	if(currPlayer)
	{
		currPlayer->setSprite(resource->pixmaparray("guy1", 1/*12*/));
		currPlayer->move(currPlayer->x(), currPlayer->y());
	}

	for (Player *player = playerList.first(); player != NULL; player = playerList.next())
	{
		player->setSprite(resource->pixmaparray("guy1", 1/*12*/));
		player->move(player->x(), player->y());
	}

	for (Bomb *bomb = bombList.first(); bomb != NULL; bomb = bombList.next())
	{
		bomb->setSprite(resource->pixmaparray("bomb", /*2*/8));
		bomb->move(bomb->x(), bomb->y());
	}

	for (Blast *blast = blastList.first(); blast != NULL; blast = blastList.next())
	{
		blast->setSprite(resource->pixmaparray("blast", /*10*/4));
		blast->move(blast->x(), blast->y());
	}

	for (Item *item = itemList.first(); item != NULL; item = itemList.next())
	{
		switch(item->type())
		{
			case Level::invalid:
				// nothing
				break;
			case Level::ground:
				break;
				// background
			case Level::wall:
				// background
				break;
			case Level::bridge:
				// background
				break;
			case Level::space:
				// nothing
				break;
			case Level::itemScree:
				item->setSprite(resource->pixmaparray("item_scree", 3));
				break;
			case Level::itemBomb:
				item->setSprite(resource->pixmaparray("item_bomb", 3));
				break;
			case Level::itemLive:
				item->setSprite(resource->pixmaparray("item_live", 3));
				break;
			case Level::itemPower:
				item->setSprite(resource->pixmaparray("item_power", 3));
				break;
			case Level::itemGrail:
				item->setSprite(resource->pixmaparray("item_grail", 3));
				break;
			case Level::itemSpeed:
				item->setSprite(resource->pixmaparray("item_speed", 3));
				break;
			case Level::itemInvisible:
				item->setSprite(resource->pixmaparray("item_invisible", 3));
				break;
			case Level::itemFlash:
				item->setSprite(resource->pixmaparray("item_flash", 3));
				break;
		}
		item->move(item->x(), item->y());
	}
}

void PlayCanvas::drawBackground(void)
{
	QPainter painter;
	QString pixmap;
	QPixmap pm;

	if(!m_level) return;
	
	pm = backgroundPixmap();

	if(pm.isNull()) return;

	QPixmap pmWall = resource->pixmap("wall", 0);
	QPixmap pmBridge = resource->pixmap("bridge", 0);
	QPixmap pmGround = resource->pixmap("ground", 0);

	painter.begin(&pm);
	for(int j = 0; j < m_level->height(); j++) {
		for(int i = 0; i < m_level->width(); i++) {
			switch (m_level->tile(i, j)) {
				case Level::wall:
					painter.drawPixmap(resource->tilesize() * i, resource->tilesize() * j, pmWall);
					break;
				case Level::bridge:
					painter.drawPixmap(resource->tilesize() * i, resource->tilesize() * j, pmBridge);
					break;
				case Level::space:
					break;
				case Level::ground:
				default:
					painter.drawPixmap(resource->tilesize() * i, resource->tilesize() * j, pmGround);
					break;
			}

		}
	}

	painter.end();

	setBackgroundPixmap(pm);
}

void PlayCanvas::buildLevel(QString levelfile)
{
	int w, h;

	if(levelfile.isNull()) return;
	//kdDebug() << "build level with " << "'" << levelfile << "'" << endl;

	m_level = new Level();

	bool success = m_level->loadLevel(/*resource->load(levelfile, Resource::level)*/levelfile.latin1());
	if(!success) return;
	//kdDebug() << "loaded file: '" << resource->load(levelfile, Resource::level) << "'" << endl;

	QPixmap background(resource->path("background"));
	QImage im = background.convertToImage();
	im = im.smoothScale(resource->tilesize() * m_level->width(), resource->tilesize() * m_level->height());
	background.convertFromImage(im);
	setBackgroundPixmap(background);

	/* paint the background */
	drawBackground();

	w = resource->tilesize() * m_level->width();
	h = resource->tilesize() * m_level->height();
	resize(w, h);

	setAdvancePeriod(1);
	update();
}

void PlayCanvas::createExit(int x, int y)
{
	Q_UNUSED(x);
	Q_UNUSED(y);

	QCanvasSprite *sprite = new QCanvasSprite(resource->pixmaparray("exit", 3), this);
	sprite->setZ(-0.1);
}

void PlayCanvas::createItem(int type, int id, int x, int y)
{
	QCanvasSprite *sprite;

	sprite = NULL;
	switch(type)
	{
		case Level::itemScree:
			sprite = new QCanvasSprite(resource->pixmaparray("item_scree", 3), this);
			break;
		case Level::itemPower:
			sprite = new QCanvasSprite(resource->pixmaparray("item_power", 3), this);
			break;
		case Level::itemGrail:
			sprite = new QCanvasSprite(resource->pixmaparray("item_grail", 3), this);
			break;
		case Level::itemLive:
			sprite = new QCanvasSprite(resource->pixmaparray("item_live", 3), this);
			break;
		case Level::itemBomb:
			sprite = new QCanvasSprite(resource->pixmaparray("item_bomb", 3), this);
			break;
		case Level::itemSpeed:
			sprite = new QCanvasSprite(resource->pixmaparray("item_speed", 3), this);
			break;
		case Level::itemInvisible:
			sprite = new QCanvasSprite(resource->pixmaparray("item_invisible", 3), this);
			break;
		case Level::itemFlash:
			sprite = new QCanvasSprite(resource->pixmaparray("item_flash", 3), this);
			break;
	}

	Item *item = new Item(id, x, y, sprite, type);
	itemList.append(item);

	m_level->setTile(x, y, type);
}

void PlayCanvas::createPlayer(int id, int x, int y)
{
	QCanvasSprite *sprite = new QCanvasSprite(resource->pixmaparray("guy1", 1/*12*/), this);
	if(sprite->frameCount() > 2) sprite->setFrame(2);

	Player *p = new Player(id, x, y, sprite);
	playerList.append(p);

	// HACK!
	if(!currPlayer) currPlayer = p;
}

bool PlayCanvas::action(int event, int option)
{
	return action_internal(event, option);
}

bool PlayCanvas::action_internal(int event, int option)
{
	switch(event)
	{
		case moveEvent:
			switch(option)
			{
				case optLeft:
					m_x--;
					break;
				case optRight:
					m_x++;
					break;
				case optUp:
					m_y--;
					break;
				case optDown:
					m_y++;
					break;
			}

			emit position(m_x, m_y);
			break;
	}

	return true;
}

Item *PlayCanvas::findItem(int x, int y)
{
	Item *item;

	for (item = itemList.first(); item != NULL; item = itemList.next())
		if (item->x() == x && item->y() == y)
			return item;
	
	return NULL;
}

Level *PlayCanvas::level()
{
	return m_level;
}

void PlayCanvas::enable(bool enabled)
{
	m_enabled = enabled;
	setTheme(resource->theme());
}

void PlayCanvas::enableLocal(bool enabled)
{
	m_localenabled = enabled;

	if(enabled)
	{
		createPlayer(0, 0, 0);
	}
}

void PlayCanvas::removeItem(int id)
{
	for(Item *item = itemList.first(); item; item = itemList.next())
		if(item->id() == id)
		{
			if(!item->isActive())
			{
				m_level->setTile(item->x(), item->y(), Level::ground);
			}
			itemList.remove(item);
			return;
		}
}

void PlayCanvas::activateItem(int id)
{
	for(Item *item = itemList.first(); item; item = itemList.next())
		if(item->id() == id)
		{
			item->activate(true);
			return;
		}
}

void PlayCanvas::highlightItem(int id)
{
	for(Item *item = itemList.first(); item; item = itemList.next())
		if(item->id() == id)
		{
			item->setHighlighted(true);
			return;
		}
}

bool PlayCanvas::enabled()
{
	return m_enabled;
}

