/*
 * Copyright 2015 The Cobalt Authors. 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 <atomic>
#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();

  // Returns the unique id of the context instance.
  int context_id() const { return context_id_; }

  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 CopyTexSubImage2D(GLenum target,
                         GLint level,
                         GLint xoffset,
                         GLint yoffset,
                         GLint x,
                         GLint y,
                         GLsizei width,
                         GLsizei height);

  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 unique id of context instance. It might be queried from different
  // threads.
  std::atomic_int context_id_;

  // 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_
