package org.oblodiff.token.text.simple;

import java.util.Collection;
import org.oblodiff.token.api.Token;
import org.oblodiff.token.text.TextualSplittableToken;

import java.util.List;
import java.util.Stack;

/**
 * This is a document is a full text that is simple in terms of just plain text. It consists of paragraphs, sentences,
 * words and characters.
 *
 * @since 1.0.0
 * @author Christian Rösch &lt;christianroesch@gmx.net&gt;
 */
public class Document extends TextualSplittableToken {

    private static final Character CARRIAGE_RETURN = '\r';
    private static final Character LINE_FEED = '\n';

    public Document(String s) {
        super(s);
    }

    @Override
    protected boolean shouldSplitAt(int i, Character character) {
        final boolean isCarriageReturn = character.equals(CARRIAGE_RETURN);
        return (isCarriageReturn || character.equals(LINE_FEED)) && containsBreakTillNextNonWhitespace(i + 1,
            isCarriageReturn);
    }

    private boolean containsBreakTillNextNonWhitespace(int begin, boolean isCarriageReturn) {
        for (int i = begin; i < getContent().length(); ++i) {
            final Character character = getContent().charAt(i);

            if (character.equals(CARRIAGE_RETURN)) {
                return true;
            }

            if (character.equals(LINE_FEED) && (i > begin || !isCarriageReturn)) {
                return true;
            }

            if (String.valueOf(character.charValue()).matches("\\S")) {
                return false;
            }
        }
        return false;
    }

    @Override
    protected Token newToken(String content) {
        return new Sentence(content);
    }

    @Override
    protected void endReached(Collection<Token> children, int begin, Character cc) {
        final Stack<Character> whitespaces = new Stack<>();

        for (int i = getContent().length() - 1; i >= begin; --i) {
            final Character character = getContent().charAt(i);

            if (String.valueOf(character.charValue()).matches("\\s")) {
                whitespaces.push(character);
            } else {
                break;
            }
        }
        addToken(children, begin, getContent().length() - whitespaces.size());
        while (!whitespaces.isEmpty()) {
            children.add(new org.oblodiff.token.text.Character(whitespaces.pop()));
        }
    }

    @Override
    protected int addDivider(Collection<Token> children, int begin, Character cc) {
        int inserted = 0;
        for (int i = begin; i < getContent().length(); ++i) {
            final Character character = getContent().charAt(i);

            if (String.valueOf(character.charValue()).matches("\\s")) {
                children.add(new org.oblodiff.token.text.Character(character));
                ++inserted;
            } else {
                break;
            }
        }

        return inserted;
    }
}

@@ -160,31 +160,8 @@
 n;%0A%0A
-import java.util.List;%0A
 impo
@@ -207,16 +207,22 @@
 ocument 
+which 
 is a ful
@@ -271,16 +271,26 @@
 in text.
+%0A * %3Cp%3E%0A *
  It cons
@@ -319,19 +319,16 @@
 ntences,
-%0A *
  words a
@@ -342,16 +342,213 @@
 acters.%0A
+ * %3C/p%3E%0A *%0A * XXX I think it is not a good idea to have two Document classes (line based). This makes it impossible for API clients%0A * to use both of them, unless they reference it full qualified.%0A
  *%0A * @s
@@ -790,16 +790,116 @@
  '%5Cn';%0A%0A
+    /**%0A     * Dedicated constructor.%0A     *%0A     * @param content must not be %7B@code null%7D%0A     */%0A
     publ
@@ -914,16 +914,28 @@
 ent(
+final 
 String 
-s
+content
 ) %7B%0A
@@ -948,17 +948,23 @@
   super(
-s
+content
 );%0A    %7D
@@ -1019,14 +1019,26 @@
 tAt(
-int i,
+final int i, final
  Cha
@@ -1133,16 +1133,17 @@
 ETURN);%0A
+%0A
         
@@ -1337,16 +1337,22 @@
 tespace(
+final 
 int begi
@@ -1353,16 +1353,22 @@
 t begin,
+ final
  boolean
@@ -1857,32 +1857,33 @@
     %7D%0A        %7D%0A
+%0A
         return f
@@ -1938,16 +1938,22 @@
 ewToken(
+final 
 String c
@@ -2051,16 +2051,22 @@
 Reached(
+final 
 Collecti
@@ -2076,32 +2076,38 @@
 Token%3E children,
+ final
  int begin, Char
@@ -2488,32 +2488,33 @@
     %7D%0A        %7D%0A
+%0A
         addToken
@@ -2572,24 +2572,25 @@
 es.size());%0A
+%0A
         whil
@@ -2762,16 +2762,22 @@
 Divider(
+final 
 Collecti
@@ -2795,16 +2795,22 @@
 hildren,
+ final
  int beg
@@ -2855,16 +2855,17 @@
 ed = 0;%0A
+%0A
         

Fix the javadoc and add missing finals.