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