/*
 * Decompiled with CFR 0.152.
 * 
 * Could not load the following classes:
 *  meteordevelopment.orbit.EventHandler
 *  net.minecraft.class_124
 *  net.minecraft.class_1799
 *  net.minecraft.class_1802
 *  net.minecraft.class_2487
 *  net.minecraft.class_2558
 *  net.minecraft.class_2558$class_10607
 *  net.minecraft.class_2561
 *  net.minecraft.class_2583
 *  net.minecraft.class_2596
 *  net.minecraft.class_2820
 *  net.minecraft.class_5225$class_5231
 *  net.minecraft.class_5250
 *  net.minecraft.class_5348
 *  net.minecraft.class_9262
 *  net.minecraft.class_9301
 *  net.minecraft.class_9302
 *  net.minecraft.class_9334
 *  org.lwjgl.BufferUtils
 *  org.lwjgl.PointerBuffer
 *  org.lwjgl.system.MemoryUtil
 *  org.lwjgl.util.tinyfd.TinyFileDialogs
 */
package meteordevelopment.meteorclient.systems.modules.misc;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
import java.util.PrimitiveIterator;
import java.util.Random;
import java.util.function.Predicate;
import meteordevelopment.meteorclient.MeteorClient;
import meteordevelopment.meteorclient.events.world.TickEvent;
import meteordevelopment.meteorclient.gui.GuiTheme;
import meteordevelopment.meteorclient.gui.widgets.WLabel;
import meteordevelopment.meteorclient.gui.widgets.WWidget;
import meteordevelopment.meteorclient.gui.widgets.containers.WHorizontalList;
import meteordevelopment.meteorclient.gui.widgets.pressable.WButton;
import meteordevelopment.meteorclient.mixin.TextHandlerAccessor;
import meteordevelopment.meteorclient.settings.BoolSetting;
import meteordevelopment.meteorclient.settings.EnumSetting;
import meteordevelopment.meteorclient.settings.IntSetting;
import meteordevelopment.meteorclient.settings.Setting;
import meteordevelopment.meteorclient.settings.SettingGroup;
import meteordevelopment.meteorclient.settings.StringSetting;
import meteordevelopment.meteorclient.systems.modules.Categories;
import meteordevelopment.meteorclient.systems.modules.Module;
import meteordevelopment.meteorclient.utils.player.FindItemResult;
import meteordevelopment.meteorclient.utils.player.InvUtils;
import meteordevelopment.orbit.EventHandler;
import net.minecraft.class_124;
import net.minecraft.class_1799;
import net.minecraft.class_1802;
import net.minecraft.class_2487;
import net.minecraft.class_2558;
import net.minecraft.class_2561;
import net.minecraft.class_2583;
import net.minecraft.class_2596;
import net.minecraft.class_2820;
import net.minecraft.class_5225;
import net.minecraft.class_5250;
import net.minecraft.class_5348;
import net.minecraft.class_9262;
import net.minecraft.class_9301;
import net.minecraft.class_9302;
import net.minecraft.class_9334;
import org.lwjgl.BufferUtils;
import org.lwjgl.PointerBuffer;
import org.lwjgl.system.MemoryUtil;
import org.lwjgl.util.tinyfd.TinyFileDialogs;

public class BookBot
extends Module {
    private final SettingGroup sgGeneral;
    private final Setting<Mode> mode;
    private final Setting<Integer> pages;
    private final Setting<Boolean> onlyAscii;
    private final Setting<Integer> delay;
    private final Setting<Boolean> sign;
    private final Setting<String> name;
    private final Setting<Boolean> count;
    private final Setting<Boolean> wordWrap;
    private File file;
    private final PointerBuffer filters;
    private int delayTimer;
    private int bookCount;
    private Random random;

    public BookBot() {
        super(Categories.Misc, "book-bot", "Automatically writes in books.");
        this.sgGeneral = this.settings.getDefaultGroup();
        this.mode = this.sgGeneral.add(((EnumSetting.Builder)((EnumSetting.Builder)((EnumSetting.Builder)new EnumSetting.Builder().name("mode")).description("What kind of text to write.")).defaultValue(Mode.Random)).build());
        this.pages = this.sgGeneral.add(((IntSetting.Builder)((IntSetting.Builder)((IntSetting.Builder)((IntSetting.Builder)new IntSetting.Builder().name("pages")).description("The number of pages to write per book.")).defaultValue(50)).range(1, 100).sliderRange(1, 100).visible(() -> this.mode.get() != Mode.File)).build());
        this.onlyAscii = this.sgGeneral.add(((BoolSetting.Builder)((BoolSetting.Builder)((BoolSetting.Builder)((BoolSetting.Builder)new BoolSetting.Builder().name("ascii-only")).description("Only uses the characters in the ASCII charset.")).defaultValue(false)).visible(() -> this.mode.get() == Mode.Random)).build());
        this.delay = this.sgGeneral.add(((IntSetting.Builder)((IntSetting.Builder)((IntSetting.Builder)new IntSetting.Builder().name("delay")).description("The amount of delay between writing books.")).defaultValue(20)).min(1).sliderRange(1, 200).build());
        this.sign = this.sgGeneral.add(((BoolSetting.Builder)((BoolSetting.Builder)((BoolSetting.Builder)new BoolSetting.Builder().name("sign")).description("Whether to sign the book.")).defaultValue(true)).build());
        this.name = this.sgGeneral.add(((StringSetting.Builder)((StringSetting.Builder)((StringSetting.Builder)((StringSetting.Builder)new StringSetting.Builder().name("name")).description("The name you want to give your books.")).defaultValue("Meteor on Crack!")).visible(this.sign::get)).build());
        this.count = this.sgGeneral.add(((BoolSetting.Builder)((BoolSetting.Builder)((BoolSetting.Builder)((BoolSetting.Builder)new BoolSetting.Builder().name("append-count")).description("Whether to append the number of the book to the title.")).defaultValue(true)).visible(this.sign::get)).build());
        this.wordWrap = this.sgGeneral.add(((BoolSetting.Builder)((BoolSetting.Builder)((BoolSetting.Builder)((BoolSetting.Builder)new BoolSetting.Builder().name("word-wrap")).description("Prevents words from being cut in the middle of lines.")).defaultValue(true)).visible(() -> this.mode.get() == Mode.File)).build());
        this.file = new File(MeteorClient.FOLDER, "bookbot.txt");
        if (!this.file.exists()) {
            this.file = null;
        }
        this.filters = BufferUtils.createPointerBuffer((int)1);
        ByteBuffer txtFilter = MemoryUtil.memASCII((CharSequence)"*.txt");
        this.filters.put(txtFilter);
        this.filters.rewind();
    }

    @Override
    public WWidget getWidget(GuiTheme theme) {
        WHorizontalList list = theme.horizontalList();
        WButton selectFile = list.add(theme.button("Select File")).widget();
        WLabel fileName = list.add(theme.label(this.file != null && this.file.exists() ? this.file.getName() : "No file selected.")).widget();
        selectFile.action = () -> {
            String path = TinyFileDialogs.tinyfd_openFileDialog((CharSequence)"Select File", (CharSequence)new File(MeteorClient.FOLDER, "bookbot.txt").getAbsolutePath(), (PointerBuffer)this.filters, null, (boolean)false);
            if (path != null) {
                this.file = new File(path);
                fileName.set(this.file.getName());
            }
        };
        return list;
    }

    @Override
    public void onActivate() {
        if (!(this.file != null && this.file.exists() || this.mode.get() != Mode.File)) {
            this.info("No file selected, please select a file in the GUI.", new Object[0]);
            this.toggle();
            return;
        }
        this.random = new Random();
        this.delayTimer = this.delay.get();
        this.bookCount = 0;
    }

    @EventHandler
    private void onTick(TickEvent.Post event) {
        Predicate<class_1799> bookPredicate = i -> {
            class_9301 component = (class_9301)i.method_58694(class_9334.field_49653);
            return i.method_7909() == class_1802.field_8674 && (component == null || component.comp_2422().isEmpty());
        };
        FindItemResult writableBook = InvUtils.find(bookPredicate);
        if (!writableBook.found()) {
            this.toggle();
            return;
        }
        if (!InvUtils.testInMainHand(bookPredicate)) {
            InvUtils.move().from(writableBook.slot()).toHotbar(this.mc.field_1724.method_31548().method_67532());
            return;
        }
        if (this.delayTimer > 0) {
            --this.delayTimer;
            return;
        }
        this.delayTimer = this.delay.get();
        if (this.mode.get() == Mode.Random) {
            int origin = this.onlyAscii.get() != false ? 33 : 2048;
            int bound = this.onlyAscii.get() != false ? 126 : 0x10FFFF;
            this.writeBook(this.random.ints(origin, bound).filter(i -> !Character.isWhitespace(i) && i != 13 && i != 10).iterator());
        } else if (this.mode.get() == Mode.File) {
            if (!(this.file != null && this.file.exists() || this.mode.get() != Mode.File)) {
                this.info("No file selected, please select a file in the GUI.", new Object[0]);
                this.toggle();
                return;
            }
            if (this.file.length() == 0L) {
                class_5250 message = class_2561.method_43470((String)"");
                message.method_10852((class_2561)class_2561.method_43470((String)"The bookbot file is empty! ").method_27692(class_124.field_1061));
                message.method_10852((class_2561)class_2561.method_43470((String)"Click here to edit it.").method_10862(class_2583.field_24360.method_27705(new class_124[]{class_124.field_1073, class_124.field_1061}).method_10958((class_2558)new class_2558.class_10607(this.file.getAbsolutePath()))));
                this.info((class_2561)message);
                this.toggle();
                return;
            }
            try (BufferedReader reader = new BufferedReader(new FileReader(this.file));){
                String line;
                StringBuilder file = new StringBuilder();
                while ((line = reader.readLine()) != null) {
                    file.append(line).append('\n');
                }
                reader.close();
                this.writeBook(file.toString().chars().iterator());
            }
            catch (IOException ignored) {
                this.error("Failed to read the file.", new Object[0]);
            }
        }
    }

    private void writeBook(PrimitiveIterator.OfInt chars) {
        int maxPages;
        ArrayList<String> pages = new ArrayList<String>();
        ArrayList<class_9262<class_2561>> filteredPages = new ArrayList<class_9262<class_2561>>();
        int n = maxPages = this.mode.get() == Mode.File ? 100 : this.pages.get();
        if (this.wordWrap.get().booleanValue() && this.mode.get() == Mode.File) {
            StringBuilder text = new StringBuilder();
            while (chars.hasNext()) {
                text.appendCodePoint(chars.nextInt());
            }
            List wrappedLines = this.mc.field_1772.method_72101((class_5348)class_2561.method_43470((String)text.toString()), 114);
            this.processLinesToPages(wrappedLines, pages, filteredPages, maxPages);
        } else {
            class_5225.class_5231 widthRetriever = ((TextHandlerAccessor)this.mc.field_1772.method_27527()).meteor$getWidthRetriever();
            int pageIndex = 0;
            int lineIndex = 0;
            StringBuilder page = new StringBuilder();
            float lineWidth = 0.0f;
            while (chars.hasNext()) {
                int c = chars.nextInt();
                if (c == 13 || c == 10) {
                    page.append('\n');
                    lineWidth = 0.0f;
                    ++lineIndex;
                } else {
                    float charWidth = widthRetriever.getWidth(c, class_2583.field_24360);
                    if (lineWidth + charWidth > 114.0f) {
                        page.append('\n');
                        lineWidth = charWidth;
                        if (++lineIndex != 14) {
                            page.appendCodePoint(c);
                        }
                    } else {
                        if (lineWidth == 0.0f && c == 32) continue;
                        lineWidth += charWidth;
                        page.appendCodePoint(c);
                    }
                }
                if (lineIndex != 14) continue;
                filteredPages.add((class_9262<class_2561>)class_9262.method_57137((Object)class_2561.method_30163((String)page.toString())));
                pages.add(page.toString());
                page.setLength(0);
                lineIndex = 0;
                if (++pageIndex == maxPages) break;
                if (c == 13 || c == 10) continue;
                page.appendCodePoint(c);
            }
            if (!page.isEmpty() && pageIndex != maxPages) {
                filteredPages.add((class_9262<class_2561>)class_9262.method_57137((Object)class_2561.method_30163((String)page.toString())));
                pages.add(page.toString());
            }
        }
        this.createBook(pages, filteredPages);
    }

    private void processLinesToPages(List<class_5348> lines, ArrayList<String> pages, ArrayList<class_9262<class_2561>> filteredPages, int maxPages) {
        int pageIndex = 0;
        int lineIndex = 0;
        StringBuilder currentPage = new StringBuilder();
        for (class_5348 line : lines) {
            String lineText = line.getString();
            if (currentPage.length() > 0) {
                currentPage.append('\n');
            }
            currentPage.append(lineText);
            if (++lineIndex != 14) continue;
            filteredPages.add((class_9262<class_2561>)class_9262.method_57137((Object)class_2561.method_30163((String)currentPage.toString())));
            pages.add(currentPage.toString());
            currentPage.setLength(0);
            lineIndex = 0;
            if (++pageIndex != maxPages) continue;
            break;
        }
        if (!currentPage.isEmpty() && pageIndex < maxPages) {
            filteredPages.add((class_9262<class_2561>)class_9262.method_57137((Object)class_2561.method_30163((String)currentPage.toString())));
            pages.add(currentPage.toString());
        }
    }

    private void createBook(ArrayList<String> pages, ArrayList<class_9262<class_2561>> filteredPages) {
        Object title = this.name.get();
        if (this.count.get().booleanValue() && this.bookCount != 0) {
            title = (String)title + " #" + this.bookCount;
        }
        this.mc.field_1724.method_6047().method_57379(class_9334.field_49606, (Object)new class_9302(class_9262.method_57137((Object)title), this.mc.field_1724.method_7334().name(), 0, filteredPages, true));
        this.mc.field_1724.field_3944.method_52787((class_2596)new class_2820(this.mc.field_1724.method_31548().method_67532(), pages, this.sign.get() != false ? Optional.of(title) : Optional.empty()));
        ++this.bookCount;
    }

    @Override
    public class_2487 toTag() {
        class_2487 tag = super.toTag();
        if (this.file != null && this.file.exists()) {
            tag.method_10582("file", this.file.getAbsolutePath());
        }
        return tag;
    }

    @Override
    public Module fromTag(class_2487 tag) {
        if (tag.method_10545("file")) {
            this.file = new File(tag.method_68564("file", ""));
        }
        return super.fromTag(tag);
    }

    public static enum Mode {
        File,
        Random;

    }
}

