/*
 * Copyright (C) 2013 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include <stdlib.h>
#include <stdio.h>
#include <stdarg.h>

#include <EGL/egl.h>
#include <GLES2/gl2.h>

#include <system/graphics.h>

#include "util.h"

void matrix_init_ortho(GLfloat *m, float w, float h) {
	m[0] = 2.0 / w;
	m[1] = 0.0;
	m[2] = 0.0;
	m[3] = -1.0;
	m[4] = 0.0;
	m[5] = 2.0 / h;
	m[6] = 0.0;
	m[7] = -1.0;
	m[8] = 0.0;
	m[9] = 0.0;
	m[10] = -1.0;
	m[11] = 0.0;
	m[12] = 0.0;
	m[13] = 0.0;
	m[14] = 0.0;
	m[15] = 1.0;
}

static GLuint load_shader(GLenum shaderType, const char *src) {
	GLint status = 0, len = 0;
	GLuint shader;

	if (!(shader = glCreateShader(shaderType)))
		return 0;

	glShaderSource(shader, 1, &src, NULL);
	glCompileShader(shader);
	glGetShaderiv(shader, GL_COMPILE_STATUS, &status);

	if (status)
		return shader;

	glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &len);
	if (len) {
		char *msg = malloc(len);
		if (msg) {
			glGetShaderInfoLog(shader, len, NULL, msg);
			msg[len-1] = 0;
			fprintf(stderr, "error compiling shader:\n%s\n", msg);
			free(msg);
		}
	}
	glDeleteShader(shader);
	return 0;
}

GLuint load_program(const char *vert_src, const char *frag_src) {
	GLuint vert, frag, prog;
	GLint status = 0, len = 0;

	if (!(vert = load_shader(GL_VERTEX_SHADER, vert_src)))
		return 0;
	if (!(frag = load_shader(GL_FRAGMENT_SHADER, frag_src)))
		goto fail_frag;
	if (!(prog = glCreateProgram()))
		goto fail_prog;

	glAttachShader(prog, vert);
	glAttachShader(prog, frag);
	glLinkProgram(prog);

	glGetProgramiv(prog, GL_LINK_STATUS, &status);
	if (status)
		return prog;

	glGetProgramiv(prog, GL_INFO_LOG_LENGTH, &len);
	if (len) {
		char *buf = (char*) malloc(len);
		if (buf) {
			glGetProgramInfoLog(prog, len, NULL, buf);
			buf[len-1] = 0;
			fprintf(stderr, "error linking program:\n%s\n", buf);
			free(buf);
		}
	}
	glDeleteProgram(prog);
fail_prog:
	glDeleteShader(frag);
fail_frag:
	glDeleteShader(vert);
	return 0;
}

int select_config_for_window(EGLDisplay dpy, EGLint *attr,
	unsigned format, EGLConfig *config) {
	EGLint R,G,B,A;
	EGLint i, n, max;
	EGLConfig *cfg;

	switch (format) {
	case HAL_PIXEL_FORMAT_RGBA_8888:
	case HAL_PIXEL_FORMAT_BGRA_8888:
		R = G = B = A = 8;
		break;
	case HAL_PIXEL_FORMAT_RGB_565:
		R = 5; G = 6; B = 5; A = 0;
		break;
	default:
		fprintf(stderr, "unknown fb pixel format %d\n", format);
		return -1;
	}

	if (eglGetConfigs(dpy, NULL, 0, &max) == EGL_FALSE) {
		fprintf(stderr, "no EGL configurations available?!\n");
		return -1;
	}

	cfg = (EGLConfig*) malloc(sizeof(EGLConfig) * max);
	if (!cfg)
		return -1;

	if (eglChooseConfig(dpy, attr, cfg, max, &n) == EGL_FALSE) {
		fprintf(stderr, "eglChooseConfig failed\n");
		return -1;
	}

	for (i = 0; i < n; i++) {
		EGLint r,g,b,a;
		eglGetConfigAttrib(dpy, cfg[i], EGL_RED_SIZE,   &r);
		eglGetConfigAttrib(dpy, cfg[i], EGL_GREEN_SIZE, &g);
		eglGetConfigAttrib(dpy, cfg[i], EGL_BLUE_SIZE,  &b);
		eglGetConfigAttrib(dpy, cfg[i], EGL_ALPHA_SIZE, &a);
		if (r == R && g == G && b == B && a == A) {
			*config = cfg[i];
			free(cfg);
			return 0;
		}
	}

	fprintf(stderr, "cannot find matching config\n");
	free(cfg);
	return -1;
}

static struct CNativeWindow *_cnw = 0;

int egl_create(EGLDisplay *_display, EGLSurface *_surface, int *_w, int *_h) {
	EGLBoolean res;
	EGLConfig config = { 0 };
	EGLint context_attrs[] = { EGL_CONTEXT_CLIENT_VERSION, 2, EGL_NONE };
	EGLint config_attrs[] = {
		EGL_SURFACE_TYPE, EGL_WINDOW_BIT,
		EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT,
		EGL_NONE };
	EGLint major, minor;
	EGLContext context;
	EGLSurface surface;
	EGLint w, h;
	EGLDisplay display;
	EGLNativeWindowType window;
	unsigned width, height, format;
	struct CNativeWindow *cnw;

	display = eglGetDisplay(EGL_DEFAULT_DISPLAY);
	if (display == EGL_NO_DISPLAY)
		return -1;

	if (!(res = eglInitialize(display, &major, &minor)))
		return -1;

	fprintf(stderr, "egl version: %d.%d\n", major, minor);

	if ((cnw = cnw_create()) == 0)
		return -1;

	cnw_info(cnw, &width, &height, &format);
	window = (EGLNativeWindowType) cnw;

	if ((res = select_config_for_window(display, config_attrs, format, &config)))
		goto fail;

	surface = eglCreateWindowSurface(display, config, window, NULL);
	if (surface == EGL_NO_SURFACE)
		goto fail;

	context = eglCreateContext(display, config, EGL_NO_CONTEXT, context_attrs);
	if (context == EGL_NO_CONTEXT)
		goto fail;

	if (!(res = eglMakeCurrent(display, surface, surface, context)))
		goto fail;

	eglQuerySurface(display, surface, EGL_WIDTH, &w);
	eglQuerySurface(display, surface, EGL_HEIGHT, &h);

	fprintf(stderr, "window: %d x %d\n", w, h);

	*_display = display;
	*_surface = surface;
	*_w = w;
	*_h = h;

	_cnw = cnw;
	return 0;

fail:
	cnw_destroy(cnw);
	return -1;
}

void egl_destroy(EGLDisplay display, EGLSurface surface) {
	if (_cnw) {
		eglDestroySurface(display, surface);
		eglTerminate(display);
		cnw_destroy(_cnw);
		_cnw = 0;
	}
}
