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

//#define GL_API
//#define GL_APIENTRY

#undef ANDROID
#include <EGL/egl.h>
#include <GLES/gl.h>

#undef HAVE_MALLOC_H
#include <SDL.h>
#include <SDL_syswm.h>


#define WINDOW_WIDTH    500
#define WINDOW_HEIGHT   500

#define TEX_WIDTH 256
#define TEX_HEIGHT 256


#define F_to_X(d) ((d) > 32767.65535 ? 32767 * 65536 + 65535 :  \
               (d) < -32768.65535 ? -32768 * 65536 + 65535 : \
               ((GLfixed) ((d) * 65536)))
#define X_to_F(x)  ((float)(x))/65536.0f

static EGLint const attribute_list[] = {
    EGL_RED_SIZE, 1,
    EGL_GREEN_SIZE, 1,
    EGL_BLUE_SIZE, 1,
    EGL_NONE
};

unsigned char *genTexture(int width, int height, int comp)
{
    unsigned char *img = new unsigned char[width * height * comp];
    unsigned char *ptr = img;
    for (int i = 0; i < height; i++) {
        for (int j = 0; j < width; j++) {
            unsigned char col = ((i / 8 + j / 8) % 2) * 255 ;
            for (int c = 0; c < comp; c++) {
                *ptr = col; ptr++;
            }
        }
    }
    return img;
}

unsigned char *genRedTexture(int width, int height, int comp)
{
    unsigned char *img = new unsigned char[width * height * comp];
        memset(img,0,width*height*comp);
    unsigned char *ptr = img;
    for (int i = 0; i < height; i++) {
        for (int j = 0; j < width; j++) {
            unsigned char col = ((i / 8 + j / 8) % 2) * 255 ;
                        *ptr = col;
                         ptr+=comp;
        }
    }
    return img;
}

//mip 0;
unsigned char *genPalette4_rgb8(int width, int height,int color)
{
        int size = width*height/2 + 16*3/*palette size*/;
    unsigned char *img = new unsigned char[size];

        memset(img,0,size);
        img[0] = 255; img[1] = 0; img[2] = 0;     // red
        img[3] = 0; img[4] = 0; img[5] = 255;    //blue
        img[7] = 128; img[8] = 0; img[9] = 128;  //fucsia
        //rest of the palette is empty

    unsigned char *ptr = img+(16*3);
    for (int i = 0; i < (height*width/2); i++) {
             ptr[i] = (i%2)?0x0|color:0x11|color;
    }
    return img;
}

void usage(const char *progname)
{
    fprintf(stderr, "usage: %s [-n <nframes> -i -h]\n", progname);
    fprintf(stderr, "\t-h: this message\n");
    fprintf(stderr, "\t-i: immidate mode\n");
    fprintf(stderr, "\t-n nframes: generate nframes\n");
    fprintf(stderr, "\t-e: use index arrays\n");
    fprintf(stderr, "\t-t: use texture\n");
    fprintf(stderr, "\t-f: use fixed points\n");
    fprintf(stderr, "\t-p: use point size OES extention\n");
}

#ifdef _WIN32
int WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nShowCmd)
#else
int main(int argc, char **argv)
#endif
{
    GLuint  ui32Vbo = 0; // Vertex buffer object handle
    GLuint  ui32IndexVbo;
    GLuint  ui32Texture;

    int nframes = 100;
    bool immidateMode     = true;
    bool useIndices       = false;
    bool useTexture       = false;
    bool useCompTexture   = false;
    bool useFixed         = false;
    bool usePoints        = true;
    bool useCopy          = false;
    bool useSubCopy       = false;

    int c;
    extern char *optarg;

    #ifdef _WIN32
        HWND   windowId = NULL;
    #else
        Window windowId = NULL;
    #endif

        //      // Inialize SDL window
        //
        if (SDL_Init(SDL_INIT_NOPARACHUTE | SDL_INIT_VIDEO)) {
            fprintf(stderr,"SDL init failed: %s\n", SDL_GetError());
            return -1;
        }

        SDL_Surface *surface = SDL_SetVideoMode(WINDOW_WIDTH,WINDOW_HEIGHT, 32, SDL_HWSURFACE);
        if (surface == NULL) {
            fprintf(stderr,"Failed to set video mode: %s\n", SDL_GetError());
            return -1;
        }

        SDL_SysWMinfo  wminfo;
        memset(&wminfo, 0, sizeof(wminfo));
        SDL_GetWMInfo(&wminfo);
    #ifdef _WIN32
        windowId = wminfo.window;
    #else
        windowId = wminfo.info.x11.window;
    #endif

        int major,minor,num_config;
        EGLConfig configs[150];
        EGLSurface egl_surface;
        EGLContext ctx;
        EGLDisplay d = eglGetDisplay(EGL_DEFAULT_DISPLAY);
        eglInitialize(d,&major,&minor);
        printf("DISPLAY == %p major =%d minor = %d\n",d,major,minor);
        eglChooseConfig(d, attribute_list, configs, 150, &num_config);
        printf("config returned %d\n",num_config);
        egl_surface = eglCreateWindowSurface(d,configs[0],windowId,NULL);
        ctx = eglCreateContext(d,configs[0],EGL_NO_CONTEXT,NULL);
        printf("SURFACE == %p CONTEXT == %p\n",egl_surface,ctx);
        if(eglMakeCurrent(d,egl_surface,egl_surface,ctx)!= EGL_TRUE){
            printf("make current failed\n");
            return false;
        }
        printf("after make current\n");

        GLenum err = glGetError();
        if(err != GL_NO_ERROR) {
        printf("error before drawing ->>> %d  \n",err);
        } else {
        printf("no error before drawing\n");
        }

    if (useTexture) {

        glEnable(GL_TEXTURE_2D);
        ui32Texture = 1;
        glBindTexture(GL_TEXTURE_2D, ui32Texture);
                GLenum err = glGetError();

        unsigned char *pixels = NULL;
                if(useCompTexture) {
                        pixels = genPalette4_rgb8(TEX_WIDTH,TEX_HEIGHT,3);
                        glCompressedTexImage2D(GL_TEXTURE_2D,0,GL_PALETTE4_RGB8_OES,TEX_WIDTH,TEX_HEIGHT,0,3*16+TEX_WIDTH*TEX_HEIGHT/2,pixels);

                } else {
                        pixels = genTexture(TEX_WIDTH, TEX_HEIGHT, 4);
            glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, TEX_WIDTH, TEX_HEIGHT, 0, GL_RGBA, GL_UNSIGNED_BYTE, pixels);
                }

        delete pixels;

                err = glGetError();
                if(err != GL_NO_ERROR)
            printf("error %d after image \n",err);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
                err = glGetError();
                if(err != GL_NO_ERROR)
            printf("error after min filter \n");
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
                err = glGetError();
                if(err != GL_NO_ERROR)
            printf("error after mag filter \n");
        glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
                err = glGetError();
                if(err != GL_NO_ERROR)
            printf("error after env mode \n");

                if(useCompTexture) {
                    pixels = genPalette4_rgb8(TEX_WIDTH,TEX_HEIGHT,1);
                    glCompressedTexSubImage2D(GL_TEXTURE_2D,0,TEX_WIDTH/4,TEX_HEIGHT/4,TEX_WIDTH/8,TEX_HEIGHT/8,GL_PALETTE4_RGB8_OES,3*16+(TEX_WIDTH*TEX_HEIGHT/128),pixels);
                } else {
            pixels = genRedTexture(TEX_WIDTH/8, TEX_HEIGHT/8, 4);
                    glTexSubImage2D(GL_TEXTURE_2D,0,TEX_WIDTH/4,TEX_HEIGHT/4,TEX_WIDTH/8,TEX_HEIGHT/8,GL_RGBA,GL_UNSIGNED_BYTE,pixels);
                }
                 err = glGetError();
                if(err != GL_NO_ERROR)
            printf("error %d after subimage \n",err);
        delete pixels;

    }

    glClearColor(0.6f, 0.8f, 1.0f, 1.0f); // clear blue

    float afVertices[] = {  -0.4f,-0.4f,0.0f, // Position
                 1.0f,0.0f,0.0f,1.0f, // Color
                 0.0f, 0.0f, // texture
                 12.f, //point size

                 0.4f,-0.4f,0.0f,
                 0.0f,1.0f,0.0f,1.0f,
                 1.0f, 0.0f,
                 47.0f,

                 0.0f,0.4f,0.0f,
                 0.0f,0.0f,1.0f,1.0f,
                 0.5f, 1.0f,
                 14.0f
    };

    GLfixed fixedVertices[] = { F_to_X(-0.4f),F_to_X(-0.4f),F_to_X(0.0f), // Position
                    F_to_X(1.0f),F_to_X(0.0f),F_to_X(0.0f),F_to_X(1.0f), // Color
                    F_to_X(0.0f),F_to_X(0.0f), // texture
                    F_to_X(12.0f),//points size

                    F_to_X(0.4f),F_to_X(-0.4f),F_to_X(0.0f),
                    F_to_X(0.0f),F_to_X(1.0f),F_to_X(0.0f),F_to_X(1.0f),
                    F_to_X(1.0f),F_to_X( 0.0f),
                    F_to_X(30.0f),

                    F_to_X(0.0f),F_to_X(0.4f),F_to_X(0.0f),
                    F_to_X(0.0f),F_to_X(0.0f),F_to_X(1.0f),F_to_X(1.0f),
                    F_to_X(0.5f), F_to_X(1.0f),
                    F_to_X(30.0)
    };

    unsigned short indices[] = { 2, 1, 0 };

    if (!immidateMode) {
        glGenBuffers(1, &ui32Vbo);
        ui32Vbo = 1;
         printf("ui32Vbo = %d\n", ui32Vbo);

        glBindBuffer(GL_ARRAY_BUFFER, ui32Vbo);
        unsigned int uiSize = 3 * (sizeof(float) * 10);
        glBufferData(GL_ARRAY_BUFFER, uiSize, useFixed?(void *)fixedVertices:(void*)afVertices, GL_STATIC_DRAW);

        ui32IndexVbo = 2;
        glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ui32IndexVbo);
        glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices, GL_STATIC_DRAW);
    }

    // Draws a triangle for 800 frames
    float angle = 0.0;
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();

    GLvoid* arr = NULL;
    GLenum  type;
    GLenum  drawType;
    int     size_of;

    if(useFixed)
    {
        arr = fixedVertices;
        type = GL_FIXED;
        size_of = sizeof(GLfixed);
    }
    else
    {
        arr = afVertices;
        type = GL_FLOAT;
        size_of = sizeof(float);
    }

    if(usePoints)
    {
        drawType = GL_POINTS;
    }
    else
        drawType = GL_TRIANGLES;

    for (int i = 0; i < 10000; i++) {

        glClear(GL_COLOR_BUFFER_BIT);
        glPushMatrix();
        glRotatef(angle, 0.0, 0.0, 1.0);
        angle += 360.0 / nframes;
        // Enable vertex arrays
        glEnableClientState(GL_VERTEX_ARRAY);
        if (immidateMode) {
            glVertexPointer(3,type, size_of * 10, arr);
        } else {
            glVertexPointer(3,type, size_of * 10, 0);
        }

        // Set color data in the same way
        glEnableClientState(GL_COLOR_ARRAY);
        if (immidateMode) {
            glColorPointer(4, type, size_of * 10, useFixed?(GLvoid*)(fixedVertices+3):(GLvoid*)(afVertices+3));
        } else {
            glColorPointer(4,type,size_of * 10, (GLvoid*) (size_of * 3) );
        }
        if (useTexture) {
            glEnableClientState(GL_TEXTURE_COORD_ARRAY);
            if (immidateMode) {
                glTexCoordPointer(2, type, size_of * 10, useFixed?(GLvoid*)(fixedVertices + 7):(GLvoid*)(afVertices+7));
            } else {
                glTexCoordPointer(2, type, size_of * 10, (GLvoid*)(size_of * 7));
            }
        }
        if(usePoints)
        {
            glEnableClientState(GL_POINT_SIZE_ARRAY_OES);
            if (immidateMode) {
                glPointSizePointerOES(type,size_of * 10,useFixed?(GLvoid*)(fixedVertices + 9):(GLvoid*)(afVertices+9));
                        } else {
                glPointSizePointerOES(type,size_of * 10,(GLvoid*)(size_of * 9));
                        }
        }

        if (useIndices) {
            if (immidateMode) {
                glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
                glDrawElements(drawType, 3, GL_UNSIGNED_SHORT, indices);
            } else {
                glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ui32IndexVbo);
                glDrawElements(drawType, 3, GL_UNSIGNED_SHORT, 0);
            }
        } else {
            glDrawArrays(drawType, 0, 3);
        }

                GLenum err = glGetError();
                if(err != GL_NO_ERROR)
            printf(" error %d has occured while drawing\n",err);


        glPopMatrix();
                eglSwapBuffers(d,egl_surface);

                if(useTexture && useCopy)
                    glCopyTexImage2D(GL_TEXTURE_2D,0,GL_RGBA,0,0,256,256,0);
                else if(useTexture && useSubCopy)
                    glCopyTexSubImage2D(GL_TEXTURE_2D,0,100,100,WINDOW_WIDTH/2,WINDOW_HEIGHT/2,50,50);
    }
                err = glGetError();
                if(err != GL_NO_ERROR)
            printf("error ->>> %d  \n",err);
        eglDestroySurface(d,egl_surface);
        eglDestroyContext(d,ctx);

// Just wait until the window is closed
        SDL_Event ev;
        while( SDL_WaitEvent(&ev) ) {
            if (ev.type == SDL_QUIT) {
                break;
            }
        }
    return 0;
}


