package ru.kirillius.cooler.controller.UI;

import com.fazecast.jSerialComm.SerialPort;
import ru.kirillius.cooler.controller.Application;
import ru.kirillius.cooler.controller.EventSystem.EventHandler;
import ru.kirillius.cooler.controller.EventSystem.EventListener;

import javax.swing.*;
import java.awt.event.ActionListener;

public class PortListComboBox extends JComboBox<PortListComboBox.PortItem> {
    private final EventHandler<EventListener<PortItem>, PortItem> handler = new EventHandler<>();

    public PortListComboBox() {
        reload();
        bindActions();
    }

    public SerialPort selectPortByName(String name) {
        if (name != null) {
            for (var i = 0; i < getItemCount(); i++) {
                PortItem item = getItemAt(i);
                if (item.text.equals(name)) {
                    setSelectedIndex(i);
                    return item.port;
                }
            }
        }
        return null;
    }

    public void addListener(EventListener<PortItem> listener) {
        handler.addListener(listener);
    }

    private void reload() {
        removeAllItems();
        addItem(new PortItem("Refresh...", null));
        if (Application.DEBUG) {
            addItem(new PortItem("debug/virtual", null));
        }
        try {
            for (SerialPort port : SerialPort.getCommPorts()) {
                addItem(new PortItem(port.getSystemPortName(), port));
            }
        } catch (Throwable t) {
            throw new RuntimeException("Failed to get serial port list", t);
        }
    }

    private void bindActions() {
        super.addActionListener(e -> {
            int index = getSelectedIndex();
            if (index == -1) return;
            PortItem item = getItemAt(index);

            if (item.port == null && index == 0) {
                reload();
            } else {
                handler.invoke(item);
            }
        });
    }

    @Override
    public void addActionListener(ActionListener l) {
        throw new UnsupportedOperationException();
    }


    public static final class PortItem {
        private final String text;
        private final SerialPort port;

        public PortItem(String text, SerialPort port) {
            this.text = text;
            this.port = port;
        }

        public String getText() {
            return text;
        }

        public SerialPort getPort() {
            return port;
        }

        @Override
        public String toString() {
            return text;
        }
    }
}
