// 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_ALL_RENDERERS_REQUIRED_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  // #if SB_API_VERSION >= SB_ALL_RENDERERS_REQUIRED_VERSION ||
        // SB_HAS(BLITTER)

#endif  // COBALT_RENDERER_RASTERIZER_BLITTER_RENDER_STATE_H_
