#include "game/Level.h"

#include "constants/AdhesionConstants.h"

#include <math.h>
#include <string.h>

#include "utilities/JSONParser.h"

struct LevelWall LevelWall_fromJSON(JSONNode * node) {
	struct LevelWall wall;
	unsigned int nodeIndex;
	
	if (!strcmp("sticky", node->key)) {
		wall.type = WALL_TYPE_STICKY;
	} else if (!strcmp("exit", node->key)) {
		wall.type = WALL_TYPE_EXIT;
	} else if (!strcmp("bouncy", node->key)) {
		wall.type = WALL_TYPE_BOUNCY;
	} else if (!strcmp("deadly", node->key)) {
		wall.type = WALL_TYPE_DEADLY;
	} else {
		wall.type = WALL_TYPE_STICKY;
	}
	
	wall.vertexCount = 0;
	wall.vertices = malloc(sizeof(Vector2) * node->numberOfChildren);
	for (nodeIndex = 0; nodeIndex < node->numberOfChildren; nodeIndex++) {
		wall.vertices[nodeIndex] = Vector2_fromJSON(&node->children[nodeIndex]);
		wall.vertexCount++;
	}
	
	return wall;
}

Level * Level_fromJSON(JSONNode * node) {
	Level * self;
	unsigned int nodeIndex;
	
	if (node == NULL) {
		return NULL;
	}
	
	self = malloc(sizeof(Level));
	self->size = Vector2_withValues(NaN, NaN);
	self->center = Vector2_withValues(NaN, NaN);
	self->radius = NaN;
	self->startPosition = Vector2_withValues(NaN, NaN);
	self->wallCount = 0;
	self->walls = NULL;
	
	for (nodeIndex = 0; nodeIndex < node->numberOfChildren; nodeIndex++) {
		if (!strcmp("size", node->children[nodeIndex].key)) {
			self->size = Vector2_fromJSON(&node->children[nodeIndex]);
			
		} else if (!strcmp("center", node->children[nodeIndex].key)) {
			self->center = Vector2_fromJSON(&node->children[nodeIndex]);
			
		} else if (!strcmp("radius", node->children[nodeIndex].key)) {
			self->radius = node->children[nodeIndex].value.number;
			
		} else if (!strcmp("start_position", node->children[nodeIndex].key)) {
			self->startPosition = Vector2_fromJSON(&node->children[nodeIndex]);
			
		} else if (!strcmp("walls", node->children[nodeIndex].key)) {
			unsigned int wallIndex;
			
			self->walls = malloc(sizeof(struct LevelWall) * node->children[nodeIndex].numberOfChildren);
			for (wallIndex = 0; wallIndex < node->children[nodeIndex].numberOfChildren; wallIndex++) {
				self->walls[wallIndex] = LevelWall_fromJSON(&node->children[nodeIndex].children[wallIndex]);
				self->wallCount++;
			}
		}
	}
	
	if (isnan(self->size.x) || isnan(self->size.y) ||
	    isnan(self->center.x) || isnan(self->center.y) ||
	    isnan(self->radius) ||
	    isnan(self->startPosition.x) || isnan(self->startPosition.y) ||
	    self->wallCount == 0) {
		Level_dispose(self);
		return NULL;
	}
	
	return self;
}

void Level_dispose(Level * self) {
	unsigned int wallIndex;
	
	for (wallIndex = 0; wallIndex < self->wallCount; wallIndex++) {
		free(self->walls[wallIndex].vertices);
	}
	free(self->walls);
	free(self);
}
