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

        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
