package indi.key.mipsemulator.controller.component;

import indi.key.mipsemulator.core.controller.Machine;
import indi.key.mipsemulator.core.controller.TimingRenderer;
import indi.key.mipsemulator.model.interfaces.Resetable;
import indi.key.mipsemulator.model.interfaces.TickCallback;
import indi.key.mipsemulator.vga.GraphProvider;
import indi.key.mipsemulator.vga.ScreenProvider;
import indi.key.mipsemulator.vga.TextProvider;
import indi.key.mipsemulator.vga.VgaConfigures;
import javafx.application.Platform;
import javafx.scene.image.Image;
import javafx.scene.image.ImageView;
import javafx.scene.image.PixelFormat;
import javafx.scene.image.WritableImage;

public class VgaController implements TickCallback, Resetable {

    public static final int WIDTH = 640;
    public static final int HEIGHT = 480;

    private WritableImage content;
    private Image placeHolder;
    private ImageView screen;
    private Machine machine;

    private GraphProvider graphProvider;
    private TextProvider textProvider;

    public VgaController(ImageView screen, Machine machine) {
        content = new WritableImage(WIDTH, HEIGHT);
        this.machine = machine;
        placeHolder = new Image(VgaController.class.getResourceAsStream("/drawable/placeholder.jpg"));
        this.screen = screen;
        screen.setImage(placeHolder);

        graphProvider = new GraphProvider(machine);
        textProvider = new TextProvider(machine);

        TimingRenderer.register(this);
    }

    @Override
    public void onTick(long ticks) {
        Platform.runLater(() -> {
            if (VgaConfigures.getResolution() == VgaConfigures.Resolution.CLOSE) {
                return;
            }
            if (machine.isLooping() && screen.getImage() != content) {
                screen.setImage(content);
            }
            ScreenProvider currentProvider = VgaConfigures.isTextMode() ? textProvider : graphProvider;
            content.getPixelWriter().setPixels(0, 0, WIDTH, HEIGHT, PixelFormat.getByteBgraPreInstance()
                    , currentProvider.get(), 0, WIDTH * 4);
            // blink cursor
            if (ticks % 10 == 0) {
                machine.blink();
            }
        });

    }

    @Override
    public void reset() {
        graphProvider.reset();
        textProvider.reset();
        screen.setImage(placeHolder);
    }
}