#include "level.h"

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

Level::Level()
{
	m_width = 0;
	m_height = 0;
	m_field = NULL;
	m_values = NULL;
	m_conditions = NULL;
}

Level::~Level()
{
	if(m_field)
	{
		for(int i = 0; i < m_width; i++)
			free(m_field[i]);
		free(m_field);
	}
	if(m_values)
	{
		for(int i = 0; i < m_width; i++)
			free(m_values[i]);
		free(m_values);
	}
	if(m_conditions)
	{
		for(int i = 0; i < m_width; i++)
			free(m_conditions[i]);
		free(m_conditions);
	}
}

bool Level::loadLevel(const char *levelfile)
{
	FILE *f;
	char buf[256];
	char *token;
	int i, j;

	f = fopen(levelfile, "r");
	if(!f) return false;

	fgets(buf, sizeof(buf), f);
	buf[strlen(buf) - 1] = 0;
	m_width = atoi(buf);
	fgets(buf, sizeof(buf), f);
	buf[strlen(buf) - 1] = 0;
	m_height = atoi(buf);

	m_field = (int**)malloc(sizeof(int*) * m_width);
	for(i = 0; i < m_width; i++)
	{
		m_field[i] = (int*)malloc(sizeof(int) * m_height);
		for(j = 0; j < m_height; j++)
			m_field[i][j] = invalid;
	}
	m_values = (int**)malloc(sizeof(int*) * m_width);
	for(i = 0; i < m_width; i++)
	{
		m_values[i] = (int*)malloc(sizeof(int) * m_height);
		for(j = 0; j < m_height; j++)
			m_values[i][j] = 0;
	}
	m_conditions = (int**)malloc(sizeof(int*) * m_width);
	for(i = 0; i < m_width; i++)
	{
		m_conditions[i] = (int*)malloc(sizeof(int) * m_height);
		for(j = 0; j < m_height; j++)
			m_conditions[i][j] = 0;
	}

	j = 0;
	while(fgets(buf, sizeof(buf), f))
	{
		buf[strlen(buf) - 1] = 0;
		token = strtok(buf, " ");
		i = 0;
		while(token)
		{
			if((i >= 0) && (j >= 0) && (i < m_width) && (j < m_height))
				m_field[i][j] = atoi(token);
			token = strtok(NULL, " ");
			i++;
		}
		j++;
	}

	fclose(f);
	return true;
}

void Level::setTile(int x, int y, int tiletype)
{
	if(!m_field) return;
	if((x < 0) || (y < 0) || (x >= m_width) || (y >= m_height)) return;
	m_field[x][y] = tiletype;
}

int Level::tile(int x, int y)
{
	if(!m_field) return invalid;
	if((x < 0) || (y < 0) || (x >= m_width) || (y >= m_height)) return invalid;
	return m_field[x][y];
}

int Level::width()
{
	return m_width;
}

int Level::height()
{
	return m_height;
}

int Level::value(int x, int y)
{
	if(!m_values) return 1;
	if((x < 0) || (y < 0) || (x >= m_width) || (y >= m_height)) return 1;
	return m_values[x][y];
}

void Level::addValue(int x, int y, int value)
{
	if(!m_values) return;
	if((x < 0) || (y < 0) || (x >= m_width) || (y >= m_height)) return;

	m_values[x][y] += value;
}

void Level::clearValues()
{
	if(!m_values) return;

	for(int j = 0; j < m_height; j++)
		for(int i = 0; i < m_width; i++)
			m_values[i][j] = 0;
}

void Level::setCondition(int x, int y, int cond)
{
	if(!m_conditions) return;
	if((x < 0) || (y < 0) || (x >= m_width) || (y >= m_height)) return;
	m_conditions[x][y] = cond;
}

int Level::condition(int x, int y)
{
	if(!m_conditions) return 0;
	if((x < 0) || (y < 0) || (x >= m_width) || (y >= m_height)) return 0;
	return m_conditions[x][y];
}

