package org.spoofax.jsglr2.parser;

public class Position {

    /**
     * The offset in the input string, starts counting at 0 (consistent with Java string indexing).
     */
    final public int offset;

    /**
     * The line number of the current offset, starts counting at 1 (consistent with IDE cursor position).
     */
    final public int line;

    /**
     * The column number of the current offset, starts counting at 1 (consistent with IDE cursor position).
     */
    final public int column;

    /**
     * Basic constructor.
     */
    public Position(int offset, int line, int column) {
        this.offset = offset;
        this.line = line;
        this.column = column;
    }

    /**
     * Clones a Position.
     *
     * @param p
     *            The Position to clone.
     */
    public Position(Position p) {
        this.offset = p.offset;
        this.line = p.line;
        this.column = p.column;
    }

    public static Position atEnd(String string) {
        String[] lines = string.split("\n");

        if(lines.length > 0) {
            int line = lines.length;
            int column = lines[line - 1].length() + 1;

            if(string.endsWith("\n")) {
                line++;
                column = 1;
            }

            return new Position(string.length(), line, column);
        } else
            return new Position(string.length(), 2, 1);
    }

    public static Position atOffset(String string, int offset) {
        return atEnd(string.substring(0, offset));
    }

    /**
     * @return A new position that represents the position right of the current position.
     */
    public Position nextColumn() {
        return new Position(offset + 1, line, column + 1);
    }

    /**
     * Should only be called when the character at the current position is a newline character.
     *
     * @return A new position that represents the first column on the line after the current position.
     */
    public Position nextLine() {
        return new Position(offset + 1, line + 1, 1);
    }

    /**
     * Step from the current position in the given string by the given width.
     *
     * @return A new position that presents the position after the step in the given string.
     */
    public Position step(String string, int width) {
        return atEnd(string.substring(0, offset + width));
    }

    public String coordinatesToString() {
        return line + ":" + column;
    }

    @Override public String toString() {
        return "l: " + line + " c: " + column + " offset: " + offset;
    }

    @Override public int hashCode() {
        final int prime = 31;
        int result = 1;
        result = prime * result + column;
        result = prime * result + line;
        result = prime * result + offset;
        return result;
    }

    @Override public boolean equals(Object obj) {
        if(this == obj)
            return true;
        if(obj == null)
            return false;
        if(getClass() != obj.getClass())
            return false;
        Position other = (Position) obj;
        if(column != other.column)
            return false;
        if(line != other.line)
            return false;
        if(offset != other.offset)
            return false;
        return true;
    }


}

@@ -2098,29 +2098,29 @@
 tion in the 
-given
+input
  string by t
@@ -2267,33 +2267,38 @@
 ion step(String 
-s
+inputS
 tring, int width
@@ -2313,56 +2313,433 @@
     
-return atEnd(string.substring(0, offset + width)
+int offset = this.offset;%0A        int line = this.line;%0A        int column = this.column;%0A        int end = Integer.min(inputString.length(), offset + width);%0A        for (; offset %3C end; offset++) %7B%0A            if (inputString.charAt(offset) == '%5Cn') %7B%0A                line++;%0A                column = 1;%0A            %7D else %7B%0A                column++;%0A            %7D%0A        %7D%0A        return new Position(offset, line, column
 );%0A 
@@ -3462,19 +3462,23 @@
     
-if(
+return 
 column 
-!
+=
 = ot
@@ -3491,53 +3491,18 @@
 lumn
-)%0A            return false;%0A        if(
+ && 
 line 
-!
+=
 = ot
@@ -3513,55 +3513,20 @@
 line
-)%0A            return false;%0A        if(
+ && 
 offset 
-!
+=
 = ot
@@ -3539,55 +3539,8 @@
 fset
-)%0A            return false;%0A        return true
 ;%0A  

Optimize Position.step