
function ASSERT(pred) {
    console.assert(pred, 'assert failed');
}

function LOG(...args) {
    // comment out for non-debugging
//    console.log(args);
}

function MakeCursor(CanvasKit) {
    const linePaint = new CanvasKit.Paint();
    linePaint.setColor([0,0,1,1]);
    linePaint.setStyle(CanvasKit.PaintStyle.Stroke);
    linePaint.setStrokeWidth(2);
    linePaint.setAntiAlias(true);

    const pathPaint = new CanvasKit.Paint();
    pathPaint.setColor([0,0,1,0.25]);
    linePaint.setAntiAlias(true);

    return {
        _line_paint: linePaint,    // wrap in weak-ref so we can delete it?
        _path_paint: pathPaint,
        _x: 0,
        _top: 0,
        _bottom: 0,
        _path: null,            // only use x,top,bottom if path is null
        _draws_per_sec: 2,

        // pass 0 for no-draw, pass inf. for always on
        setBlinkRate: function(blinks_per_sec) {
            this._draws_per_sec = blinks_per_sec;
        },
        place: function(x, top, bottom) {
            this._x = x;
            this._top = top;
            this._bottom = bottom;

            this.setPath(null);
        },
        setPath: function(path) {
            if (this._path) {
                this._path.delete();
            }
            this._path = path;
        },
        draw_before: function(canvas) {
            if (this._path) {
                canvas.drawPath(this._path, this._path_paint);
            }
        },
        draw_after: function(canvas) {
            if (this._path) {
                return;
            }
            if (Math.floor(Date.now() * this._draws_per_sec / 1000) & 1) {
                canvas.drawLine(this._x, this._top, this._x, this._bottom, this._line_paint);
            }
        },
    };
}

function MakeMouse() {
    return {
        _start_x: 0, _start_y: 0,
        _curr_x:  0,  _curr_y: 0,
        _active: false,

        isActive: function() {
            return this._active;
        },
        setDown: function(x, y) {
            this._start_x = this._curr_x = x;
            this._start_y = this._curr_y = y;
            this._active = true;
        },
        setMove: function(x, y) {
            this._curr_x = x;
            this._curr_y = y;
        },
        setUp: function(x, y) {
            this._curr_x = x;
            this._curr_y = y;
            this._active = false;
        },
        getPos: function(dx, dy) {
            return [ this._start_x + dx, this._start_y + dy, this._curr_x + dx, this._curr_y + dy ];
        },
    };
}

function runs_x_to_index(runs, x) {
    for (const r of runs) {
        for (let i = 1; i < r.offsets.length; i += 1) {
            if (x < r.positions[i*2]) {
                const mid = (r.positions[i*2-2] + r.positions[i*2]) * 0.5;
                if (x <= mid) {
                    return r.offsets[i-1];
                } else {
                    return r.offsets[i];
                }
            }
        }
    }
    const r = runs[runs.length-1];
    return r.offsets[r.offsets.length-1];
}

function lines_pos_to_index(lines, x, y) {
    if (y < lines[0].top) {
        return 0;
    }
    const l = lines.find((l) => y <= l.bottom);
    return l ? runs_x_to_index(l.runs, x)
             : lines[lines.length - 1].textRange.last;
}

function runs_index_to_run(runs, index) {
    const r = runs.find((r) => index <= r.offsets[r.offsets.length-1]);
    // return last if no run is found
    return r ? r : runs[runs.length-1];
}

function runs_index_to_x(runs, index) {
    const r = runs_index_to_run(runs, index);
    const i = r.offsets.findIndex((offset) => index === offset);
    return i >= 0 ? r.positions[i*2]
                  : r.positions[r.positions.length-2]; // last x
}

function lines_index_to_line_index(lines, index) {
    const l = lines.findIndex((l) => index <= l.textRange.last);
    return l >= 0 ? l : lines.length-1;
}

function lines_index_to_line(lines, index) {
  return lines[lines_index_to_line_index(lines, index)];
}

function lines_indices_to_path(lines, a, b, width) {
    if (a == b) {
        return null;
    }
    if (a > b) { [a, b] = [b, a]; }

    const path = new CanvasKit.Path();
    const la = lines_index_to_line(lines, a);
    const lb = lines_index_to_line(lines, b);
    const ax = runs_index_to_x(la.runs, a);
    const bx = runs_index_to_x(lb.runs, b);
    if (la == lb) {
        path.addRect([ax, la.top, bx, la.bottom]);
    } else {
        path.addRect([ax, la.top, width, la.bottom]);
        path.addRect([0, lb.top, bx, lb.bottom]);
        if (la.bottom < lb.top) {
            path.addRect([0, la.bottom, width, lb.top]);   // extra lines inbetween
        }
    }
    return path;
}

function string_del(str, start, end) {
    return str.slice(0, start) + str.slice(end, str.length);
}

function make_default_paint() {
    const p = new CanvasKit.Paint();
    p.setAntiAlias(true);
    return p;
}

function make_default_font(tf) {
    const font = new CanvasKit.Font(tf);
    font.setSubpixel(true);
    return font;
}

function MakeStyle(length) {
    return {
        _length: length,
        typeface: null,
        size: null,
        color: null,
        bold: null,
        italic: null,

        _check_toggle: function(src, dst) {
            if (src == 'toggle') {
                return !dst;
            } else {
                return src;
            }
        },

        // returns true if we changed something affecting layout
        mergeFrom: function(src) {
            let layoutChanged = false;

            if (src.typeface && this.typeface !== src.typeface) {
                this.typeface = src.typeface;
                layoutChanged = true;
            }
            if (src.size && this.size !== src.size) {
                this.size = src.size;
                layoutChanged = true;
            }
            if (src.color) {
                this.color = src.color;
                delete this.shaderIndex;    // we implicitly delete shader if there is a color
            }

            if (src.bold) {
                this.bold = this._check_toggle(src.bold, this.bold);
            }
            if (src.italic) {
                this.italic = this._check_toggle(src.italic, this.italic);
            }
            if (src.wavy) {
                this.wavy = this._check_toggle(src.wavy, this.wavy);
            }

            if (src.size_add) {
                this.size += src.size_add;
                layoutChanged = true;
            }

            if ('shaderIndex' in src) {
                if (src.shaderIndex >= 0) {
                    this.shaderIndex = src.shaderIndex;
                } else {
                    delete this.shaderIndex;
                }
            }
            return layoutChanged;
        }
    };
}

function MakeEditor(text, style, cursor, width) {
    const ed = {
        _text: text,
        _lines: null,
        _cursor: cursor,
        _width: width,
        _index: { start: 0, end: 0 },
        _styles: null,
        // drawing
        _X: 0,
        _Y: 0,
        _paint: make_default_paint(),
        _font: make_default_font(style.typeface),

        getLines: function() { return this._lines; },

        width: function() {
            return this._width;
        },
        height: function() {
            return this._lines[this._lines.length-1].bottom;
        },
        bounds: function() {
            return [this._X, this._Y, this._X + this.width(), this._Y + this.height()];
        },
        setXY: function(x, y) {
            this._X = x;
            this._Y = y;
        },

        _rebuild_selection: function() {
            const a = this._index.start;
            const b = this._index.end;
            ASSERT(a >= 0 && a <= b && b <= this._text.length);
            if (a === b) {
                const l = lines_index_to_line(this._lines, a);
                const x = runs_index_to_x(l.runs, a);
                this._cursor.place(x, l.top, l.bottom);
            } else {
                this._cursor.setPath(lines_indices_to_path(this._lines, a, b, this._width));
            }
        },
        setIndex: function(i) {
            this._index.start = this._index.end = i;
            this._rebuild_selection();
        },
        setIndices: function(a, b) {
            if (a > b) { [a, b] = [b, a]; }
            this._index.start = a;
            this._index.end = b;
            this._rebuild_selection();
        },
        moveDX: function(dx) {
            let index;
            if (this._index.start == this._index.end) {
                // just adjust and pin
                index = Math.max(Math.min(this._index.start + dx, this._text.length), 0);
            } else {
                // 'deselect' the region, and turn it into just a single index
                index = dx < 0 ? this._index.start : this._index.end;
            }
            this.setIndex(index);
        },
        moveDY: function(dy) {
            let index = (dy < 0) ? this._index.start : this._index.end;
            const i = lines_index_to_line_index(this._lines, index);
            if (dy < 0 && i === 0) {
                index = 0;
            } else if (dy > 0 && i == this._lines.length - 1) {
                index = this._text.length;
            } else {
                const x = runs_index_to_x(this._lines[i].runs, index);
                // todo: statefully track "original" x when an up/down sequence started,
                //       so we can avoid drift.
                index = runs_x_to_index(this._lines[i+dy].runs, x);
            }
            this.setIndex(index);
        },

        _validateStyles: function() {
            const len = this._styles.reduce((sum, style) => sum + style._length, 0);
            ASSERT(len === this._text.length);
        },
        _validateBlocks: function(blocks) {
            const len = blocks.reduce((sum, block) => sum + block.length, 0);
            ASSERT(len === this._text.length);
        },

        _buildLines: function() {
            this._validateStyles();

            const blocks = [];
            let block = null;
            for (const s of this._styles) {
                if (!block || (block.typeface === s.typeface && block.size === s.size)) {
                    if (!block) {
                        block = { length: 0, typeface: s.typeface, size: s.size };
                    }
                    block.length += s._length;
                } else {
                    blocks.push(block);
                    block = { length: s._length, typeface: s.typeface, size: s.size };
                }
            }
            blocks.push(block);
            this._validateBlocks(blocks);

            this._lines = CanvasKit.ParagraphBuilder.ShapeText(this._text, blocks, this._width);
            this._rebuild_selection();

            // add textRange to each run, to aid in drawing
            this._runs = [];
            for (const l of this._lines) {
                for (const r of l.runs) {
                    r.textRange = { start: r.offsets[0], end: r.offsets[r.offsets.length-1] };
                    this._runs.push(r);
                }
            }
        },

        // note: this does not rebuild lines/runs, or update the cursor,
        //       but it does edit the text and styles
        // returns true if it deleted anything
        _deleteRange: function(start, end) {
            ASSERT(start >= 0 && end <= this._text.length);
            ASSERT(start <= end);
            if (start === end) {
                return false;
            }

            this._delete_style_range(start, end);
            // Do this after shrink styles (we use text.length in an assert)
            this._text = string_del(this._text, start, end);
        },
        deleteSelection: function(direction) {
            let start = this._index.start;
            if (start == this._index.end) {
                if (direction < 0) {
                    if (start == 0) {
                        return;     // nothing to do
                    }
                    this._deleteRange(start - 1, start);
                    start -= 1;
                } else {
                    if (start >= this._text.length) {
                        return;     // nothing to do
                    }
                    this._deleteRange(start, start + 1);
                }
            } else {
                this._deleteRange(start, this._index.end);
            }
            this._index.start = this._index.end = start;
            this._buildLines();
        },
        insert: function(charcode) {
            const len = charcode.length;
            if (this._index.start != this._index.end) {
                this.deleteSelection();
            }
            const index = this._index.start;

            // do this before edit the text (we use text.length in an assert)
            const [i, prev_len] = this.find_style_index_and_prev_length(index);
            this._styles[i]._length += len;

            // now grow the text
            this._text = this._text.slice(0, index) + charcode + this._text.slice(index);

            this._index.start = this._index.end = index + len;
            this._buildLines();
        },

        draw: function(canvas, shaders) {
            canvas.save();
            canvas.translate(this._X, this._Y);

            this._cursor.draw_before(canvas);

            const runs = this._runs;
            const styles = this._styles;
            const f = this._font;
            const p = this._paint;

            let s = styles[0];
            let sindex = 0;
            let s_start = 0;
            let s_end = s._length;

            let r = runs[0];
            let rindex = 0;

            let start = 0;
            let end = 0;
            while (start < this._text.length) {
                while (r.textRange.end <= start) {
                    r = runs[++rindex];
                    if (!r) {
                        // ran out of runs, so the remaining text must just be WS
                        break;
                    }
                }
                if (!r) break;
                while (s_end <= start) {
                    s = styles[++sindex];
                    s_start = s_end;
                    s_end += s._length;
                }
                end = Math.min(r.textRange.end, s_end);

                LOG('New range: ', start, end,
                    'from run', r.textRange.start, r.textRange.end,
                    'style', s_start, s_end);

                // check that we have anything to draw
                if (r.textRange.start >= end) {
                    start = end;
                    continue;  // could be a span of WS with no glyphs
                }

//              f.setTypeface(r.typeface); // r.typeface is always null (for now)
                f.setSize(r.size);
                f.setEmbolden(s.bold);
                f.setSkewX(s.italic ? -0.2 : 0);
                p.setColor(s.color ? s.color : [0,0,0,1]);
                p.setShader(s.shaderIndex >= 0 ? shaders[s.shaderIndex] : null);

                let gly = r.glyphs;
                let pos = r.positions;
                if (start > r.textRange.start || end < r.textRange.end) {
                    // search for the subset of glyphs to draw
                    let glyph_start, glyph_end;
                    for (let i = 0; i < r.offsets.length; ++i) {
                        if (r.offsets[i] >= start) {
                            glyph_start = i;
                            break;
                        }
                    }
                    for (let i = glyph_start+1; i < r.offsets.length; ++i) {
                        if (r.offsets[i] >= end) {
                            glyph_end = i;
                            break;
                        }
                    }
                    LOG('    glyph subrange', glyph_start, glyph_end);
                    gly = gly.slice(glyph_start, glyph_end);
                    pos = pos.slice(glyph_start*2, glyph_end*2);
                } else {
                    LOG('    use entire glyph run');
                }

                let working_pos = pos;
                if (s.wavy) {
                    const xscale = 0.05;
                    const yscale = r.size * 0.125;
                    let wavy = [];
                    for (let i = 0; i < pos.length; i += 2) {
                        const x = pos[i + 0];
                        wavy.push(x);
                        wavy.push(pos[i + 1] + Math.sin(x * xscale) * yscale);
                    }
                    working_pos = new Float32Array(wavy);
                }
                canvas.drawGlyphs(gly, working_pos, 0, 0, f, p);

                p.setShader(null);  // in case our caller deletes their shader(s)

                start = end;
            }

            this._cursor.draw_after(canvas);
            canvas.restore();
        },

        // Styling

        // returns [index, prev total length before this style]
        find_style_index_and_prev_length: function(index) {
            let len = 0;
            for (let i = 0; i < this._styles.length; ++i) {
                const l = this._styles[i]._length;
                len += l;
                // < favors the latter style if index is between two styles
                if (index < len) {
                    return [i, len - l];
                }
            }
            ASSERT(len === this._text.length);
            return [this._styles.length-1, len];
        },
        _delete_style_range: function(start, end) {
            // shrink/remove styles
            //
            // [.....][....][....][.....]  styles
            //    [..................]     start...end
            //
            // - trim the first style
            // - remove the middle styles
            // - trim the last style

            let N = end - start;
            let [i, prev_len] = this.find_style_index_and_prev_length(start);
            let s = this._styles[i];
            if (start > prev_len) {
                // we overlap the first style (but not entirely
                const skip = start - prev_len;
                ASSERT(skip < s._length);
                const shrink = Math.min(N, s._length - skip);
                ASSERT(shrink > 0);
                s._length -= shrink;
                N -= shrink;
                if (N === 0) {
                    return;
                }
                i += 1;
                ASSERT(i < this._styles.length);
            }
            while (N > 0) {
                s = this._styles[i];
                if (N >= s._length) {
                    N -= s._length;
                    this._styles.splice(i, 1);
                } else {
                    s._length -= N;
                    break;
                }
            }
        },

        applyStyleToRange: function(style, start, end) {
            if (start > end) { [start, end] = [end, start]; }
            ASSERT(start >= 0 && end <= this._text.length);
            if (start === end) {
                return;
            }

            LOG('trying to apply', style, start, end);
            let i;
            for (i = 0; i < this._styles.length; ++i) {
                if (start <= this._styles[i]._length) {
                    break;
                }
                start -= this._styles[i]._length;
                end -= this._styles[i]._length;
            }

            let s = this._styles[i];
            // do we need to fission off a clean subset for the head of s?
            if (start > 0) {
                const ns = Object.assign({}, s);
                s._length = start;
                ns._length -= start;
                LOG('initial splice', i, start, s._length, ns._length);
                i += 1;
                this._styles.splice(i, 0, ns);
                end -= start;
                // we don't use start any more
            }
            // merge into any/all whole styles we overlap
            let layoutChanged = false;
            while (end >= this._styles[i]._length) {
                LOG('whole run merging for style index', i)
                layoutChanged |= this._styles[i].mergeFrom(style);
                end -= this._styles[i]._length;
                i += 1;
                if (end == 0) {
                    break;
                }
            }
            // do we partially cover the last run
            if (end > 0) {
                s = this._styles[i];
                const ns = Object.assign({}, s);    // the new first half
                ns._length = end;
                s._length -= end;                   // trim the (unchanged) tail
                LOG('merging tail', i, ns._length, s._length);
                layoutChanged |= ns.mergeFrom(style);
                this._styles.splice(i, 0, ns);
            }

            this._validateStyles();
            LOG('after applying styles', this._styles);

            if (layoutChanged) {
                this._buildLines();
            }
        },
        applyStyleToSelection: function(style) {
            this.applyStyleToRange(style, this._index.start, this._index.end);
        },
    };

    const s = MakeStyle(ed._text.length);
    s.mergeFrom(style);
    ed._styles = [ s ];
    ed._buildLines();
    return ed;
}
