/*
 * EditorState.cpp
 *
 *  Created on: 2009-07-10
 *      Author: wasyl
 */

#include "EditorState.h"

#include "../prep/Common.h"
#include <allegro5/allegro.h>
#include <allegro5/a5_primitives.h>
#include "../thing/Tile.h"
#include "../thing/Avatar.h"
#include "../prep/Common.h"
#include "../thing/Level.h"
#include "../thing/Bag.h"
#include "../thing/Container.h"
#include "../thing/Cloud.h"
#include "../misc/LoadSave.h"
#include "../prep/res/Resources.h"
#include "../state/PlayState.h"
#include "../thing/Message.h"
#include "../thing/Garbage.h"
#include "../thing/Lever.h"
#include "../thing/Spikes.h"
#include "../thing/ForceField.h"
#include "../thing/PressPad.h"
#include "../thing/Baddie.h"
#include "../thing/Fireworks.h"

EditorState::EditorState()
	: AppState<int>(al_get_current_display())
{
	for (int x = 0; x < 40; x++)
		for (int y = 0; y < 30; y++)
				tile[x][y] = NULL;

	for (int i = 0; i < 5; i++)
		palette.push_back(new Tile(i,NULL,0,0));

	palette.push_back(new Message("Test message."));
	palette.push_back(new Bag());
	palette.push_back(new Garbage());
	palette.push_back(new Spikes());
	palette.push_back(new ForceField(false));
	palette.push_back(new ForceField(true));

	palette.push_back(new Avatar());
	palette.push_back(new Baddie(false));
	palette.push_back(new Baddie(true));

	for (int i = 1; i < 6; i++)
		palette.push_back(new Container(Vec(0,0),i));

	for (int i = 0; i < 5; i++)
	{
		palette.push_back(new Lever(i,false));
		palette.push_back(new Lever(i,true));
	}
	for (int i = 0; i < 5; i++)
	{
		palette.push_back(new PressPad(i,false));
		palette.push_back(new PressPad(i,true));
	}
	palette.push_back(new Fireworks());


	selected = 0;

	mPut = new OnPress(new MouseKey(MouseKey::LEFT));
	mContinue = new MouseKey(MouseKey::LEFT);
	mSave = new OnPress(new Key(ALLEGRO_KEY_S));
	mLoad = new OnPress(new Key(ALLEGRO_KEY_L));
	mPlay = new OnPress(new Key(ALLEGRO_KEY_P));
	mPrev = new OnPress(new Key(ALLEGRO_KEY_Z));
	mNext = new OnPress(new Key(ALLEGRO_KEY_X));
	mRemove = new MouseKey(MouseKey::RIGHT);

	Resources::load(mFont, "media/font.ttf");
}

EditorState::~EditorState()
{
}

void EditorState::update(double dt)
{
	if (*mPut)
	{
		int x = mouseState()->x / 20 * 20;
		int y = mouseState()->y / 20 * 20;
		mLastX = x; mLastY = y;

		if (tile[x/20][y/20])
			mWorld.remove(tile[x/20][y/20]);

		Entity *toPut = palette[selected]->clone();
		toPut->setPos(Vec(x,y));
		mWorld.add(toPut);
		mWorld.reindex();
		tile[x/20][y/20] = toPut;
	}
	else if (*mContinue)
	{
		int x = mouseState()->x / 20 * 20;
		int y = mouseState()->y / 20 * 20;
		if (mLastX != x || mLastY != y)
		{
			if (tile[x/20][y/20])
				mWorld.remove(tile[x/20][y/20]);

			mLastX = x; mLastY = y;
			Entity *toPut = palette[selected]->clone();
			toPut->setPos(Vec(x,y));
			mWorld.add(toPut);
			mWorld.reindex();
			tile[x/20][y/20] = toPut;
		}
	}

	if (*mRemove)
	{
		int x = mouseState()->x / 20;
		int y = mouseState()->y / 20;
		if (tile[x][y])
		{
			mWorld.remove(tile[x][y]);
			mWorld.reindex();
			tile[x][y] = NULL;
		}
	}

	if (*mPrev)
		selected = (selected + palette.size() - 1) % palette.size();
	else if (*mNext)
		selected = (selected + 1) % palette.size();
	int z = mouseState()->z;
	selected = (selected + z - mLastZ + palette.size()) % palette.size();
	mLastZ = z;

	if (*mSave)
	{
		LoadSave().save("levels/edit.lv", &mWorld);
	}
	if (*mLoad)
	{
		Entities &ents = mWorld.index(ID("entt"));
		FOREACH(vector,Entity*,e,ents)
			mWorld.remove(*e);
		mWorld.reindex();

		LoadSave().load("levels/edit.lv", &mWorld);
		mWorld.reindex();

		Entities &ents2 = mWorld.index(ID("entt"));
		FOREACH(vector,Entity*,e,ents2)
		{
			int x = (*e)->x() / 20;
			int y = (*e)->y() / 20;
			tile[x][y] = (*e);
		}
	}
	if (*mPlay)
	{
		LoadSave().save("levels/play.lv", &mWorld);
		PlayState ps(-1, "levels/play.lv");
		spawn(&ps);
		Tile::resetPresent();
	}
}

void EditorState::render(ALLEGRO_DISPLAY *)
{
	al_clear_to_color(al_map_rgb(120, 180, 255));
	for (int x = 0; x < 800; x += 20)
		al_draw_line(x, 0, x, 600, al_map_rgb(60, 100, 255), 1.0);
	for (int y = 0; y < 600; y += 20)
		al_draw_line(0, y, 800, y, al_map_rgb(60, 100, 255), 1.0);

	Entities &renders = mWorld.index(ID("rndr"));
	FOREACH(vector,Entity*,e,renders)
		(*e)->render();

	al_draw_textf(mFont, 5, 5, 0, "%s", palette[selected]->edString().c_str());
}

