// Copyright 2019 Google LLC
// Use of this source code is governed by a BSD-style license that can be found in the LICENSE file.
#ifndef editor_DEFINED
#define editor_DEFINED

#include "modules/skplaintexteditor/include/stringslice.h"
#include "modules/skplaintexteditor/include/stringview.h"

#include "include/core/SkColor.h"
#include "include/core/SkFont.h"
#include "include/core/SkFontMgr.h"
#include "include/core/SkRefCnt.h"
#include "include/core/SkString.h"
#include "include/core/SkTextBlob.h"

#include <climits>
#include <cstdint>
#include <utility>
#include <vector>

class SkCanvas;
class SkShaper;

namespace SkPlainTextEditor {

class Editor {
    struct TextLine;
public:
    // total height in canvas display units.
    int getHeight() const { return fHeight; }

    // set display width in canvas display units
    void setWidth(int w); // may force re-shape

    // get/set current font (used for shaping and displaying text)
    const SkFont& font() const { return fFont; }
    void setFont(SkFont font);

    void setFontMgr(sk_sp<SkFontMgr> fontMgr);

    struct Text {
        const std::vector<TextLine>& fLines;
        struct Iterator {
            std::vector<TextLine>::const_iterator fPtr;
            StringView operator*() { return fPtr->fText.view(); }
            void operator++() { ++fPtr; }
            bool operator!=(const Iterator& other) const { return fPtr != other.fPtr; }
        };
        Iterator begin() const { return Iterator{fLines.begin()}; }
        Iterator end() const { return Iterator{fLines.end()}; }
    };
    // Loop over all the lines of text.  The lines are not '\0'- or '\n'-terminated.
    // For example, to dump the entire file to standard output:
    //     for (SkPlainTextEditor::StringView str : editor.text()) {
    //         std::cout.write(str.data, str.size) << '\n';
    //     }
    Text text() const { return Text{fLines}; }

    // get size of line in canvas display units.
    int lineHeight(size_t index) const { return fLines[index].fHeight; }

    struct TextPosition {
        size_t fTextByteIndex = SIZE_MAX;   // index into UTF-8 representation of line.
        size_t fParagraphIndex = SIZE_MAX;  // logical line, based on hard newline characters.
    };
    enum class Movement {
        kNowhere,
        kLeft,
        kUp,
        kRight,
        kDown,
        kHome,
        kEnd,
        kWordLeft,
        kWordRight,
    };
    TextPosition move(Editor::Movement move, Editor::TextPosition pos) const;
    TextPosition getPosition(SkIPoint);
    SkRect getLocation(TextPosition);
    // insert into current text.
    TextPosition insert(TextPosition, const char* utf8Text, size_t byteLen);
    // remove text between two positions
    TextPosition remove(TextPosition, TextPosition);

    // If dst is nullptr, returns size of given selection.
    // Otherwise, fill dst with a copy of the selection, and return the amount copied.
    size_t copy(TextPosition pos1, TextPosition pos2, char* dst = nullptr) const;
    size_t lineCount() const { return fLines.size(); }
    StringView line(size_t i) const {
        return i < fLines.size() ? fLines[i].fText.view() : StringView{nullptr, 0};
    }

    struct PaintOpts {
        SkColor4f fBackgroundColor = {1, 1, 1, 1};
        SkColor4f fForegroundColor = {0, 0, 0, 1};
        // TODO: maybe have multiple selections and cursors, each with separate colors.
        SkColor4f fSelectionColor = {0.729f, 0.827f, 0.988f, 1};
        SkColor4f fCursorColor = {1, 0, 0, 1};
        TextPosition fSelectionBegin;
        TextPosition fSelectionEnd;
        TextPosition fCursor;
    };
    void paint(SkCanvas* canvas, PaintOpts);

private:
    // TODO: rename this to TextParagraph. fLines to fParas.
    struct TextLine {
        StringSlice fText;
        sk_sp<const SkTextBlob> fBlob;
        std::vector<SkRect> fCursorPos;
        std::vector<size_t> fLineEndOffsets;
        std::vector<bool> fWordBoundaries;
        SkIPoint fOrigin = {0, 0};
        int fHeight = 0;
        bool fShaped = false;

        explicit TextLine(StringSlice t) : fText(std::move(t)) {}
        TextLine() {}
    };
    std::vector<TextLine> fLines;
    int fWidth = 0;
    int fHeight = 0;
    SkFont fFont;
    sk_sp<SkFontMgr> fFontMgr;
    bool fNeedsReshape = false;
    const char* fLocale = "en";  // TODO: make this setable

    void markDirty(TextLine*);
    void reshapeAll();
};
}  // namespace SkPlainTextEditor

static inline bool operator==(const SkPlainTextEditor::Editor::TextPosition& u,
                              const SkPlainTextEditor::Editor::TextPosition& v) {
    return u.fParagraphIndex == v.fParagraphIndex && u.fTextByteIndex == v.fTextByteIndex;
}
static inline bool operator!=(const SkPlainTextEditor::Editor::TextPosition& u,
                              const SkPlainTextEditor::Editor::TextPosition& v) { return !(u == v); }

static inline bool operator<(const SkPlainTextEditor::Editor::TextPosition& u,
                             const SkPlainTextEditor::Editor::TextPosition& v) {
    return u.fParagraphIndex < v.fParagraphIndex ||
           (u.fParagraphIndex == v.fParagraphIndex && u.fTextByteIndex < v.fTextByteIndex);
}


#endif  // editor_DEFINED
