// Copyright 2017 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.

#include "cobalt/renderer/fps_overlay.h"

#include <memory>
#include <string>
#include <utility>
#include <vector>

#include "base/strings/stringprintf.h"
#include "cobalt/render_tree/brush.h"
#include "cobalt/render_tree/color_rgba.h"
#include "cobalt/render_tree/composition_node.h"
#include "cobalt/render_tree/font.h"
#include "cobalt/render_tree/glyph_buffer.h"
#include "cobalt/render_tree/rect_node.h"
#include "cobalt/render_tree/resource_provider.h"
#include "cobalt/render_tree/text_node.h"

namespace cobalt {
namespace renderer {

namespace {
const render_tree::ColorRGBA kTextColor(1.0f, 1.0f, 1.0f, 1.0f);
const render_tree::ColorRGBA kBackgroundColor(1.0f, 0.6f, 0.6f, 1.0f);
const char* kTypefaceName = "Roboto";
const float kFontSize = 14.0f;

// Distance between the text bounds and the background bounds.
const int kTextMarginInPixels = 5;

// Spacing between each line of text.
const int kTextVerticalSpacingInPixels = 5;

scoped_refptr<render_tree::Node> ConvertLinesToOverlay(
    render_tree::ResourceProvider* resource_provider, render_tree::Font* font,
    const std::vector<std::string>& lines) {
  // First create a composition node that composes all the lines of text
  // together.
  float y_offset = kTextMarginInPixels;
  render_tree::CompositionNode::Builder text_builder;
  for (const auto& line : lines) {
    scoped_refptr<render_tree::GlyphBuffer> glyph_buffer =
        resource_provider->CreateGlyphBuffer(line, font);
    math::RectF bounds(glyph_buffer->GetBounds());

    text_builder.AddChild(new render_tree::TextNode(
        math::Vector2dF(-bounds.x() + kTextMarginInPixels,
                        -bounds.y() + y_offset),
        glyph_buffer, kTextColor));

    y_offset += bounds.height() + kTextVerticalSpacingInPixels;
  }

  scoped_refptr<render_tree::CompositionNode> text =
      new render_tree::CompositionNode(std::move(text_builder));

  // Now compose that onto a solid background.
  math::RectF background_bounds = text->GetBounds();
  background_bounds.set_height(background_bounds.height() +
                               2 * kTextMarginInPixels);
  background_bounds.set_y(0);
  background_bounds.set_width(background_bounds.width() +
                              2 * kTextMarginInPixels);
  background_bounds.set_x(0);

  render_tree::CompositionNode::Builder text_with_background_builder;
  text_with_background_builder.AddChild(new render_tree::RectNode(
      background_bounds,
      std::unique_ptr<render_tree::Brush>(
          new render_tree::SolidColorBrush(kBackgroundColor))));
  text_with_background_builder.AddChild(text);

  return new render_tree::CompositionNode(
      std::move(text_with_background_builder));
}

scoped_refptr<render_tree::Node> ConvertFPSStatsToOverlay(
    render_tree::ResourceProvider* resource_provider, render_tree::Font* font,
    const base::CValCollectionTimerStatsFlushResults& fps_stats) {
  std::vector<std::string> lines;
  lines.push_back(base::StringPrintf(
      "Samples: %d", static_cast<unsigned int>(fps_stats.sample_count)));
  lines.push_back(base::StringPrintf("Average: %.1fms",
                                     fps_stats.average.InMillisecondsF()));
  lines.push_back(
      base::StringPrintf("Min: %.1fms", fps_stats.minimum.InMillisecondsF()));
  lines.push_back(
      base::StringPrintf("Max: %.1fms", fps_stats.maximum.InMillisecondsF()));
  lines.push_back(base::StringPrintf(
      "25th Pct: %.1fms", fps_stats.percentile_25th.InMillisecondsF()));
  lines.push_back(base::StringPrintf(
      "50th Pct: %.1fms", fps_stats.percentile_50th.InMillisecondsF()));
  lines.push_back(base::StringPrintf(
      "75th Pct: %.1fms", fps_stats.percentile_75th.InMillisecondsF()));
  lines.push_back(base::StringPrintf(
      "95th Pct: %.1fms", fps_stats.percentile_95th.InMillisecondsF()));

  return ConvertLinesToOverlay(resource_provider, font, lines);
}
}  // namespace

FpsOverlay::FpsOverlay(render_tree::ResourceProvider* resource_provider)
    : resource_provider_(resource_provider) {
  font_ = resource_provider_
              ->GetLocalTypeface(kTypefaceName, render_tree::FontStyle())
              ->CreateFontWithSize(kFontSize);
}

void FpsOverlay::UpdateOverlay(
    const base::CValCollectionTimerStatsFlushResults& fps_stats) {
  cached_overlay_ =
      ConvertFPSStatsToOverlay(resource_provider_, font_.get(), fps_stats);
}

scoped_refptr<render_tree::Node> FpsOverlay::AnnotateRenderTreeWithOverlay(
    render_tree::Node* original_tree) {
  if (!cached_overlay_) {
    return original_tree;
  } else {
    // Compose the overlay onto the top left corner of the original render tree.
    render_tree::CompositionNode::Builder builder;
    builder.AddChild(original_tree);
    builder.AddChild(cached_overlay_);
    return new render_tree::CompositionNode(std::move(builder));
  }
}

}  // namespace renderer
}  // namespace cobalt
