Revision 1 (by (no author), 2006/09/28 22:53:53) Initial import
/// \file boardmanager.cpp
/// Main source file for main game screen manager

#include <allegro.h>
#include <string>
#include <fstream>
#include <sstream>
#include "boardmanager.h"
#include "core.h"

extern "C" {
#include <lualib.h>
#include <lauxlib.h>
}

using namespace std;

static int l_inherits(lua_State* state)
{
	lua_pushnil(state);
	while(lua_next(state, 2) != 0)
	{
		lua_pushvalue(state, -2);
		lua_gettable(state, 1);
		if(lua_isnil(state, -1))
		{
			lua_pop(state, 1);
			lua_pushvalue(state, -2);
			lua_insert(state, -2);
			lua_settable(state, 1);
		}
		else
			lua_pop(state, 2);
	}
	return 0;
}

BoardManager::BoardManager()
{
	state = lua_open();
	
	turn = 0;
	
	ConstructBoard();
	
	ConstructLuaTable();
	LoadObject("core.lua");
	LoadObjects("scripts");
	LoadObject("game.lua");
}

BoardManager::~BoardManager()
{
	lua_gc(state, LUA_GCCOLLECT, 0);
	lua_close(state);
		
	delete [] spaces;
}

Board::Pawn* BoardManager::Advance()
{
	return NULL;
}

void BoardManager::ConstructBoard()
{
	spaces = new Space [Width * Height];
	
	for(int y = 0; y < Height; y++)
	{
		for(int x = 0; x < Width; x++)
		{
			if(y < Height / 3)
				spaces[x + y * Width].red_control = 100;
			else
				spaces[x + y * Width].red_control = 0;
			if(y >= Height * 2 / 3)
				spaces[x + y * Width].blue_control = 100;
			else
				spaces[x + y * Width].blue_control = 0;
		}
	}
	
	RecalculateStatus();
}

void BoardManager::ConstructLuaTable()
{
	int (BoardManager::*func)();
	void* data;
	int idx;
	
	luaopen_base(state);
	lua_register(state, "inherits", l_inherits);
	
	lua_pushlightuserdata(state, this);
	lua_setfield(state, LUA_REGISTRYINDEX, "bm");
	
	Board::RegisterAll(state);
	board = Board::Board::CreateInstance(state);
}

/*void BoardManager::Deal(Player& player)
{
	for(list<Card>::iterator i = cards.begin(); i != cards.end(); i++)
	{
		player.hand.push_back(&*i);
	}
}*/

void BoardManager::RecalculateStatus()
{
	for(int y = 0; y < Height; y++)
	{
		for(int x = 0; x < Width; x++)
		{
			Space& space = spaces[y * Width + x];
			space.status = 0;
			if(space.red_control >= 100)
				space.status |= 1;
			if(space.blue_control >= 100)
				space.status |= 2;
		}
	}
}

void BoardManager::LoadObjects(const char* path)
{
	al_ffblk info;
	string pattern = path;
	pattern += "/*.lua";
	
	if(al_findfirst(pattern.c_str(), &info, 0) != 0)
		return;
		
	do {
		string fullname = path;
		fullname += "/";
		fullname += info.name;
		
		LoadObject(fullname.c_str());
	} while(al_findnext(&info) == 0);

	al_findclose(&info);
}

bool BoardManager::LoadObject(const char* filename)
{
	ifstream file(filename);
	stringstream data;
	
	if(!file.good())
	{
		//Write(string("Failed to open file ") + filename);
	}
	else
	{
		while(1)
		{
			char c = file.get();
			if(!file.good())
				break;
			data.put(c);
		}
		LoadObject(filename, data.str().c_str());
	}
}

bool BoardManager::LoadObject(const char* file, const char* data)
{
	if(luaL_loadbuffer(state, data, strlen(data), file) != 0 || lua_pcall(state, 0, 0, 0) != 0)
	{
		stringstream msg;
		msg << "Failed to load " << file;
		board->Write(msg.str());
		msg.str("");
		
		if(!lua_isnil(state, -1))
		{
			const char *str = lua_tostring(state, -1);
			if(str == NULL)
				str = "(error object is not a string)";
			msg << str;
			board->Write(msg.str());
			lua_pop(state, 1);
		}
	}
}

/*int BoardManager::AddCard()
{
	if(lua_gettop(state) != 5)
	{
		lua_pushstring(state, "wrong number of arguments");
		return lua_error(state);
	}
	
	cards.push_back(Card());
	Card& card = cards.back();
	card.name = lua_tostring(state, 2);
	card.graphic = lua_tointeger(state, 3);
	card.level = lua_tointeger(state, 4);
	
	lua_getfield(state, LUA_REGISTRYINDEX, "registered_cards");
	
	lua_pushvalue(state, 5);
	lua_setfield(state, -2, card.name.c_str());
	
	lua_pop(state, 6);
	
	return 0;
}

int BoardManager::Console()
{
	int n = lua_gettop(state);
	ostringstream msg;
	
	for(int i = 2; i <= n; i++)
	{
		if(lua_tostring(state, i))
			msg << lua_tostring(state, i);
		else
			msg << lua_typename(state, lua_type(state, i));
	}
	
	Write(msg.str());
}*/

// The end