package _VisualDVM.Visual.Syntax;
import org.fife.ui.rsyntaxtextarea.Token;

import javax.swing.text.Segment;
//сткуртура контейнер для всех текущих переменных.
//для упрощения операций.
public class TokenProvider {
    public Segment text;
    public char[] array;
    public int offset;
    public int count;
    public int end;
    // Token starting offsets are always of the form:
    // 'startOffset + (currentTokenStart-offset)', but since startOffset and
    // offset are constant, tokens' starting positions become:
    // 'newStartOffset+currentTokenStart'.
    public int newStartOffset;
    public int currentTokenStart;
    public int startTokenType; //хранить тип токена который нам передали, ради переносов
    public int currentTokenType;
    public int i;
    public int position;
    public char c;
    public boolean label_flag;
    public TokenProvider(Segment text_in, int startTokenType_in, int startOffset) {
        text = text_in;
        startTokenType = startTokenType_in; //может указывать на то, что мы продолжаем.
        array = text.array;
        offset = text.offset;
        count = text.count;
        end = offset + count;
        // Token starting offsets are always of the form:
        // 'startOffset + (currentTokenStart-offset)', but since startOffset and
        // offset are constant, tokens' starting positions become:
        // 'newStartOffset+currentTokenStart'.
        newStartOffset = startOffset - offset;
        currentTokenStart = offset;
        currentTokenType = Token.NULL; //изначально не знаем что будем обрабатывать.
        position = 0;
        i = offset;
        label_flag = false;
    }
    public void checkWrap() {
        if (startTokenType != Token.NULL) {
            start();
            startTokenType = Token.NULL;
        }
    }
    public void readNext() {
        c = array[i];
    }
    public void gotoNext() {
        ++i;
        ++position;
        //todo от греха от табов надо избавляться.
        // возникает расхожедние между реальным и табским смещением. отсюда галюны.
        // лучше бы их не отображать даже если они есть. но это к тексту файла. или как то узнавать их длину..
    }
    public boolean canRead() {
        return i < end;
    }
    public void setType(int currentTokenType_in) {
        currentTokenType = currentTokenType_in;
    }
    public void stop() {
        i = end - 1;
    }
    public void start() {
        currentTokenStart = i;
    }
    //в зоне основной строки
    //по текущему символу определяем тип уже начатого токена.
    public void detectType() {
        switch (c) {
            case ' ':
            case '\t':
            case '\r':
                currentTokenType = Token.WHITESPACE;
                break;
            case '+':
            case '-':
            case '*':
            case '/':
            case '=':
            case '(':
            case ')':
            case '[':
            case ']':
            case '<':
            case '>':
            case '{':
            case '}':
            case ',':
            case '&':
                currentTokenType = Token.OPERATOR;
                break;
            case '\'':
                currentTokenType = Token.LITERAL_CHAR;
                break;
            case '"':
                currentTokenType = Token.LITERAL_STRING_DOUBLE_QUOTE;
                break;
            case '0':
            case '1':
            case '2':
            case '3':
            case '4':
            case '5':
            case '6':
            case '7':
            case '8':
            case '9':
                currentTokenType = Token.LITERAL_NUMBER_DECIMAL_INT;
                break;
            case '.':
                //возможный кандидат на число с плавающей точкой.
                currentTokenType = Token.RESERVED_WORD_2;
                break;
            case '!':
                currentTokenType = Token.COMMENT_EOL;
                stop();
                break;
            default:
                currentTokenType = Token.IDENTIFIER;
                break;
        }
    }
    //досрочный выход из зоны переноса.
    public void SkipWrap() {
        startTokenType = Token.NULL; //перенос исключается.
        position += 6; //гарантированное непопадание в зону переноса при анализе.
        setType(Token.WHITESPACE); //стоит таб, значит переноса не будет. идет набор пробелов.
    }
}
