/*
 * Copyright 2015 Google Inc. All Rights Reserved.
 *
 * 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.
 */

#ifndef GLIMP_GLES_CONTEXT_H_
#define GLIMP_GLES_CONTEXT_H_

#include <GLES3/gl3.h>

#include <map>
#include <set>
#include <string>
#include <utility>

#include "glimp/egl/surface.h"
#include "glimp/gles/context_impl.h"
#include "glimp/gles/draw_state.h"
#include "glimp/gles/framebuffer.h"
#include "glimp/gles/resource_manager.h"
#include "glimp/gles/sampler.h"
#include "glimp/gles/vertex_attribute.h"
#include "nb/ref_counted.h"
#include "nb/scoped_ptr.h"
#include "starboard/atomic.h"
#include "starboard/thread.h"

namespace glimp {
namespace gles {

class Context {
 public:
  Context(nb::scoped_ptr<ContextImpl> context_impl, Context* share_context);

  ~Context() { SbAtomicNoBarrier_Store(&has_swapped_buffers_, 0); }

  // Returns current thread's current context, or NULL if nothing is current.
  static Context* GetTLSCurrentContext();

  // Sets the current thread's current context.  None of the parameters can
  // be NULL (use ReleaseTLSCurrentContext() if you wish to release the current
  // context).
  static bool SetTLSCurrentContext(Context* context,
                                   egl::Surface* draw,
                                   egl::Surface* read);

  // Releases the current thread's current context.
  static void ReleaseTLSCurrentContext();

  egl::Surface* draw_surface() {
    return default_draw_framebuffer_->color_attachment_surface();
  }

  // Returns the thread that currently holds this Context, or kSbThreadInvalid
  // if no thread currently holds the context.
  SbThread current_thread() const { return current_thread_; }

  // Return the last error generated and reset the error flag to GL_NO_ERROR.
  GLenum GetError();

  const GLubyte* GetString(GLenum name);
  void GetIntegerv(GLenum pname, GLint* params);
  void GetShaderiv(GLuint shader, GLenum pname, GLint* params);
  void GetShaderInfoLog(GLuint shader,
                        GLsizei bufsize,
                        GLsizei* length,
                        GLchar* infolog);
  void GetProgramiv(GLuint program, GLenum pname, GLint* params);
  void GetProgramInfoLog(GLuint program,
                         GLsizei bufsize,
                         GLsizei* length,
                         GLchar* infolog);

  void PixelStorei(GLenum pname, GLint param);

  void Enable(GLenum cap);
  void Disable(GLenum cap);

  void ColorMask(GLboolean red,
                 GLboolean green,
                 GLboolean blue,
                 GLboolean alpha);
  void DepthMask(GLboolean flag);

  void Clear(GLbitfield mask);
  void ClearColor(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha);

  void BlendFunc(GLenum sfactor, GLenum dfactor);
  void BlendEquation(GLenum mode);

  void CullFace(GLenum mode);
  void FrontFace(GLenum mode);

  GLuint CreateProgram();
  void DeleteProgram(GLuint program);
  void AttachShader(GLuint program, GLuint shader);
  void LinkProgram(GLuint program);
  void BindAttribLocation(GLuint program, GLuint index, const GLchar* name);
  void UseProgram(GLuint program);

  GLuint CreateShader(GLenum type);
  void DeleteShader(GLuint shader);
  void ShaderSource(GLuint shader,
                    GLsizei count,
                    const GLchar* const* string,
                    const GLint* length);
  void CompileShader(GLuint shader);

  void GenBuffers(GLsizei n, GLuint* buffers);
  void GenBuffersForVideoFrame(GLsizei n, GLuint* buffers);
  void DeleteBuffers(GLsizei n, const GLuint* buffers);
  void BindBuffer(GLenum target, GLuint buffer);
  void BufferData(GLenum target,
                  GLsizeiptr size,
                  const GLvoid* data,
                  GLenum usage);
  void BufferSubData(GLenum target,
                     GLintptr offset,
                     GLsizeiptr size,
                     const GLvoid* data);
  void* MapBufferRange(GLenum target,
                       GLintptr offset,
                       GLsizeiptr length,
                       GLbitfield access);
  bool UnmapBuffer(GLenum target);

  void LineWidth(GLfloat width);

  void GenTextures(GLsizei n, GLuint* textures);
  void DeleteTextures(GLsizei n, const GLuint* textures);
  void ActiveTexture(GLenum texture);
  void BindTexture(GLenum target, GLuint texture);
  void GetTexParameteriv(GLenum target, GLenum pname, GLint* params);
  void TexParameteri(GLenum target, GLenum pname, GLint param);
  void TexImage2D(GLenum target,
                  GLint level,
                  GLint internalformat,
                  GLsizei width,
                  GLsizei height,
                  GLint border,
                  GLenum format,
                  GLenum type,
                  const GLvoid* pixels);
  void TexSubImage2D(GLenum target,
                     GLint level,
                     GLint xoffset,
                     GLint yoffset,
                     GLsizei width,
                     GLsizei height,
                     GLenum format,
                     GLenum type,
                     const GLvoid* pixels);

  void GenFramebuffers(GLsizei n, GLuint* framebuffers);
  void DeleteFramebuffers(GLsizei n, const GLuint* framebuffers);
  void BindFramebuffer(GLenum target, GLuint framebuffer);
  void FramebufferTexture2D(GLenum target,
                            GLenum attachment,
                            GLenum textarget,
                            GLuint texture,
                            GLint level);
  GLenum CheckFramebufferStatus(GLenum target);
  void FramebufferRenderbuffer(GLenum target,
                               GLenum attachment,
                               GLenum renderbuffertarget,
                               GLuint renderbuffer);

  void GenRenderbuffers(GLsizei n, GLuint* renderbuffers);
  void DeleteRenderbuffers(GLsizei n, const GLuint* renderbuffers);
  void BindRenderbuffer(GLenum target, GLuint renderbuffer);
  void RenderbufferStorage(GLenum target,
                           GLenum internalformat,
                           GLsizei width,
                           GLsizei height);

  void StencilMask(GLuint mask);
  void ClearStencil(GLint s);

  void Viewport(GLint x, GLint y, GLsizei width, GLsizei height);
  void Scissor(GLint x, GLint y, GLsizei width, GLsizei height);

  void VertexAttribPointer(GLuint indx,
                           GLint size,
                           GLenum type,
                           GLboolean normalized,
                           GLsizei stride,
                           const GLvoid* ptr);
  void EnableVertexAttribArray(GLuint index);
  void DisableVertexAttribArray(GLuint index);
  void VertexAttribfv(GLuint indx, int elem_size, const GLfloat* values);

  GLint GetUniformLocation(GLuint program, const GLchar* name);
  void Uniformiv(GLint location,
                 GLsizei count,
                 GLsizei elem_size,
                 const GLint* v);
  void Uniformfv(GLint location,
                 GLsizei count,
                 GLsizei elem_size,
                 const GLfloat* v);
  void UniformMatrixfv(GLint location,
                       GLsizei count,
                       GLboolean transpose,
                       GLsizei dim_size,
                       const GLfloat* value);

  void DrawArrays(GLenum mode, GLint first, GLsizei count);
  void DrawElements(GLenum mode,
                    GLsizei count,
                    GLenum type,
                    const GLvoid* indices);

  void ReadPixels(GLint x,
                  GLint y,
                  GLsizei width,
                  GLsizei height,
                  GLenum format,
                  GLenum type,
                  GLvoid* pixels);

  void Flush();
  void Finish();
  void SwapBuffers();

  // Called when eglBindTexImage() is called.
  bool BindTextureToEGLSurface(egl::Surface* surface);
  // Called when eglReleaseTexImage() is called.
  bool ReleaseTextureFromEGLSurface(egl::Surface* surface);

  // Utility functions for use by other modules.
  nb::scoped_refptr<Texture> GetTexture(uint32_t id) {
    return resource_manager_->GetTexture(id);
  }

  DrawStateDirtyFlags* GetDrawStateDirtyFlags() {
    return &draw_state_dirty_flags_;
  }

  static bool has_swapped_buffers() {
    return SbAtomicNoBarrier_Load(&has_swapped_buffers_) != 0;
  }

 private:
  void MakeCurrent(egl::Surface* draw, egl::Surface* read);
  void ReleaseContext();
  void SetError(GLenum error) { error_ = error; }

  // Returns the bound buffer for the specific specified target.
  // This returns a pointer because it is used by glBindBuffer() which modifies
  // what the returned scoped_refptr points to.
  nb::scoped_refptr<Buffer>* GetBoundBufferForTarget(GLenum target);

  // Returns the bound texture for the specific specified target and slot.
  // This returns a pointer because it is used by glBindTexture() which modifies
  // what the returned scoped_refptr points to.
  nb::scoped_refptr<Texture>* GetBoundTextureForTarget(GLenum target,
                                                       GLenum texture);

  void SetupExtensionsString();

  void UpdateVertexAttribsInDrawState();
  void UpdateSamplersInDrawState();

  // Packs enabled vertex attributes and samplers into dense lists in the
  // |draw_state_| if they have been modified.
  void CompressDrawStateForDrawCall();

  // Marks the used program as being dirty, but this may also imply the marking
  // of attributes and uniforms as being dirty as well.
  void MarkUsedProgramDirty();

  // Sets the bound framebuffer to the default framebuffer (e.g. when
  // glBindFramebuffer(GL_FRAMEBUFFER, 0) is called).
  void SetBoundDrawFramebufferToDefault();
  void SetBoundReadFramebufferToDefault();
  bool IsDefaultDrawFramebufferBound() const;
  bool IsDefaultReadFramebufferBound() const;

  // Takes settings like GL_UNPACK_ROW_LENGTH and GL_UNPACK_ALIGNMENT into
  // account to determine the pitch of incoming pixel data.
  int GetPitchForTextureData(int width, PixelFormat pixel_format) const;

  // A reference to the platform-specific implementation aspects of the context.
  nb::scoped_ptr<ContextImpl> impl_;

  // The thread that currently holds this context as its current context.
  SbThread current_thread_;

  // Has this context ever been made current before?
  bool has_been_current_;

  // The value to be returned when GetString(GL_EXTENSIONS) is called.
  std::string extensions_string_;

  // The resource manager containing all referenced resources.
  nb::scoped_refptr<ResourceManager> resource_manager_;

  // Sets the active texture, which can be thought of more intuitively as
  // the active "sampler".  Set using glActiveTexture().
  GLenum active_texture_;

  // The set of sampler units, of which |active_texture_| indexes.
  nb::scoped_array<nb::scoped_refptr<Texture> > texture_units_;
  bool enabled_textures_dirty_;

  // A mapping from an integer index (specified by the index parameter of
  // glBindAttribLocation(), glVertexAttribPointer(), and others) to vertex
  // attribute information structure.
  std::map<unsigned int, VertexAttributeArray> vertex_attrib_map_;

  // This map is populated by calls to glVertexAttribXfv() and contains
  // attribute values that, when used, should apply to ALL vertices in a draw
  // call.  These attribute values will be used instead of those set by
  // glVertexAttribPointer() whenever the corresponding vertex attribute id
  // (the key of this map) attribute array is disabled through a call to
  // glDisableVertexAttribArray().
  std::map<unsigned int, VertexAttributeConstant> const_vertex_attrib_map_;

  // Keeps track of which vertex attributes are enabled.  This set is modified
  // through calls to glEnableVertexAttribArray() and
  // glDisableVertexAttribArray().
  std::set<unsigned int> enabled_vertex_attribs_;
  bool enabled_vertex_attribs_dirty_;

  // The default draw and read framebuffer are those whose surfaces are set by
  // calls to eglMakeCurrent().  The default draw framebuffer is the initial
  // framebuffer target for draw commands, and can be selected by calling
  // glBindFramebuffer(0).
  nb::scoped_refptr<Framebuffer> default_draw_framebuffer_;
  nb::scoped_refptr<Framebuffer> default_read_framebuffer_;

  // The currently bound read framebuffer.  If this is set to the default read
  // framebuffer, then it will be equal to |default_read_framebuffer_|.
  nb::scoped_refptr<Framebuffer> read_framebuffer_;

  // Tracks all GL draw state.  It is updated by making various GL calls,
  // and it is read when a draw (or clear) call is made.  It is modified
  // by this Context object and read from the ContextImpl object.
  DrawState draw_state_;

  // Tracks which members of |draw_state_| have been modified since the last
  // draw (or clear) command issued to the ContextImpl object.  This
  // allows implementations to determine whether it is necessary to re-setup
  // certain context information.  It is expected that implementations will
  // set these dirty flags to false after they have processed the corresponding
  // draw state.
  DrawStateDirtyFlags draw_state_dirty_flags_;

  // The pack/unpack alignments are used when transferring pixel data to/from
  // client CPU memory, respectively.  For example, calls to glTexImage2D()
  // will refer to the unpack alignment to determine the expected alignment
  // of each row of pixel data.  These values are set through glPixelStorei().
  //   https://www.khronos.org/opengles/sdk/docs/man/xhtml/glPixelStorei.xml
  int pack_alignment_;
  int unpack_alignment_;

  // Allows the pitch of texture data to be explicitly specified.  This value
  // can be modified by calling glPixelStorei(GL_UNPACK_ALIGNMENT, x).
  //   https://www.khronos.org/opengles/sdk/docs/man3/html/glPixelStorei.xhtml
  int unpack_row_length_;

  // Tracks the currently bound pixel unpack buffer object, or NULL if none
  // are bound.
  nb::scoped_refptr<Buffer> bound_pixel_unpack_buffer_;

  // Keeps track of the set of EGLSurfaces that are bound to textures
  // currently.
  std::map<egl::Surface*, nb::scoped_refptr<Texture> > bound_egl_surfaces_;

  // The currently bound renderbuffer, specified through a call to
  // glBindRenderbuffer().
  //   https://www.khronos.org/opengles/sdk/docs/man/xhtml/glBindRenderbuffer.xml
  nb::scoped_refptr<Renderbuffer> bound_renderbuffer_;

  // The last GL ES error raised.
  GLenum error_;

  // Track if SwapBuffers() has been called. Stores 0 if SwapBuffers() has not
  // been called, and 1 if SwapBuffers() has been called.
  static SbAtomic32 has_swapped_buffers_;
};

}  // namespace gles
}  // namespace glimp

#endif  // GLIMP_GLES_CONTEXT_H_
