/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 * 
 *   http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */

package org.apache.uima.cas.test;

import org.apache.uima.analysis_component.JCasAnnotator_ImplBase;
import org.apache.uima.jcas.JCas;

public class SubiteratorAnnotator extends JCasAnnotator_ImplBase {

  public SubiteratorAnnotator() {
    super();
  }

  public void process(JCas jCas) {
    String text = jCas.getDocumentText();
    boolean isInToken = false;
    int tokenStart = 0;
    for (int i = 0; i < text.length(); i++) {
      char c = text.charAt(i);
      if (Character.isLetterOrDigit(c)) {
        if (!isInToken) {
          isInToken = true;
          tokenStart = i;
        }
      } else {
        if (isInToken) {
          isInToken = false;
          Token token = new Token(jCas);
          token.setBegin(tokenStart);
          token.setEnd(i);
          token.addToIndexes();
        }
      }
    }
    if (isInToken) {
      Token token = new Token(jCas);
      token.setBegin(tokenStart);
      token.setEnd(text.length());
      token.addToIndexes();
    }

    int sentenceStart = 0;
    for (int i = 0; i < text.length(); i++) {
      if (text.charAt(i) == '.') {
        Sentence sentence = new Sentence(jCas);
        sentence.setBegin(sentenceStart);
        sentence.setEnd(i+1);
        sentence.addToIndexes();
        sentenceStart = i + 1;
      }
    }
    
  }

}
