/*
 * Copyright 2014 The Emscripten Authors.  All rights reserved.
 * Emscripten is available under two separate licenses, the MIT license and the
 * University of Illinois/NCSA Open Source License.  Both these licenses can be
 * found in the LICENSE file.
 */

// Built from glbook/hello triange and sdl_ogl, see details there

#include "SDL/SDL.h"
#include "SDL/SDL_image.h"
#include "SDL/SDL_opengl.h"

#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include <string.h>

GLuint programObject;
int width = 512;
int height = 256;

GLuint LoadShader ( GLenum type, const char *shaderSrc )
{
   GLuint shader;
   GLint compiled;
   
   shader = glCreateShader ( type );
   if ( shader == 0 )
   	return 0;

   glShaderSource ( shader, 1, &shaderSrc, NULL );
   glCompileShader ( shader );
   glGetShaderiv ( shader, GL_COMPILE_STATUS, &compiled );
   if ( !compiled ) 
   {
      GLint infoLen = 0;
      glGetShaderiv ( shader, GL_INFO_LOG_LENGTH, &infoLen );
      if ( infoLen > 1 )
      {
         char* infoLog = malloc (sizeof(char) * infoLen );
         glGetShaderInfoLog ( shader, infoLen, NULL, infoLog );
         printf ( "Error compiling shader:\n%s\n", infoLog );            
         free ( infoLog );
      }
      glDeleteShader ( shader );
      return 0;
   }
   return shader;
}

int Init ()
{
   GLbyte vShaderStr[] =  
      "attribute vec4 vPosition;    \n"
      "void main()                  \n"
      "{                            \n"
      "   gl_Position = vPosition;  \n"
      "}                            \n";
   
   GLbyte fShaderStr[] =  
      "precision mediump float;\n"\
      "void main()                                  \n"
      "{                                            \n"
      "  gl_FragColor = vec4 ( 0.0, 0.0, 1.0, 1.0 );\n"
      "}                                            \n";

   GLuint vertexShader;
   GLuint fragmentShader;
   GLint linked;

   vertexShader = LoadShader ( GL_VERTEX_SHADER, (const char *)vShaderStr );
   fragmentShader = LoadShader ( GL_FRAGMENT_SHADER, (const char *)fShaderStr );

   programObject = glCreateProgram ( );
   if ( programObject == 0 )
      return 0;

   glAttachShader ( programObject, vertexShader );
   glAttachShader ( programObject, fragmentShader );
   glBindAttribLocation ( programObject, 0, "vPosition" );
   glLinkProgram ( programObject );
   glGetProgramiv ( programObject, GL_LINK_STATUS, &linked );
   if ( !linked ) 
   {
      GLint infoLen = 0;
      glGetProgramiv ( programObject, GL_INFO_LOG_LENGTH, &infoLen );
      if ( infoLen > 1 )
      {
         char* infoLog = malloc (sizeof(char) * infoLen );
         glGetProgramInfoLog ( programObject, infoLen, NULL, infoLog );
         printf ( "Error linking program:\n%s\n", infoLog );            
         free ( infoLog );
      }
      glDeleteProgram ( programObject );
      return GL_FALSE;
   }

   glClearColor ( 0.0f, 0.0f, 0.0f, 0.0f );
   return GL_TRUE;
}

///
// Draw a triangle using the shader pair created in Init()
//
void Draw ()
{
   void *buffer;
   GLfloat vVertices[] = {  0.0f,  0.5f, 0.0f, 
                           -0.5f, -0.5f, 0.0f,
                            0.5f, -0.5f, 0.0f };

   // No clientside arrays, so do this in a webgl-friendly manner
   GLuint vertexPosObject;
   glGenBuffers(1, &vertexPosObject);
   glBindBuffer(GL_ARRAY_BUFFER, vertexPosObject);
   glBufferData(GL_ARRAY_BUFFER, sizeof(vVertices), NULL, GL_STATIC_DRAW);
   buffer = glMapBufferRange(
     GL_ARRAY_BUFFER,
     0,
     sizeof(vVertices),
     GL_MAP_FLUSH_EXPLICIT_BIT | GL_MAP_INVALIDATE_BUFFER_BIT | GL_MAP_WRITE_BIT
   );
   if (buffer == NULL) {
     fprintf(stderr, "Could not map buffer: %x\n", glGetError());
     exit(1);
   }
   memcpy(buffer, vVertices, sizeof(vVertices));
   glFlushMappedBufferRange(GL_ARRAY_BUFFER, 0, sizeof(vVertices));
   glUnmapBuffer(GL_ARRAY_BUFFER);
   
   glViewport ( 0, 0, width, height );
   glClear ( GL_COLOR_BUFFER_BIT );
   glUseProgram ( programObject );

   glBindBuffer(GL_ARRAY_BUFFER, vertexPosObject);
   glVertexAttribPointer(0 /* ? */, 3, GL_FLOAT, 0, 0, 0);
   glEnableVertexAttribArray(0);

   glDrawArrays ( GL_TRIANGLES, 0, 3 );
}

void Verify() {
  unsigned char *data = malloc(width*height*4 + 16);
  int *last = (int*)(data + width*height*4 - 4);
  int *after = (int*)(data + width*height*4);
  *last = 0xdeadbeef;
  *after = 0x12345678;
  glReadPixels(0, 0, width, height, GL_RGBA, GL_UNSIGNED_BYTE, data);
  assert(*last != 0xdeadbeef); // should overwrite the buffer to the end
  assert(*after == 0x12345678); // nothing should be written afterwards!
  // Should see some blue, and nothing else
  int seen = 0;
  int ok = 1;
  for (int x = 0; x < width*height; x++) {
    seen = seen || data[x*4+2] != 0;
    ok = ok && (data[x*4+0] == 0);
    ok = ok && (data[x*4+1] == 0);
  }
  int result = seen && ok;
  REPORT_RESULT(result);
}

int main(int argc, char *argv[])
{
  SDL_Surface *screen;
  if ( SDL_Init(SDL_INIT_VIDEO) != 0 ) {
    printf("Unable to initialize SDL: %s\n", SDL_GetError());
    return 1;
  }

  screen = SDL_SetVideoMode(width, height, 32, SDL_OPENGL);
  if (!screen) {
    printf("Unable to set video mode: %s\n", SDL_GetError());
    return 1;
  }

  Init();
  Draw();
  Verify();

  return 0;
}

