// Copyright 2016 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 COBALT_RENDERER_RASTERIZER_BLITTER_RENDER_STATE_H_
#define COBALT_RENDERER_RASTERIZER_BLITTER_RENDER_STATE_H_

#include <algorithm>
#include <stack>

#include "base/logging.h"
#include "cobalt/math/matrix3_f.h"
#include "cobalt/math/rect.h"
#include "cobalt/math/rect_f.h"
#include "cobalt/math/vector2d_f.h"
#include "cobalt/render_tree/brush.h"
#include "starboard/blitter.h"

#if SB_API_VERSION < SB_BLITTER_DEPRECATED_VERSION && SB_HAS(BLITTER)

namespace cobalt {
namespace renderer {
namespace rasterizer {
namespace blitter {

// Keeps track of the current scale/offset transforms.  Note that while the
// render tree supports general affine transformations, the Starboard Blitter
// API only supports scale and translations, so we maintain only those.  If
// rotations are used, we can fallback to software rendering.
class Transform {
 public:
  Transform() : scale_(1.0f, 1.0f), translate_(0.0f, 0.0f) {}

  explicit Transform(const math::Matrix3F& matrix)
      : scale_(matrix.Get(0, 0), matrix.Get(1, 1)),
        translate_(matrix.Get(0, 2), matrix.Get(1, 2)) {
    // We cannot handle sheers and rotations.
    DCHECK_EQ(0, matrix.Get(0, 1));
    DCHECK_EQ(0, matrix.Get(1, 0));
  }

  Transform(const math::Vector2dF& scale, const math::Vector2dF& translate)
      : scale_(scale), translate_(translate) {}

  const math::Vector2dF& scale() const { return scale_; }
  const math::Vector2dF& translate() const { return translate_; }

  void ApplyOffset(const math::Vector2dF& offset) {
    translate_ +=
        math::Vector2dF(scale_.x() * offset.x(), scale_.y() * offset.y());
  }
  void ApplyScale(const math::Vector2dF& scale_mult) {
    scale_.Scale(scale_mult.x(), scale_mult.y());
  }

  math::RectF TransformRect(const math::RectF& rect) const {
    return math::RectF(rect.x() * scale_.x() + translate_.x(),
                       rect.y() * scale_.y() + translate_.y(),
                       rect.width() * scale_.x(), rect.height() * scale_.y());
  }

  math::Matrix3F ToMatrix() const {
    return math::Matrix3F::FromValues(scale_.x(), 0, translate_.x(), 0,
                                      scale_.y(), translate_.y(), 0, 0, 1);
  }

 private:
  math::Vector2dF scale_;
  math::Vector2dF translate_;
};

// Helper class to manage the pushing and popping of rectangular bounding
// boxes.  This manages intersecting newly pushed bounding boxes with the
// existing stack of bounding boxes.
class BoundsStack {
 public:
  // Helper class to scope a pair of Push()/Pop() calls.
  class ScopedPush {
   public:
    ScopedPush(BoundsStack* stack, const math::Rect& bounds) : stack_(stack) {
      stack_->Push(bounds);
    }
    ~ScopedPush() { stack_->Pop(); }

   private:
    BoundsStack* stack_;
  };

  BoundsStack(SbBlitterContext context, const math::Rect& initial_bounds);
  void Push(const math::Rect& bounds);
  void Pop();

  const math::Rect& Top() const { return bounds_.top(); }

  // Updates the SbBlitterContext object with the current top of the stack.
  void UpdateContext();

 private:
  SbBlitterContext context_;
  std::stack<math::Rect> bounds_;
};

// The full render state used by the Blitter API RenderTreeNodeVisitor.
// Packages together a render target, current transform and clip stack.
struct RenderState {
  RenderState(SbBlitterRenderTarget render_target, const Transform& transform,
              const BoundsStack& bounds_stack)
      : render_target(render_target),
        transform(transform),
        bounds_stack(bounds_stack),
        opacity(1.0f)
#if defined(ENABLE_DEBUGGER)
        ,
        highlight_software_draws(false)
#endif  // defined(ENABLE_DEBUGGER)
  {
  }

  SbBlitterRenderTarget render_target;
  Transform transform;
  BoundsStack bounds_stack;
  float opacity;

#if defined(ENABLE_DEBUGGER)
  // If true, all software rasterization results are replaced with a green
  // fill rectangle.  Thus, if the software cache is used, one will see a flash
  // of green every time something is registered with the cache.
  bool highlight_software_draws;
#endif  // defined(ENABLE_DEBUGGER)
};

}  // namespace blitter
}  // namespace rasterizer
}  // namespace renderer
}  // namespace cobalt

#endif  // SB_API_VERSION < SB_BLITTER_DEPRECATED_VERSION && SB_HAS(BLITTER)

#endif  // COBALT_RENDERER_RASTERIZER_BLITTER_RENDER_STATE_H_
