#include "demo.h"

static GLuint rayVao, rayVbo;
extern const GLchar *raymarcher_1;
extern GLint raymarcher_1_len;
extern const GLchar *raymarcher_2;
extern GLint raymarcher_2_len;
extern const GLchar *trivial;
extern GLint trivial_len;

struct texture {
	GLuint id;
	char *filename;
};

enum { tex_checker, tex_noise, tex1, tex2, tex3, tex4 };
static struct texture textures[] = {
	[tex_checker] = { .filename = "checker.png", },
	[tex_noise] = { .filename = "noise.png", },
	[tex1] = { .filename = "tex1.jpg", },
	[tex2] = { .filename = "tex2.jpg", },
	[tex3] = { .filename = "tex3.jpg", },
	[tex4] = { .filename = "tex4.jpg", },
};

static struct shaderProgram raymarcher[] = {
	{
        .fragmentShadersrc = &raymarcher_1,
        .fragmentShadersize = &raymarcher_1_len,
	.vertexShadersrc = &trivial,
	.vertexShadersize = &trivial_len,
        .name = "raymarcher1",
	},
#if 0
	{
        .fragmentShadersrc = &raymarcher_2,
        .fragmentShadersize = &raymarcher_2_len,
	.vertexShadersrc = &trivial,
	.vertexShadersize = &trivial_len,
        .name = "raymarcher2",
	},
#endif
};

static struct textTexture texts[] = {
	{ .text = "  sooda   ", },
	{ .text = "  cyndis  ", },
	{ .text = "  R B B S ", },
	{ .text = "  Fulcrum ", },
	{ .text = "  C C C   ", },
	{ .text = "          ", },
	{ .text = "  Don't   ", },
	{ .text = " Forget:  ", },
	{ .text = " Drink more", },
	{ .text = " Club Mate", },
	{ .text = "          ", },
	{ .text = " First Demo", },
	{ .text = " 3D crap  ", },
	{ .text = " Stereo sound", },
	{ .text = " (No surround)", },
	{ .text = " Achievment ", },
	{ .text = " Unlocked  ", },
};

static float rectVertices[] = {
	-1.0f, 1.0f, 0.0f, 1.0f,
	 1.0f, 1.0f, 1.0f, 1.0f,
	 1.0f, -1.0f, 1.0f, 0.0f, 

	 1.0f, -1.0f, 1.0f, 0.0f,
	 -1.0f, -1.0f, 0.0f, 0.0f,
	 -1.0, 1.0f, 0.0f, 1.0f,
};

static struct attribute rectAttributes[] = {
        { .name = "position", .size = 2, .offset = 0},
        { .name = "texcoord", .size = 2, .offset = 2},
};

void setup_raymarcher(int width, int height)
{
	int i,j;

	for (i = 0; i < ARRAY_SIZE(textures); i++) {
		textures[i].id = create_texture_from_file(textures[i].filename, GL_REPEAT);
	}

	for (i = 0; i < ARRAY_SIZE(raymarcher); i++) {
        	setup_vertices(&rayVao, &rayVbo, rectVertices, sizeof(rectVertices));
		setup_shaders(&raymarcher[i]);
		setup_attributes(&raymarcher[i], rectAttributes, ARRAY_SIZE(rectAttributes), 4);
	}

	for (i = 0; i < ARRAY_SIZE(texts); i++) {
                texts[i].texID = render_text(texts[i].text, &texts[i].width,
                                         &texts[i].height, BIGFONT, GL_REPEAT);
	}

}	

void do_raymarcher(double ts, double base_ts)
{
	GLint uniTs;
	GLuint shader;
	int i;
	static int tex_sel = 0;
	static float beat_base = -1;
	GLint uni;

	if (beat_base < 0)
		beat_base = base_ts;

	if ((ts - beat_base) / 1000 > (60 / 147.0)) {
		tex_sel++;
		beat_base = ts;
	}

	shader = raymarcher[0].shaderProgram;
	glUseProgram(shader);
	switch (tex_sel % 2) {
	case 0:
		glActiveTexture(GL_TEXTURE0);
		glBindTexture(GL_TEXTURE_2D, textures[tex3].id);
		uni = glGetUniformLocation(shader, "texObject");
		glUniform1i(uni, 0);
		uni = glGetUniformLocation(shader, "texFloor");
		glUniform1i(uni, 0);
		break;
	case 1:
		glActiveTexture(GL_TEXTURE0);
		glBindTexture(GL_TEXTURE_2D, textures[tex_noise].id);
		uni = glGetUniformLocation(shader, "texObject");
		glUniform1i(uni, 0);
		uni = glGetUniformLocation(shader, "texFloor");
		glUniform1i(uni, 0);
		break;
	}
	glActiveTexture(GL_TEXTURE1);
	glBindTexture(GL_TEXTURE_2D, texts[(tex_sel / 4) % ARRAY_SIZE(texts)].texID);
	uni = glGetUniformLocation(shader, "texObject2");
	glUniform1i(uni, 1);

	uniTs = glGetUniformLocation(shader, "now");
	glUniform1f(uniTs, (float)ts);

	glBindVertexArray(rayVao); 

	glBindFramebuffer(GL_FRAMEBUFFER, 0);
	glClearColor(0, 0, 0, 1.0f);
	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

	glDrawArrays(GL_TRIANGLES, 0, 6);

}

