/*
 * Copyright 2017 Google Inc.
 *
 * 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 LIB_TXT_SRC_PARAGRAPH_TXT_H_
#define LIB_TXT_SRC_PARAGRAPH_TXT_H_

#include <set>
#include <utility>
#include <vector>

#include "flutter/fml/compiler_specific.h"
#include "flutter/fml/macros.h"
#include "font_collection.h"
#include "line_metrics.h"
#include "minikin/LineBreaker.h"
#include "paint_record.h"
#include "paragraph.h"
#include "paragraph_style.h"
#include "placeholder_run.h"
#include "run_metrics.h"
#include "styled_runs.h"
#include "third_party/googletest/googletest/include/gtest/gtest_prod.h"  // nogncheck
#include "third_party/skia/include/core/SkFontMetrics.h"
#include "third_party/skia/include/core/SkRect.h"
#include "utils/LinuxUtils.h"
#include "utils/MacUtils.h"
#include "utils/WindowsUtils.h"

namespace txt {

using GlyphID = uint32_t;

// Constant with the unicode codepoint for the "Object replacement character".
// Used as a stand-in character for Placeholder boxes.
const int objReplacementChar = 0xFFFC;
// Constant with the unicode codepoint for the "Replacement character". This is
// the character that commonly renders as a black diamond with a white question
// mark. Used to replace non-placeholder instances of 0xFFFC in the text buffer.
const int replacementChar = 0xFFFD;

// Paragraph provides Layout, metrics, and painting capabilities for text. Once
// a Paragraph is constructed with ParagraphBuilder::Build(), an example basic
// workflow can be this:
//
//   std::unique_ptr<Paragraph> paragraph = paragraph_builder.Build();
//   paragraph->Layout(<somewidthgoeshere>);
//   paragraph->Paint(<someSkCanvas>, <xpos>, <ypos>);
class ParagraphTxt : public Paragraph {
 public:
  // Constructor. It is highly recommended to construct a paragraph with a
  // ParagraphBuilder.
  ParagraphTxt();

  virtual ~ParagraphTxt();

  // Minikin Layout doLayout() and LineBreaker addStyleRun() has an
  // O(N^2) (according to benchmarks) time complexity where N is the total
  // number of characters. However, this is not significant for reasonably sized
  // paragraphs. It is currently recommended to break up very long paragraphs
  // (10k+ characters) to ensure speedy layout.
  virtual void Layout(double width) override;

  virtual void Paint(SkCanvas* canvas, double x, double y) override;

  // Getter for paragraph_style_.
  const ParagraphStyle& GetParagraphStyle() const;

  // Returns the number of characters/unicode characters. AKA text_.size()
  size_t TextSize() const;

  double GetHeight() override;

  double GetMaxWidth() override;

  double GetLongestLine() override;

  double GetAlphabeticBaseline() override;

  double GetIdeographicBaseline() override;

  double GetMaxIntrinsicWidth() override;

  // Currently, calculated similarly to as GetLayoutWidth(), however this is not
  // necessarily 100% correct in all cases.
  double GetMinIntrinsicWidth() override;

  std::vector<TextBox> GetRectsForRange(
      size_t start,
      size_t end,
      RectHeightStyle rect_height_style,
      RectWidthStyle rect_width_style) override;

  PositionWithAffinity GetGlyphPositionAtCoordinate(double dx,
                                                    double dy) override;

  std::vector<Paragraph::TextBox> GetRectsForPlaceholders() override;

  Range<size_t> GetWordBoundary(size_t offset) override;

  // Returns the number of lines the paragraph takes up. If the text exceeds the
  // amount width and maxlines provides, Layout() truncates the extra text from
  // the layout and this will return the max lines allowed.
  size_t GetLineCount();

  bool DidExceedMaxLines() override;

  // Gets the full vector of LineMetrics which includes detailed data on each
  // line in the final layout.
  std::vector<LineMetrics>& GetLineMetrics() override;

  // Sets the needs_layout_ to dirty. When Layout() is called, a new Layout will
  // be performed when this is set to true. Can also be used to prevent a new
  // Layout from being calculated by setting to false.
  void SetDirty(bool dirty = true);

 private:
  friend class ParagraphBuilderTxt;
  FRIEND_TEST(ParagraphTest, SimpleParagraph);
  FRIEND_TEST(ParagraphTest, SimpleParagraphSmall);
  FRIEND_TEST(ParagraphTest, SimpleRedParagraph);
  FRIEND_TEST(ParagraphTest, RainbowParagraph);
  FRIEND_TEST(ParagraphTest, DefaultStyleParagraph);
  FRIEND_TEST(ParagraphTest, BoldParagraph);
  FRIEND_TEST_WINDOWS_DISABLED(ParagraphTest, LeftAlignParagraph);
  FRIEND_TEST_WINDOWS_DISABLED(ParagraphTest, RightAlignParagraph);
  FRIEND_TEST_WINDOWS_DISABLED(ParagraphTest, CenterAlignParagraph);
  FRIEND_TEST_WINDOWS_DISABLED(ParagraphTest, JustifyAlignParagraph);
  FRIEND_TEST_WINDOWS_DISABLED(ParagraphTest, JustifyRTL);
  FRIEND_TEST_WINDOWS_DISABLED(ParagraphTest, InlinePlaceholderLongestLine);
  FRIEND_TEST_LINUX_ONLY(ParagraphTest, JustifyRTLNewLine);
  FRIEND_TEST(ParagraphTest, DecorationsParagraph);
  FRIEND_TEST(ParagraphTest, ItalicsParagraph);
  FRIEND_TEST(ParagraphTest, ChineseParagraph);
  FRIEND_TEST(ParagraphTest, DISABLED_ArabicParagraph);
  FRIEND_TEST(ParagraphTest, SpacingParagraph);
  FRIEND_TEST(ParagraphTest, LongWordParagraph);
  FRIEND_TEST_LINUX_ONLY(ParagraphTest, KernScaleParagraph);
  FRIEND_TEST_WINDOWS_DISABLED(ParagraphTest, NewlineParagraph);
  FRIEND_TEST_LINUX_ONLY(ParagraphTest, EmojiParagraph);
  FRIEND_TEST_LINUX_ONLY(ParagraphTest, EmojiMultiLineRectsParagraph);
  FRIEND_TEST(ParagraphTest, HyphenBreakParagraph);
  FRIEND_TEST(ParagraphTest, RepeatLayoutParagraph);
  FRIEND_TEST(ParagraphTest, Ellipsize);
  FRIEND_TEST(ParagraphTest, UnderlineShiftParagraph);
  FRIEND_TEST(ParagraphTest, WavyDecorationParagraph);
  FRIEND_TEST(ParagraphTest, SimpleShadow);
  FRIEND_TEST(ParagraphTest, ComplexShadow);
  FRIEND_TEST(ParagraphTest, FontFallbackParagraph);
  FRIEND_TEST(ParagraphTest, InlinePlaceholder0xFFFCParagraph);
  FRIEND_TEST(ParagraphTest, FontFeaturesParagraph);
  FRIEND_TEST(ParagraphTest, GetGlyphPositionAtCoordinateSegfault);
  FRIEND_TEST(ParagraphTest, KhmerLineBreaker);
  FRIEND_TEST(ParagraphTest, TextHeightBehaviorRectsParagraph);

  // Starting data to layout.
  std::vector<uint16_t> text_;
  // A vector of PlaceholderRuns, which detail the sizes, positioning and break
  // behavior of the empty spaces to leave. Each placeholder span corresponds to
  // a 0xFFFC (object replacement character) in text_, which indicates the
  // position in the text where the placeholder will occur. There should be an
  // equal number of 0xFFFC characters and elements in this vector.
  std::vector<PlaceholderRun> inline_placeholders_;
  // The indexes of the boxes that correspond to an inline placeholder.
  std::vector<size_t> inline_placeholder_boxes_;
  // The indexes of instances of 0xFFFC that correspond to placeholders. This is
  // necessary since the user may pass in manually entered 0xFFFC values using
  // AddText().
  std::unordered_set<size_t> obj_replacement_char_indexes_;
  StyledRuns runs_;
  ParagraphStyle paragraph_style_;
  std::shared_ptr<FontCollection> font_collection_;

  minikin::LineBreaker breaker_;
  mutable std::unique_ptr<icu::BreakIterator> word_breaker_;

  std::vector<LineMetrics> line_metrics_;
  size_t final_line_count_;
  std::vector<double> line_widths_;

  // Stores the result of Layout().
  std::vector<PaintRecord> records_;

  bool did_exceed_max_lines_;

  // Strut metrics of zero will have no effect on the layout.
  struct StrutMetrics {
    double ascent = 0;  // Positive value to keep signs clear.
    double descent = 0;
    double leading = 0;
    double half_leading = 0;
    double line_height = 0;
    bool force_strut = false;
  };

  StrutMetrics strut_;

  // Overall left and right extremes over all lines.
  double max_right_;
  double min_left_;

  class BidiRun {
   public:
    // Constructs a BidiRun with is_ghost defaulted to false.
    BidiRun(size_t s, size_t e, TextDirection d, const TextStyle& st)
        : start_(s), end_(e), direction_(d), style_(&st), is_ghost_(false) {}

    // Constructs a BidiRun with a custom is_ghost flag.
    BidiRun(size_t s,
            size_t e,
            TextDirection d,
            const TextStyle& st,
            bool is_ghost)
        : start_(s), end_(e), direction_(d), style_(&st), is_ghost_(is_ghost) {}

    // Constructs a placeholder bidi run.
    BidiRun(size_t s,
            size_t e,
            TextDirection d,
            const TextStyle& st,
            PlaceholderRun& placeholder)
        : start_(s),
          end_(e),
          direction_(d),
          style_(&st),
          is_ghost_(false),
          placeholder_run_(&placeholder) {}

    size_t start() const { return start_; }
    size_t end() const { return end_; }
    size_t size() const { return end_ - start_; }
    TextDirection direction() const { return direction_; }
    const TextStyle& style() const { return *style_; }
    PlaceholderRun* placeholder_run() const { return placeholder_run_; }
    bool is_rtl() const { return direction_ == TextDirection::rtl; }
    // Tracks if the run represents trailing whitespace.
    bool is_ghost() const { return is_ghost_; }
    bool is_placeholder_run() const { return placeholder_run_ != nullptr; }

   private:
    size_t start_, end_;
    TextDirection direction_;
    const TextStyle* style_;
    bool is_ghost_;
    PlaceholderRun* placeholder_run_ = nullptr;
  };

  struct GlyphPosition {
    Range<size_t> code_units;
    Range<double> x_pos;

    GlyphPosition(double x_start,
                  double x_advance,
                  size_t code_unit_index,
                  size_t code_unit_width);

    void Shift(double delta);
  };

  struct GlyphLine {
    // Glyph positions sorted by x coordinate.
    const std::vector<GlyphPosition> positions;
    const size_t total_code_units;

    GlyphLine(std::vector<GlyphPosition>&& p, size_t tcu);
  };

  struct CodeUnitRun {
    // Glyph positions sorted by code unit index.
    std::vector<GlyphPosition> positions;
    Range<size_t> code_units;
    Range<double> x_pos;
    size_t line_number;
    SkFontMetrics font_metrics;
    const TextStyle* style;
    TextDirection direction;
    const PlaceholderRun* placeholder_run;

    CodeUnitRun(std::vector<GlyphPosition>&& p,
                Range<size_t> cu,
                Range<double> x,
                size_t line,
                const SkFontMetrics& metrics,
                const TextStyle& st,
                TextDirection dir,
                const PlaceholderRun* placeholder);

    void Shift(double delta);
  };

  // Holds the laid out x positions of each glyph.
  std::vector<GlyphLine> glyph_lines_;

  // Holds the positions of each range of code units in the text.
  // Sorted in code unit index order.
  std::vector<CodeUnitRun> code_unit_runs_;
  // Holds the positions of the inline placeholders.
  std::vector<CodeUnitRun> inline_placeholder_code_unit_runs_;

  // The max width of the paragraph as provided in the most recent Layout()
  // call.
  double width_ = -1.0f;
  double longest_line_ = -1.0f;
  double max_intrinsic_width_ = 0;
  double min_intrinsic_width_ = 0;
  double alphabetic_baseline_ = std::numeric_limits<double>::max();
  double ideographic_baseline_ = std::numeric_limits<double>::max();

  bool needs_layout_ = true;

  struct WaveCoordinates {
    double x_start;
    double y_start;
    double x_end;
    double y_end;

    WaveCoordinates(double x_s, double y_s, double x_e, double y_e)
        : x_start(x_s), y_start(y_s), x_end(x_e), y_end(y_e) {}
  };

  // Passes in the text and Styled Runs. text_ and runs_ will later be passed
  // into breaker_ in InitBreaker(), which is called in Layout().
  void SetText(std::vector<uint16_t> text, StyledRuns runs);

  void SetParagraphStyle(const ParagraphStyle& style);

  void SetFontCollection(std::shared_ptr<FontCollection> font_collection);

  void SetInlinePlaceholders(
      std::vector<PlaceholderRun> inline_placeholders,
      std::unordered_set<size_t> obj_replacement_char_indexes);

  // Break the text into lines.
  bool ComputeLineBreaks();

  // Break the text into runs based on LTR/RTL text direction.
  bool ComputeBidiRuns(std::vector<BidiRun>* result);

  // Calculates and populates strut based on paragraph_style_ strut info.
  void ComputeStrut(StrutMetrics* strut, SkFont& font);

  // Adjusts the ascent and descent based on the existence and type of
  // placeholder. This method sets the proper metrics to achieve the different
  // PlaceholderAlignment options.
  void ComputePlaceholder(PlaceholderRun* placeholder_run,
                          double& ascent,
                          double& descent);

  bool IsStrutValid() const;

  void UpdateLineMetrics(const SkFontMetrics& metrics,
                         const TextStyle& style,
                         double& max_ascent,
                         double& max_descent,
                         double& max_unscaled_ascent,
                         PlaceholderRun* placeholder_run,
                         size_t line_number,
                         size_t line_limit);

  // Calculate the starting X offset of a line based on the line's width and
  // alignment.
  double GetLineXOffset(double line_total_advance, bool justify_line);

  // Creates and draws the decorations onto the canvas.
  void PaintDecorations(SkCanvas* canvas,
                        const PaintRecord& record,
                        SkPoint base_offset);

  // Computes the beziers for a wavy decoration. The results will be
  // applied to path.
  void ComputeWavyDecoration(SkPath& path,
                             double x,
                             double y,
                             double width,
                             double thickness);

  // Draws the background onto the canvas.
  void PaintBackground(SkCanvas* canvas,
                       const PaintRecord& record,
                       SkPoint base_offset);

  // Draws the shadows onto the canvas.
  void PaintShadow(SkCanvas* canvas, const PaintRecord& record, SkPoint offset);

  // Obtain a Minikin font collection matching this text style.
  std::shared_ptr<minikin::FontCollection> GetMinikinFontCollectionForStyle(
      const TextStyle& style);

  // Get a default SkTypeface for a text style.
  sk_sp<SkTypeface> GetDefaultSkiaTypeface(const TextStyle& style);

  FML_DISALLOW_COPY_AND_ASSIGN(ParagraphTxt);
};

}  // namespace txt

#endif  // LIB_TXT_SRC_PARAGRAPH_TXT_H_
