// Copyright (c) 2010 The Chromium OS Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

// Application that displays graphics using OpenGL [ES] with the intent
// of being used in functional tests.

#include <gflags/gflags.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>

#include <cmath>

#include "glbench/glinterface.h"
#include "glbench/main.h"
#include "glbench/utils.h"


GLuint GenerateAndBindTexture() {
  GLuint name = ~0;
  glGenTextures(1, &name);
  glBindTexture(GL_TEXTURE_2D, name);
  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
  return name;
}

unsigned char* CreateBitmap(int w, int h) {
  unsigned char* bitmap = new unsigned char[4 * w * h];
  unsigned char* pixel = bitmap;
  float w2 = 0.5f * w;
  float h2 = 0.5f * h;
  for (int y = 0; y < h; y++) {
    for (int x = 0; x < w; x++) {
      // Fill with soft ellipse
      float dx = fabs((x - w2) / w2);
      float dy = fabs((y - h2) / h2);
      float dist2 = dx*dx + dy*dy;
      if (dist2 > 1.f)
        dist2 = 1.f;
      *pixel = (1.f - dist2) * 255.f;
      pixel++;
      *pixel = (1.f - dist2) * 255.f;
      pixel++;
      *pixel = (1.f - dist2) * 255.f;
      pixel++;
      *pixel = 0;
      pixel++;
    }
  }
  return bitmap;
}


const char kVertexShader[] =
    "attribute vec4 vertices;"
    "varying vec2 v1;"
    "void main() {"
    "    gl_Position = vec4(vertices.x, vertices.y, 0.0, 1.0);"
    "    v1 = vec2(0.5 * vertices.x + 0.5, 0.5 * vertices.y + 0.5);"
    "}";

const char kFragmentShader[] =
    "uniform sampler2D tex;"
    "uniform vec4 color;"
    "varying vec2 v1;"
    "void main() {"
    "    gl_FragColor = color * texture2D(tex, v1);"
    "}";

// Command line flags
DEFINE_double(screenshot1_sec, 2.f, "seconds delay before screenshot1_cmd");
DEFINE_double(screenshot2_sec, 1.f, "seconds delay before screenshot2_cmd");
DEFINE_string(screenshot1_cmd, "", "system command to take a screen shot 1");
DEFINE_string(screenshot2_cmd, "", "system command to take a screen shot 2");
DEFINE_double(cooldown_sec, 1.f, "seconds delay after all screenshots");

int main(int argc, char* argv[]) {
  // Configure full screen
  g_width = -1;
  g_height = -1;

  google::ParseCommandLineFlags(&argc, &argv, true);

  g_main_gl_interface.reset(GLInterface::Create());
  if (!g_main_gl_interface->Init()) {
    printf("# Error: Failed to initialize %s.\n", argv[0]);
    return 1;
  }

  GLint viewport[2];
  glGetIntegerv(GL_MAX_VIEWPORT_DIMS, viewport);
  printf("# MAX_VIEWPORT_DIMS=(%d, %d)\n", viewport[0], viewport[1]);
  if (viewport[0] < g_width || viewport[1] < g_height) {
    printf("# Error: MAX_VIEWPORT_DIMS too small\n");
    return 1;
  }
  glViewport(0, 0, g_width, g_height);

  unsigned char* bitmap = CreateBitmap(g_height, g_width);
  GLuint texture = GenerateAndBindTexture();
  glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, g_height, g_width, 0,
               GL_RGBA, GL_UNSIGNED_BYTE, bitmap);

  GLfloat vertices[8] = {
    -1.f, -1.f,
    1.f, -1.f,
    -1.f, 1.f,
    1.f, 1.f,
  };

  GLuint program = glbench::InitShaderProgram(kVertexShader, kFragmentShader);
  int attribute_index = glGetAttribLocation(program, "vertices");
  glVertexAttribPointer(attribute_index, 2, GL_FLOAT, GL_FALSE, 0, vertices);
  glEnableVertexAttribArray(attribute_index);

  int texture_sampler = glGetUniformLocation(program, "tex");
  glUniform1i(texture_sampler, 0);

  int display_color = glGetUniformLocation(program, "color");
  float white[4] = {1.0f, 1.0f, 1.0f, 1.0f};
  float blue[4] = {0.5f, 0.5f, 1.0f, 1.0f};

  uint64_t last_event_time = GetUTime();
  enum State {
    kStateScreenShot1,
    kStateScreenShot2,
    kStateCooldown,
    kStateExit
  } state = kStateScreenShot1;
  float seconds_delay_for_next_state[] = {
      static_cast<float>(FLAGS_screenshot1_sec),
      static_cast<float>(FLAGS_screenshot2_sec),
      static_cast<float>(FLAGS_cooldown_sec),
      0
  };

  do {
    // Draw
    glClear(GL_COLOR_BUFFER_BIT);
    if (state == kStateScreenShot1)
      glUniform4fv(display_color, 1, white);
    else
      glUniform4fv(display_color, 1, blue);
    glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
    g_main_gl_interface->SwapBuffers();
    // Loop until next event
    float seconds_since_last_event =
        static_cast<float>(GetUTime() - last_event_time) / 1000000ULL;
    if (seconds_since_last_event < seconds_delay_for_next_state[state])
      continue;

    // State change. Perform action.
    switch (state) {
      case kStateScreenShot1:
        ignore_result(system(FLAGS_screenshot1_cmd.c_str()));
        break;
      case kStateScreenShot2:
        ignore_result(system(FLAGS_screenshot2_cmd.c_str()));
        break;
      default:
        break;
    }

    // Advance to next state
    last_event_time = GetUTime();
    state = static_cast<State>(state + 1);
  } while (state != kStateExit);

  glDeleteTextures(1, &texture);
  g_main_gl_interface->Cleanup();
  return 0;
}
