/* Universidade Federal Fluminense
 * Programa de Pós-Graduação em Computação
 *
 * Tópicos Avançados em Computação Visual e Interfaces II (Técnicas Avançadas de Rendering)
 * Professor: Leandro Augusto Frata Fernandes
 *
 * Version: 2012.05.05-001
 */

#include "basic_io.h"
#include <IL/il.h>
#include <IL/ilu.h>
#include <iostream>

void* loadImageFromFile(const char* filename, GLsizei& width, GLsizei& height, GLenum& format, GLenum& type) {
	ilInit();
	iluInit();

	ilEnable(IL_ORIGIN_SET);
	ilOriginFunc(IL_ORIGIN_LOWER_LEFT);

	ILuint image = ilGenImage();

	ilBindImage(image);

	if (ilLoad(IL_TYPE_UNKNOWN, filename) == IL_FALSE) {
		throw std::exception(iluErrorString(ilGetError()));
	}

	ILint size = ilGetInteger(IL_IMAGE_SIZE_OF_DATA);

	void* data;
	if (!(data = (char*)malloc(size * sizeof(char)))) {
		char msg[1024];
		sprintf(msg, "Can't alloc space for '%s'.", filename);

		throw std::exception(msg);
	}

	memcpy(data, ilGetData(), size);

	width = ilGetInteger(IL_IMAGE_WIDTH);
	height = ilGetInteger(IL_IMAGE_HEIGHT);
	format = ilGetInteger(IL_IMAGE_FORMAT);
	type = ilGetInteger(IL_IMAGE_TYPE);

	ilDeleteImage(image);

	ilShutDown();

	return data;
}

char* loadShaderFromFile(const char* filename) {
	FILE* file;
 
	if (!(file = fopen(filename, "r"))) {
		char msg[1024];
		sprintf(msg, "Can't open file '%s' for reading.", filename);

		throw std::exception(msg);
	}
 
	fseek(file, 0, SEEK_END);
	long size = ftell(file);
 
	fseek(file, 0, SEEK_SET);
 
	char* shader;
	if (!(shader = (char*)malloc(size * sizeof(char)))) {
		char msg[1024];
		sprintf(msg, "Can't alloc space for '%s'.", filename);

		throw std::exception(msg);
	}
 
	size = fread(shader, sizeof(char), size, file);
 	shader[size-1] = '\0'; // Shader sources have to term with null.
 
	fclose(file);
 
	return shader;
}

void writeImageToFile(const char* filename, const GLsizei width, const GLsizei height, const GLubyte components, const GLenum format, const GLenum type, const GLvoid* pixels) {
	ilInit();
	iluInit();

	ilEnable(IL_FILE_OVERWRITE);
	ilEnable(IL_ORIGIN_SET);
	ilOriginFunc(IL_ORIGIN_LOWER_LEFT);

	ILuint image = ilGenImage();

	ilBindImage(image);
	ilTexImage(width, height, 0, components, format, type, (void*)pixels);
	ilSaveImage(filename);

	ilDeleteImage(image);

	ilShutDown();
}
