// Copyright 2016 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef NGInlineNode_h
#define NGInlineNode_h

#include "core/CoreExport.h"
#include "core/layout/ng/ng_layout_input_node.h"
#include "platform/fonts/FontFallbackPriority.h"
#include "platform/fonts/shaping/ShapeResult.h"
#include "platform/heap/Handle.h"
#include "platform/text/TextDirection.h"
#include "wtf/text/WTFString.h"
#include <unicode/ubidi.h>
#include <unicode/uscript.h>

namespace blink {

class ComputedStyle;
class LayoutBlockFlow;
class LayoutObject;
class LayoutUnit;
class NGConstraintSpace;
class NGLayoutInlineItem;
class NGLayoutInlineItemRange;
class NGLayoutInlineItemsBuilder;
class NGLineBuilder;
class NGPhysicalFragment;

// Represents an inline node to be laid out.
class CORE_EXPORT NGInlineNode : public NGLayoutInputNode {
 public:
  NGInlineNode(LayoutObject* start_inline, const ComputedStyle* block_style);
  ~NGInlineNode() override;

  NGPhysicalFragment* Layout(NGConstraintSpace*) override;
  void LayoutInline(NGConstraintSpace*, NGLineBuilder*);
  NGInlineNode* NextSibling() override;
  LayoutObject* GetLayoutObject() override;

  // Prepare inline and text content for layout. Must be called before
  // calling the Layout method.
  void PrepareLayout();

  String Text(unsigned start_offset, unsigned end_offset) const {
    return text_content_.substring(start_offset, end_offset);
  }

  Vector<NGLayoutInlineItem>& Items() { return items_; }
  NGLayoutInlineItemRange Items(unsigned start_index, unsigned end_index);

  LayoutBlockFlow* GetLayoutBlockFlow() const;
  void GetLayoutTextOffsets(Vector<unsigned, 32>*);

  bool IsBidiEnabled() const { return is_bidi_enabled_; }

  DECLARE_VIRTUAL_TRACE();

 protected:
  NGInlineNode();  // This constructor is only for testing.
  void CollectInlines(LayoutObject* start, LayoutObject* last);
  void CollectInlines(LayoutObject* start,
                      LayoutObject* last,
                      NGLayoutInlineItemsBuilder*);
  void SegmentText();
  void ShapeText();

  LayoutObject* start_inline_;
  LayoutObject* last_inline_;
  RefPtr<const ComputedStyle> block_style_;

  Member<NGInlineNode> next_sibling_;

  // Text content for all inline items represented by a single NGInlineNode
  // instance. Encoded either as UTF-16 or latin-1 depending on content.
  String text_content_;
  Vector<NGLayoutInlineItem> items_;

  // TODO(kojii): This should move to somewhere else when we move PrepareLayout
  // to the correct place.
  bool is_bidi_enabled_ = false;
};

// Class representing a single text node or styled inline element with text
// content segmented by style, text direction, sideways rotation, font fallback
// priority (text, symbol, emoji, etc) and script (but not by font).
// In this representation TextNodes are merged up into their parent inline
// element where possible.
class NGLayoutInlineItem {
 public:
  NGLayoutInlineItem(unsigned start,
                     unsigned end,
                     const ComputedStyle* style,
                     LayoutObject* layout_object = nullptr)
      : start_offset_(start),
        end_offset_(end),
        bidi_level_(UBIDI_LTR),
        script_(USCRIPT_INVALID_CODE),
        fallback_priority_(FontFallbackPriority::Invalid),
        rotate_sideways_(false),
        style_(style),
        layout_object_(layout_object) {
    DCHECK(end >= start);
  }

  unsigned StartOffset() const { return start_offset_; }
  unsigned EndOffset() const { return end_offset_; }
  TextDirection Direction() const {
    return bidi_level_ & 1 ? TextDirection::kRtl : TextDirection::kLtr;
  }
  UBiDiLevel BidiLevel() const { return bidi_level_; }
  UScriptCode Script() const { return script_; }
  const ComputedStyle* Style() const { return style_; }
  LayoutObject* GetLayoutObject() const { return layout_object_; }

  void SetEndOffset(unsigned);

  LayoutUnit InlineSize() const;

  static void Split(Vector<NGLayoutInlineItem>&,
                    unsigned index,
                    unsigned offset);
  static unsigned SetBidiLevel(Vector<NGLayoutInlineItem>&,
                               unsigned index,
                               unsigned end_offset,
                               UBiDiLevel);

 private:
  unsigned start_offset_;
  unsigned end_offset_;
  UBiDiLevel bidi_level_;
  UScriptCode script_;
  FontFallbackPriority fallback_priority_;
  bool rotate_sideways_;
  const ComputedStyle* style_;
  Vector<RefPtr<const ShapeResult>> shape_results_;
  LayoutObject* layout_object_;

  friend class NGInlineNode;
};

DEFINE_TYPE_CASTS(NGInlineNode,
                  NGLayoutInputNode,
                  node,
                  node->Type() == NGLayoutInputNode::kLegacyInline,
                  node.Type() == NGLayoutInputNode::kLegacyInline);

// A vector-like object that points to a subset of an array of
// |NGLayoutInlineItem|.
// The source vector must keep alive and must not resize while this object
// is alive.
class NGLayoutInlineItemRange {
  STACK_ALLOCATED();

 public:
  NGLayoutInlineItemRange(Vector<NGLayoutInlineItem>*,
                          unsigned start_index,
                          unsigned end_index);

  unsigned StartIndex() const { return start_index_; }
  unsigned EndIndex() const { return start_index_ + size_; }
  unsigned Size() const { return size_; }

  NGLayoutInlineItem& operator[](unsigned index) {
    RELEASE_ASSERT(index < size_);
    return start_item_[index];
  }
  const NGLayoutInlineItem& operator[](unsigned index) const {
    RELEASE_ASSERT(index < size_);
    return start_item_[index];
  }

  using iterator = NGLayoutInlineItem*;
  using const_iterator = const NGLayoutInlineItem*;
  iterator begin() { return start_item_; }
  iterator end() { return start_item_ + size_; }
  const_iterator begin() const { return start_item_; }
  const_iterator end() const { return start_item_ + size_; }

 private:
  NGLayoutInlineItem* start_item_;
  unsigned size_;
  unsigned start_index_;
};

}  // namespace blink

#endif  // NGInlineNode_h
