/*
 * Lexan.java
 *
 * Created on March 10, 2006, 5:58 PM
 *
 * To change this template, choose Tools | Template Manager
 * and open the template in the editor.
 */

package cz.pcland.sat;
import cz.pcland.sat.tokens.*;
/**
 *
 * @author petr
 */
public class Lexan {
    String str;
    int pointer = 0;
    char nextChar = ' ';
    boolean eof = false;
    
    public char getNextChar() {
        if(pointer >= str.length()) {
            eof = true;
            return '$';
        } else {
            return str.charAt(pointer++);
        }
    }
    
    public void putBack() {
        pointer--;
    }
    
    public void skipSpaces() {
        while(getNextChar() == ' ') {}
        putBack();
    }
    
    public char lookAtNext(){
        if(pointer >= str.length()) {
            eof = true;
            return '$';
        }else {
            return str.charAt(pointer);
        }
    }
    
    public BaseToken readToken() {  
        skipSpaces();
        nextChar = getNextChar();
        
        
        if(eof) return new TokenEOF();
        
        if(nextChar == 'c') { 
            if(lookAtNext() == ' ' || lookAtNext() == '\n') {
                skipLine();
                skipSpaces();
                nextChar = getNextChar();
                if(eof) return new TokenEOF();
            }
        }
        
        if(nextChar == 'p'){
            return new TokenParams();
        }
        
        if(nextChar == '%'){
            return new TokenClausesEnd();
        }
        
        if(nextChar >= 'a' && nextChar <= 'z') {
            String word = String.valueOf(nextChar);

            if(eof) return new TokenEOF();
            while(lookAtNext() >= 'a' && lookAtNext() <= 'z'){
                word += String.valueOf(getNextChar()); 
                if(eof) return new TokenEOF();
            }
            return new TokenWord(word);
        }
        
        
        
        if(nextChar >= '0' && nextChar <= '9') {
            String num = String.valueOf(nextChar);
            
            if(eof) return new TokenEOF();
            while(lookAtNext() >= '0' && lookAtNext() <= '9') {
                num += String.valueOf(getNextChar());
                if(eof) return new TokenEOF();
            }
            return new TokenNum(Integer.parseInt(num));
        }
        
        if(nextChar == '-'){
            nextChar = getNextChar();
            if(nextChar >= '0' && nextChar <= '9'){
                String num = String.valueOf(nextChar);
              
                if(eof) return new TokenEOF();
                while(lookAtNext() >= '0' && lookAtNext() <= '9') {   
                    num += String.valueOf(getNextChar());
                    if(eof) return new TokenEOF();
                }
                return new TokenNegatedNum(Integer.parseInt(num));
            }
        }
        
        if(nextChar == '\n'){
            return new TokenEOL();
        }
        
        
        if(eof) return new TokenEOF();
        return new TokenUnknown();
    }
    
    public void skipLine() {
        while(true){
            if(nextChar == '\n' ||  eof) break;
            nextChar = getNextChar();
        }

        putBack();
    }
    
    /** Creates a new instance of Lexan */
    public Lexan(String str) {
        this.str = str;
        pointer = 0;
    }
    
}
