package com.reason.ide;

import com.reason.merlin.types.MerlinPosition;
import org.jetbrains.annotations.NotNull;

import java.util.ArrayList;
import java.util.List;

// Copied from ocaml-ide
public class LineNumbering {

    private List<Integer> lineIndex = new ArrayList<>();

    public LineNumbering(CharSequence buffer) {
        this.lineIndex.add(0);
        int i = 0;
        while (i < buffer.length()) {
            if (buffer.charAt(i) == '\n') {
                lineIndex.add(i + 1);
            }
            i++;
        }
        lineIndex.add(Integer.MAX_VALUE);
    }

    public Integer positionToOffset(@NotNull MerlinPosition position) {
        return this.lineIndex.get(position.line - 1) + position.col;
    }

    public Integer positionToOffset(int line, int col) {
        return this.lineIndex.get(line) + col;
    }

    public MerlinPosition offsetToPosition(int offset) {
        return this.bisect(offset, 0, this.lineIndex.size() - 1);
    }

    private MerlinPosition bisect(int offset, int start, int end) {
        if (end - start == 1) {
            return new MerlinPosition(start + 1, offset - this.lineIndex.get(start));
        }

        int mid = (start + end) / 2;
        if (between(offset, start, mid)) {
            return bisect(offset, start, mid);
        } else {
            return bisect(offset, mid, end);
        }
    }

    private boolean between(int offset, int start, int end) {
        return this.lineIndex.get(start) <= offset && this.lineIndex.get(end) > offset;
    }
}

@@ -665,51 +665,204 @@
     
-return this.lineIndex.get(position.line - 1
+int index = position.line - 1;%0A        if (index %3C 0) %7B%0A            index = 0;%0A        %7D%0A        int lines = this.lineIndex.size();%0A        return this.lineIndex.get(index %3E= lines ? lines : index
 ) + 

fix IndexOutOfBound exception