/*
 * 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.
 */

#include "glimp/gles/texture.h"

#include "nb/pointer_arithmetic.h"
#include "nb/rect.h"

namespace glimp {
namespace gles {

Texture::Texture(nb::scoped_ptr<TextureImpl> impl)
    : impl_(impl.Pass()),
      target_valid_(false),
      texture_allocated_(false),
      bound_to_surface_(NULL) {}

void Texture::SetTarget(GLenum target) {
  target_ = target;
  target_valid_ = true;
}

void Texture::Initialize(GLint level,
                         PixelFormat pixel_format,
                         GLsizei width,
                         GLsizei height) {
  width_ = static_cast<int>(width);
  height_ = static_cast<int>(height);
  pixel_format_ = pixel_format;

  impl_->Initialize(level, pixel_format_, width_, height_);

  texture_allocated_ = true;
}

void Texture::UpdateData(GLint level,
                         GLint xoffset,
                         GLint yoffset,
                         GLsizei width,
                         GLsizei height,
                         int pitch_in_bytes,
                         const GLvoid* pixels) {
  SB_DCHECK(pixels != NULL);
  impl_->UpdateData(level, nb::Rect<int>(xoffset, yoffset, width, height),
                    pitch_in_bytes, pixels);
}

void Texture::UpdateDataFromBuffer(
    GLint level,
    GLint xoffset,
    GLint yoffset,
    GLsizei width,
    GLsizei height,
    int pitch_in_bytes,
    const nb::scoped_refptr<Buffer>& pixel_unpack_buffer,
    uintptr_t buffer_offset) {
  SB_DCHECK(pixel_unpack_buffer);
  impl_->UpdateDataFromBuffer(
      level, nb::Rect<int>(xoffset, yoffset, width, height), pitch_in_bytes,
      pixel_unpack_buffer, buffer_offset);
}

bool Texture::BindToEGLSurface(egl::Surface* surface) {
  if (bound_to_surface_ != NULL) {
    SB_DLOG(WARNING) << "A EGLSurface is already bound to this texture.";
    return false;
  }

  width_ = surface->GetWidth();
  height_ = surface->GetHeight();

  SB_DCHECK(surface->GetTextureFormat() == EGL_TEXTURE_RGBA);
  pixel_format_ = kPixelFormatRGBA8;
  texture_allocated_ = true;

  impl_->BindToEGLSurface(surface);
  bound_to_surface_ = surface;

  return true;
}

bool Texture::ReleaseFromEGLSurface(egl::Surface* surface) {
  if (bound_to_surface_ != surface) {
    SB_DLOG(WARNING) << "Attempting to release a surface that this texture was "
                        "not bound to.";
    return false;
  }

  width_ = 0;
  height_ = 0;
  pixel_format_ = kPixelFormatInvalid;
  texture_allocated_ = false;
  bound_to_surface_ = NULL;

  impl_->Initialize(0, kPixelFormatInvalid, 0, 0);

  return true;
}

void Texture::ReadPixelsAsRGBA8(GLint x,
                                GLint y,
                                GLsizei width,
                                GLsizei height,
                                int pitch_in_bytes,
                                GLvoid* pixels) {
  impl_->ReadPixelsAsRGBA8(nb::Rect<int>(x, y, width, height), pitch_in_bytes,
                           pixels);
}

bool Texture::CanBeAttachedToFramebuffer() const {
  return impl_->CanBeAttachedToFramebuffer();
}

}  // namespace gles
}  // namespace glimp
