// 
// Decompiled by Procyon v0.6.0
// 

package org.jline.jansi.io;

import java.util.ArrayList;
import java.io.IOException;
import java.util.Iterator;
import java.io.OutputStream;

public class AnsiProcessor
{
    protected final OutputStream os;
    protected static final int ERASE_SCREEN_TO_END = 0;
    protected static final int ERASE_SCREEN_TO_BEGINING = 1;
    protected static final int ERASE_SCREEN = 2;
    protected static final int ERASE_LINE_TO_END = 0;
    protected static final int ERASE_LINE_TO_BEGINING = 1;
    protected static final int ERASE_LINE = 2;
    protected static final int ATTRIBUTE_INTENSITY_BOLD = 1;
    protected static final int ATTRIBUTE_INTENSITY_FAINT = 2;
    protected static final int ATTRIBUTE_ITALIC = 3;
    protected static final int ATTRIBUTE_UNDERLINE = 4;
    protected static final int ATTRIBUTE_BLINK_SLOW = 5;
    protected static final int ATTRIBUTE_BLINK_FAST = 6;
    protected static final int ATTRIBUTE_NEGATIVE_ON = 7;
    protected static final int ATTRIBUTE_CONCEAL_ON = 8;
    protected static final int ATTRIBUTE_UNDERLINE_DOUBLE = 21;
    protected static final int ATTRIBUTE_INTENSITY_NORMAL = 22;
    protected static final int ATTRIBUTE_UNDERLINE_OFF = 24;
    protected static final int ATTRIBUTE_BLINK_OFF = 25;
    protected static final int ATTRIBUTE_NEGATIVE_OFF = 27;
    protected static final int ATTRIBUTE_CONCEAL_OFF = 28;
    protected static final int BLACK = 0;
    protected static final int RED = 1;
    protected static final int GREEN = 2;
    protected static final int YELLOW = 3;
    protected static final int BLUE = 4;
    protected static final int MAGENTA = 5;
    protected static final int CYAN = 6;
    protected static final int WHITE = 7;
    
    public AnsiProcessor(final OutputStream os) {
        this.os = os;
    }
    
    protected int getNextOptionInt(final Iterator<Object> optionsIterator) throws IOException {
        while (optionsIterator.hasNext()) {
            final Object arg = optionsIterator.next();
            if (arg != null) {
                return (int)arg;
            }
        }
        throw new IllegalArgumentException();
    }
    
    protected boolean processEscapeCommand(final ArrayList<Object> options, final int command) throws IOException {
        try {
            switch (command) {
                case 65: {
                    this.processCursorUp(this.optionInt(options, 0, 1));
                    return true;
                }
                case 66: {
                    this.processCursorDown(this.optionInt(options, 0, 1));
                    return true;
                }
                case 67: {
                    this.processCursorRight(this.optionInt(options, 0, 1));
                    return true;
                }
                case 68: {
                    this.processCursorLeft(this.optionInt(options, 0, 1));
                    return true;
                }
                case 69: {
                    this.processCursorDownLine(this.optionInt(options, 0, 1));
                    return true;
                }
                case 70: {
                    this.processCursorUpLine(this.optionInt(options, 0, 1));
                    return true;
                }
                case 71: {
                    this.processCursorToColumn(this.optionInt(options, 0));
                    return true;
                }
                case 72:
                case 102: {
                    this.processCursorTo(this.optionInt(options, 0, 1), this.optionInt(options, 1, 1));
                    return true;
                }
                case 74: {
                    this.processEraseScreen(this.optionInt(options, 0, 0));
                    return true;
                }
                case 75: {
                    this.processEraseLine(this.optionInt(options, 0, 0));
                    return true;
                }
                case 76: {
                    this.processInsertLine(this.optionInt(options, 0, 1));
                    return true;
                }
                case 77: {
                    this.processDeleteLine(this.optionInt(options, 0, 1));
                    return true;
                }
                case 83: {
                    this.processScrollUp(this.optionInt(options, 0, 1));
                    return true;
                }
                case 84: {
                    this.processScrollDown(this.optionInt(options, 0, 1));
                    return true;
                }
                case 109: {
                    for (final Object next : options) {
                        if (next != null && next.getClass() != Integer.class) {
                            throw new IllegalArgumentException();
                        }
                    }
                    int count = 0;
                    final Iterator<Object> optionsIterator = options.iterator();
                    while (optionsIterator.hasNext()) {
                        final Object next2 = optionsIterator.next();
                        if (next2 != null) {
                            ++count;
                            final int value = (int)next2;
                            if (30 <= value && value <= 37) {
                                this.processSetForegroundColor(value - 30);
                            }
                            else if (40 <= value && value <= 47) {
                                this.processSetBackgroundColor(value - 40);
                            }
                            else if (90 <= value && value <= 97) {
                                this.processSetForegroundColor(value - 90, true);
                            }
                            else if (100 <= value && value <= 107) {
                                this.processSetBackgroundColor(value - 100, true);
                            }
                            else if (value == 38 || value == 48) {
                                if (!optionsIterator.hasNext()) {
                                    continue;
                                }
                                final int arg2or5 = this.getNextOptionInt(optionsIterator);
                                if (arg2or5 == 2) {
                                    final int r = this.getNextOptionInt(optionsIterator);
                                    final int g = this.getNextOptionInt(optionsIterator);
                                    final int b = this.getNextOptionInt(optionsIterator);
                                    if (r < 0 || r > 255 || g < 0 || g > 255 || b < 0 || b > 255) {
                                        throw new IllegalArgumentException();
                                    }
                                    if (value == 38) {
                                        this.processSetForegroundColorExt(r, g, b);
                                    }
                                    else {
                                        this.processSetBackgroundColorExt(r, g, b);
                                    }
                                }
                                else {
                                    if (arg2or5 != 5) {
                                        throw new IllegalArgumentException();
                                    }
                                    final int paletteIndex = this.getNextOptionInt(optionsIterator);
                                    if (paletteIndex < 0 || paletteIndex > 255) {
                                        throw new IllegalArgumentException();
                                    }
                                    if (value == 38) {
                                        this.processSetForegroundColorExt(paletteIndex);
                                    }
                                    else {
                                        this.processSetBackgroundColorExt(paletteIndex);
                                    }
                                }
                            }
                            else {
                                switch (value) {
                                    case 39: {
                                        this.processDefaultTextColor();
                                        continue;
                                    }
                                    case 49: {
                                        this.processDefaultBackgroundColor();
                                        continue;
                                    }
                                    case 0: {
                                        this.processAttributeReset();
                                        continue;
                                    }
                                    default: {
                                        this.processSetAttribute(value);
                                        continue;
                                    }
                                }
                            }
                        }
                    }
                    if (count == 0) {
                        this.processAttributeReset();
                    }
                    return true;
                }
                case 115: {
                    this.processSaveCursorPosition();
                    return true;
                }
                case 117: {
                    this.processRestoreCursorPosition();
                    return true;
                }
                default: {
                    if (97 <= command && command <= 122) {
                        this.processUnknownExtension(options, command);
                        return true;
                    }
                    if (65 <= command && command <= 90) {
                        this.processUnknownExtension(options, command);
                        return true;
                    }
                    return false;
                }
            }
        }
        catch (final IllegalArgumentException ex) {
            return false;
        }
    }
    
    protected boolean processOperatingSystemCommand(final ArrayList<Object> options) {
        final int command = this.optionInt(options, 0);
        final String label = options.get(1);
        try {
            switch (command) {
                case 0: {
                    this.processChangeIconNameAndWindowTitle(label);
                    return true;
                }
                case 1: {
                    this.processChangeIconName(label);
                    return true;
                }
                case 2: {
                    this.processChangeWindowTitle(label);
                    return true;
                }
                default: {
                    this.processUnknownOperatingSystemCommand(command, label);
                    return true;
                }
            }
        }
        catch (final IllegalArgumentException ex) {
            return false;
        }
    }
    
    protected boolean processCharsetSelect(final ArrayList<Object> options) {
        final int set = this.optionInt(options, 0);
        final char seq = options.get(1);
        this.processCharsetSelect(set, seq);
        return true;
    }
    
    private int optionInt(final ArrayList<Object> options, final int index) {
        if (options.size() <= index) {
            throw new IllegalArgumentException();
        }
        final Object value = options.get(index);
        if (value == null) {
            throw new IllegalArgumentException();
        }
        if (!value.getClass().equals(Integer.class)) {
            throw new IllegalArgumentException();
        }
        return (int)value;
    }
    
    private int optionInt(final ArrayList<Object> options, final int index, final int defaultValue) {
        if (options.size() <= index) {
            return defaultValue;
        }
        final Object value = options.get(index);
        if (value == null) {
            return defaultValue;
        }
        return (int)value;
    }
    
    protected void processRestoreCursorPosition() throws IOException {
    }
    
    protected void processSaveCursorPosition() throws IOException {
    }
    
    protected void processInsertLine(final int optionInt) throws IOException {
    }
    
    protected void processDeleteLine(final int optionInt) throws IOException {
    }
    
    protected void processScrollDown(final int optionInt) throws IOException {
    }
    
    protected void processScrollUp(final int optionInt) throws IOException {
    }
    
    protected void processEraseScreen(final int eraseOption) throws IOException {
    }
    
    protected void processEraseLine(final int eraseOption) throws IOException {
    }
    
    protected void processSetAttribute(final int attribute) throws IOException {
    }
    
    protected void processSetForegroundColor(final int color) throws IOException {
        this.processSetForegroundColor(color, false);
    }
    
    protected void processSetForegroundColor(final int color, final boolean bright) throws IOException {
    }
    
    protected void processSetForegroundColorExt(final int paletteIndex) throws IOException {
    }
    
    protected void processSetForegroundColorExt(final int r, final int g, final int b) throws IOException {
    }
    
    protected void processSetBackgroundColor(final int color) throws IOException {
        this.processSetBackgroundColor(color, false);
    }
    
    protected void processSetBackgroundColor(final int color, final boolean bright) throws IOException {
    }
    
    protected void processSetBackgroundColorExt(final int paletteIndex) throws IOException {
    }
    
    protected void processSetBackgroundColorExt(final int r, final int g, final int b) throws IOException {
    }
    
    protected void processDefaultTextColor() throws IOException {
    }
    
    protected void processDefaultBackgroundColor() throws IOException {
    }
    
    protected void processAttributeReset() throws IOException {
    }
    
    protected void processCursorTo(final int row, final int col) throws IOException {
    }
    
    protected void processCursorToColumn(final int x) throws IOException {
    }
    
    protected void processCursorUpLine(final int count) throws IOException {
    }
    
    protected void processCursorDownLine(final int count) throws IOException {
        for (int i = 0; i < count; ++i) {
            this.os.write(10);
        }
    }
    
    protected void processCursorLeft(final int count) throws IOException {
    }
    
    protected void processCursorRight(final int count) throws IOException {
        for (int i = 0; i < count; ++i) {
            this.os.write(32);
        }
    }
    
    protected void processCursorDown(final int count) throws IOException {
    }
    
    protected void processCursorUp(final int count) throws IOException {
    }
    
    protected void processUnknownExtension(final ArrayList<Object> options, final int command) {
    }
    
    protected void processChangeIconNameAndWindowTitle(final String label) {
        this.processChangeIconName(label);
        this.processChangeWindowTitle(label);
    }
    
    protected void processChangeIconName(final String label) {
    }
    
    protected void processChangeWindowTitle(final String label) {
    }
    
    protected void processUnknownOperatingSystemCommand(final int command, final String param) {
    }
    
    protected void processCharsetSelect(final int set, final char seq) {
    }
}
