import java.util.Scanner;
import java.io.File;

/**
 * Class that represents a token in the SILLY language.  
 */
public class Token
{
    public static enum Type {
	    STRING, INTEGER, IDENTIFIER, KEYWORD, OPERATOR, UNKNOWN
    }
    
    private String value;
    private Token.Type type;
    
    /**
     * Constructs an integer Token.
     *   @param number the integer value to be stored in the Token
     */
    public Token(int number) {
        this.setToken(""+number, Token.Type.INTEGER);
    }

    /**
     * Constructs a String-based Token (a string, keyword, operator, or identifier).
     *   @param str the String value to be stored in the Token
     */
    public Token(String str) {
        if (str.length() >= 2 && str.charAt(0) == '\"' && str.charAt(str.length()-1) == '\"') {
            this.setToken(str, Token.Type.STRING);
        }
        else if (str.equals("=") || str.equals("+")) {
            this.setToken(str, Token.Type.OPERATOR);
        }
        else if (str.toLowerCase().equals("output") || str.toLowerCase().equals("if")
                                                    || str.toLowerCase().equals("end")) {
            this.setToken(str, Token.Type.KEYWORD);
        }
        else {
            boolean ident = Character.isLetter(str.charAt(0));
            for (int i = 1; i < str.length(); i++) {
                if (!Character.isLetterOrDigit(str.charAt(i))) {
                    ident = false;
                }
            }
                    
            if (ident) {
                this.setToken(str, Token.Type.IDENTIFIER);
            }  
            else {
                this.setToken(str, Token.Type.UNKNOWN);
            }
        }
    }
     
    /**
     * Accesses the type of the Token
     *   @return the Token Type (as defined by the Token.Type enum)
     */
    public Token.Type getType() {
        return this.type;
    }
    
    /**
     * Sets the value and type of a Token.
     *   @param value the new (String) value of the Token
     *   @param type the new type of the Token
     */
    public void setToken(String value, Token.Type type) {
        this.value = value;
        this.type = type;
    }
    
    /**
     * Converts the Token into its String representation
     *   @return the String value of the Token
     */
    public String toString() {
        return this.value;
    }
}
