
#include <SDL2/SDL.h>
#include <SDL2/SDL_audio.h>

#define GLEW_STATIC
#include <GL/glew.h>
#include <GLFW/glfw3.h>

#ifdef __EMSCRIPTEN__
#include <GLES2/gl2.h>
#include <emscripten.h>
#include <emscripten/html5.h>
#else
#include <OpenGL/gl3.h>
#endif

#include "spiel.hpp"
#include "meanbot15x15.xpm"

template<unsigned short SCRNW, unsigned short SCRNH, unsigned short FPS>
class SdlApi : public Api
{
	GLuint vertexBuffer, vertexArrayObject, shaderProgram;
	GLint positionAttribute, uvAttribute;
	GLint attribute_coord2d;
	GLuint program, vbo;
	SDL_GLContext gl_context;
	SDL_Window *window;
	SDL_Renderer *renderer;

	int ScrW()
	{
		// detect screen resize and scale accordingly
		return SCRNW*3;
	}

	int ScrH()
	{
		return SCRNH*3;
	}

	public:
	SdlApi()
	{
		SDL_Init(SDL_INIT_TIMER | SDL_INIT_VIDEO | SDL_INIT_AUDIO);// | SDL_OPENGL);

		SDL_CreateWindowAndRenderer(this->ScrW(), this->ScrH(), 0, &this->window, &this->renderer);

    		this->gl_context = SDL_GL_CreateContext(this->window);
		glClearColor(0.0, 0.0, 0.0, 0.0);
		glClear(GL_COLOR_BUFFER_BIT);
		SDL_GL_SwapWindow(this->window);
	}
	~SdlApi()
	{
		this->Gtfo();
	}

	void Delay(int delay)
	{
		#ifdef __EMSCRIPTEN__
		emscripten_sleep(delay);
		#else
		SDL_Delay(delay);
		#endif
	}

	bool Quit()
	{
		SDL_Event e;
		while( SDL_PollEvent( &e ) != 0 )
		{
		    //User requests quit
		    if( e.type == SDL_QUIT )
		    {
			    return true;
		    }
		}
		return false;
	}


	void Gtfo()
	{
		SDL_CloseAudio();
		#ifdef __EMSCRIPTEN__
		emscripten_cancel_main_loop();
		#else
		SDL_Quit();
		#endif
	}
	void Lock()
	{
		//if (SDL_MUSTLOCK(this->screen)) SDL_LockSurface(this->screen);
	}
	void Unlock()
	{
		//if (SDL_MUSTLOCK(this->screen)) SDL_UnlockSurface(this->screen);
	}
	void Refresh()
	{
		//SDL_Flip(this->screen);
	}
	Uint32 Color(Uint8 R, Uint8 G, Uint8 B)
	{
		return SDL_SetRenderDrawColor(this->renderer, R, G, B, 0xFF);
	}

	void Plot(Uint16 x, Uint16 y, Uint32 color)
	{
		if (SCRNW <= x) return;
		if (SCRNH <= y) return;
		Uint8 B = (color>>16) & 0xFF,
		      G = (color>>8) & 0xFF,
		      R = color & 0xFF;
		SDL_SetRenderDrawColor(this->renderer, R>>1, G>>1, B>>1, 0xFF);
		Uint16 xx = x*3,
		       yy = y*3;
		SDL_Rect rect = {.x = xx, .y = yy, .w = 2, .h = 2};
		SDL_RenderFillRect(this->renderer, &rect);

		// Render everything from a buffer to the actual screen.
		SDL_RenderPresent(this->renderer);
	}
};



extern "C" int main(int argc, char** argv) {
	printf("hello, world!\n");

	Api * api = new SdlApi<_SCRNW,_SCRNH,_FPS>();
	printf("B==D~~~\n");

	Cunt * cunts[] = {
		new MapRGB(),
		new DrawShit(),
		new EveryFrame(),
		0
	};
	//while(1) Continuation(cunts,api);
	while(1) Coroutine(cunts,api);

	return 0;
}

