/**
 * projectM -- Milkdrop-esque visualisation SDK
 * Copyright (C)2003-2008 projectM Team
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 * See 'LICENSE.txt' included within this release
 *
 */

#include "video_init.h"
#include <projectM.hpp>
#include "sdltoprojectM.h"
#include "ConfigFile.h"
#include "getConfigFilename.h"
#include <stdlib.h>

// FIXME: portable includes?
// i just added what works for me -fatray
#include <GL/gl.h>
#include <cassert>

projectM *globalPM= NULL;

// window stuff
int wvw, wvh, fvw, fvh;
bool fullscreen;

void renderLoop();

// texture test
bool doTextureTest = false;
void textureTest();

// memleak test
bool doMemleakTest = false;
int memLeakIterations = 100;

int main(int argc, char **argv) {

	// fix `fullscreen quit kills mouse` issue.
	atexit(SDL_Quit);

	std::string config_filename = getConfigFilename();
	ConfigFile config(config_filename);

	// window dimensions from configfile
	wvw = config.read<int>("Window Width", 512);
	wvh = config.read<int>("Window Height", 512);
	fullscreen = config.read("Fullscreen", false);

	init_display(wvw, wvh, &fvw, &fvh, fullscreen);

	SDL_WM_SetCaption(PROJECTM_TITLE, NULL);

	// memleak test
	while (doMemleakTest) {
		static int k = 0;
		std::cerr << "[iter " << k++ << "]" << std::endl;
		globalPM = new projectM(config_filename);
		assert(globalPM);
		delete (globalPM);
		if (k >= memLeakIterations)
			break;
	}

	globalPM = new projectM(config_filename);

	// if started fullscreen, give PM new viewport dimensions
	if (fullscreen)
		globalPM->projectM_resetGL(fvw, fvh);

	renderLoop();

	// not reached
	return 1;
}

float fakePCM[512];


void cleanup() {
  delete(globalPM);
  exit(0);
}


void renderLoop() {
	while (1) {
		projectMEvent evt;
		projectMKeycode key;
		projectMModifier mod;

		/** Process SDL events */
		SDL_Event event;
		while (SDL_PollEvent(&event)) {
			/** Translate into projectM codes and process */
			evt = sdl2pmEvent(event);
            key = sdl2pmKeycode(event.key.keysym.sym, event.key.keysym.mod);
			mod = sdl2pmModifier(event.key.keysym.mod);

			switch (evt) {
			case PROJECTM_KEYDOWN:
				switch (key) {
				case PROJECTM_K_ESCAPE:
					cleanup();
					break;
				case PROJECTM_K_f: {
					fullscreen = !fullscreen;
					if (fullscreen) {
						resize_display(fvw, fvh, fullscreen);
						globalPM->projectM_resetGL(fvw, fvh);
					} else {
						resize_display(wvw, wvh, fullscreen);
						globalPM->projectM_resetGL(wvw, wvh);
					}
					break;
				}
				case PROJECTM_K_q:
					cleanup();
					break;
				default:
					globalPM->key_handler(evt, key, mod);
				}
				break;

			case PROJECTM_VIDEORESIZE:
				wvw = event.resize.w;
				wvh = event.resize.h;
				resize_display(wvw, wvh, 0);
				globalPM->projectM_resetGL(wvw, wvh);
				break;

			default:
				// not for us, give it to projectM
				globalPM->key_handler(evt, key, mod);
				break;
			}
		}
 fakePCM[0]=0;
        for (int x = 1; x< 512;x++)
        {
                fakePCM[x] = fakePCM[x-1] + (rand()%200 - 100) *.002;
        }


        globalPM->pcm()->addPCMfloat(fakePCM, 512);





		globalPM->renderFrame();

		if (doTextureTest)
			textureTest();

		SDL_GL_SwapBuffers();
	}
}

void textureTest() {
	static int textureHandle = globalPM->initRenderToTexture();
	static int frame = 0;
	frame++;

	glClear(GL_COLOR_BUFFER_BIT);
	glClear(GL_DEPTH_BUFFER_BIT);

	glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);

	if (fullscreen)
		glViewport(0, 0, fvw, fvh);
	else
		glViewport(0, 0, wvw, wvh);

	glMatrixMode(GL_PROJECTION);
	glLoadIdentity();
	glFrustum(-1, 1, -1, 1, 2, 10);

	glEnable(GL_DEPTH_TEST);

	glMatrixMode(GL_MODELVIEW);
	glLoadIdentity();

	glTranslatef(cos(frame*0.023), cos(frame*0.017), -5+sin(frame*0.022)*2);
	glRotatef(sin(frame*0.0043)*360, sin(frame*0.0017)*360, sin(frame *0.0032)
			*360, 1);

	glEnable(GL_TEXTURE_2D);
	glMatrixMode(GL_TEXTURE);
	glLoadIdentity();

	glBindTexture(GL_TEXTURE_2D, textureHandle);
	glColor4d(1.0, 1.0, 1.0, 1.0);

	glBegin(GL_QUADS);
	glTexCoord2d(0, 1);
	glVertex3d(-0.8, 0.8, 0);
	glTexCoord2d(0, 0);
	glVertex3d(-0.8, -0.8, 0);
	glTexCoord2d(1, 0);
	glVertex3d(0.8, -0.8, 0);
	glTexCoord2d(1, 1);
	glVertex3d(0.8, 0.8, 0);
	glEnd();

	glDisable(GL_TEXTURE_2D);

	glMatrixMode(GL_MODELVIEW);
	glDisable(GL_DEPTH_TEST);
}
