#include <GLES2/gl2.h>
#include <EGL/egl.h>
#include <gf/gf3d.h>
#include <gf/gf.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>


gf_dev_t    gfdev;
gf_layer_t  layer;
int         layer_idx;

static EGLDisplay eglDisplay;
static EGLConfig eglConfig;
static EGLSurface eglSurface;


int main(int argc, char** argv)
{
	gf_3d_target_t      target;
	gf_display_t        gf_disp;
	EGLConfig           config;
	EGLContext          econtext;
	EGLint              num_config;
	gf_dev_info_t       info;
	//gf_layer_info_t     linfo;
	gf_display_info_t   disp_info;
	GLuint              width, height;

	int layer_index = 0;

	EGLint attribs[] = {
			EGL_NATIVE_VISUAL_ID, 0,
			EGL_RED_SIZE,	5,
			EGL_GREEN_SIZE,	5,
			EGL_BLUE_SIZE,	5,
			EGL_DEPTH_SIZE, 16,
			EGL_SURFACE_TYPE, EGL_WINDOW_BIT,
			EGL_LEVEL, layer_index,
			EGL_RENDERABLE_TYPE, EGL_OPENGL_ES_BIT,
			EGL_NONE
	};

	/* initialize the graphics device */
	if (gf_dev_attach(&gfdev, NULL, &info)!=GF_ERR_OK)
	{
	  perror("gf_dev_attach()");
	  return -1;
	}

	/* Setup the layer we will use */
	if (gf_display_attach(&gf_disp, gfdev, 0, &disp_info)!=GF_ERR_OK)
	{
	  fprintf(stderr, "gf_display_attach() failed\n");
	  return -1;
	}

	layer_idx=disp_info.main_layer_index;

	/* get an EGL display connection */
	eglDisplay=eglGetDisplay(gfdev);
	//eglDisplay=eglGetDisplay(EGL_DEFAULT_DISPLAY);

	if (eglDisplay==EGL_NO_DISPLAY)
	{
	  fprintf(stderr, "eglGetDisplay() failed\n");
	  return -1;
	}

	width=disp_info.xres;
	height=disp_info.yres;


	if (gf_layer_attach(&layer, gf_disp, layer_idx, GF_LAYER_ATTACH_PASSIVE)!=GF_ERR_OK)
	{
	  fprintf(stderr, "gf_layer_attach() failed\n");
	  return -1;
	}

	if (eglInitialize(eglDisplay, NULL, NULL)!=EGL_TRUE)
	{
	  fprintf(stderr, "eglInitialize: error 0x%x\n", eglGetError());
	  return -1;
	}

	eglBindAPI(EGL_OPENGL_ES_API);
	printf("eglBindAPI : 0x%x\n", eglGetError());

    printf("preparing EGL configuration...\n");

    if ( !eglChooseConfig(eglDisplay, attribs, &eglConfig, 1, &num_config))
	{
    	//Failure case
    	printf("Failure: %d\n",  __LINE__);
    	eglTerminate(eglDisplay);
    	return -1;
	}

    printf("eglChooseConfig : 0x%x\n", eglGetError());
    printf("\nEGL Configuration - finished %d\n", num_config);

	/* create a 3D rendering target */
	int result = 0;
	if ((result = gf_3d_target_create(&target, layer, NULL, 0, disp_info.xres, disp_info.yres, disp_info.format))!=GF_ERR_OK)
	{
	  fprintf(stderr, "Unable to create rendering target %d\n", result);
	  return -1;
	}

	gf_layer_set_src_viewport(layer, 0, 0, width-1, height-1);
	gf_layer_set_dst_viewport(layer, 0, 0, width-1, height-1);
	gf_layer_enable(layer);


/*	econtext = eglCreateContext(eglDisplay, eglConfig, EGL_NO_CONTEXT, NULL);
	if (econtext==EGL_NO_CONTEXT)
	{
	  fprintf(stderr, "Create context failed: 0x%x\n", eglGetError());
	  return -1;
	}*/

	printf("creating windows surface\n");
    //EGLint window_attribs[] = {EGL_RENDER_BUFFER, EGL_BACK_BUFFER, EGL_NONE,};

	eglSurface = eglCreateWindowSurface(eglDisplay, eglConfig, target, NULL);
	if (eglSurface==EGL_NO_SURFACE)
	{
	  fprintf(stderr, "Create surface failed: 0x%x\n", eglGetError());
	  return -1;
	}
	printf("after creating windows surface\n");

	if (eglMakeCurrent(eglDisplay, eglSurface, eglSurface, econtext)==EGL_FALSE)
	{
	  fprintf(stderr, "Make current failed: 0x%x\n", eglGetError());
	  return -1;
	}

	printf("finished \n");

    return 0;
}
