package com.bluejay.repository;

import android.support.annotation.ColorInt;
import android.text.SpannableStringBuilder;
import android.text.style.*;

// It would be preferable to implement Editable and wrap a SpannableStringBuilder,
// instead of extending it directly. However, that causes the EditText to act glitchy.
// See https://stackoverflow.com/q/45125759/4077294 for more info.
public class ColoredText extends SpannableStringBuilder {
    private int index;

    public ColoredText(String rawText) {
        super(rawText);
    }

    public void colorWith(ColoringList colorings) {
        for (int i = 0; i < colorings.count(); i++) {
            long coloring = colorings.get(i);
            this.advance(getColor(coloring), getCount(coloring));
        }
    }

    private void advance(@ColorInt int color, int count) {
        assert count > 0;
        assert this.index + count <= this.length();

        Object span = new ForegroundColorSpan(color);
        this.setSpan(span, this.index, this.index + count, SPAN_INCLUSIVE_EXCLUSIVE);
        this.index += count;
    }

    @ColorInt
    private static int getColor(long coloring) {
        return (int)(coloring >> 32);
    }

    private static int getCount(long coloring) {
        return (int)coloring;
    }
}

@@ -785,32 +785,536 @@
     %7D%0D%0A    %7D%0D%0A%0D%0A
+    @Override%0D%0A    public SpannableStringBuilder replace(int start, int end, CharSequence tb, int tbstart, int tbend) %7B%0D%0A        // If text is deleted or inserted while the highlighter is running, make sure the regions%0D%0A        // of text it highlights stays in sync with the source code.%0D%0A        int count = end - start;%0D%0A        int tbcount = tbend - tbstart;%0D%0A        int diff = tbcount - count;%0D%0A        this.index += diff;%0D%0A%0D%0A        return super.replace(start, end, tb, tbstart, tbend);%0D%0A    %7D%0D%0A%0D%0A
     private void

Fix bug where modifying text while the highlighter was running would cause subsequent colorings to misalign.