#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>
#include <QTimer>
#include <QLabel>
#include <QSpinBox>
#include <QDockWidget>
#include <QList>
#include <QVector>
#include <QMap>
#include <QPointer>
#include <emdas.h>
#include "emumodel.h"
#include "configcontroller.h"
#include "dasmview.h"
#include "memview.h"
#include "regview.h"
#include "intview.h"
#include "mapview.h"
#include "brkview.h"
#include "watchview.h"
#include "stackview.h"

namespace Ui {
class MainWindow;
}

class ConfigDialog;
class TerminalWindow;
class QMenu;

class MainWindow : public QMainWindow
{
	Q_OBJECT

public:
	explicit MainWindow(QWidget *parent = nullptr);
	~MainWindow();

	// Startup power-on, driven through the ignition switch so the switch
	// graphic, EmuModel and the power-changed signal stay consistent. `program`
	// (the -p image, may be null) is preloaded after a successful init.
	void startup_power_on(const char *program);

private:
    EmuModel e;
	ConfigController cfg_ctl;
	Ui::MainWindow *ui;

	// fresh instance per open (deleted on close); the guard auto-nulls so a
	// second open just raises the existing one
	QPointer<ConfigDialog> config_dialog;

	QLabel *ips;
	QLabel *q, *bs, *nb, *flags, *mc;
	QLabel *edit_mode;
	QWidget *edit_box;
	QVector<QLabel *> mono_status_labels; // statusbar labels that track the mono font

	// All debugger docks, in Debugger-menu order. Built by register_dock(); the
	// named handles below alias entries here and exist only for the bespoke
	// default arrangement in apply_default_layout().
	QList<QDockWidget *> docks;
	QDockWidget *dock_uregs, *dock_sregs, *dock_dasm, *dock_mem, *dock_ints, *dock_map, *dock_brk, *dock_watch, *dock_stack;

	DasmView *dasm;
	MemView *mem;
	RegCompact *uregs, *sregs;
	IntView *ints;
	MapView *map;
	BrkView *brk;
	WatchView *watch;
	StackView *stack;

	void update_window_title();
	void update_docks_enabled(bool powered);
	void update_mc_status(int mc);
	void update_sr_status(uint16_t val);
	void update_r0_status(uint16_t r0);

	void build_docks();
	void init_layout();
	void wire_connections();
	void build_statusbar();
	void apply_statusbar_font();
	void pin_nb_width();
	void refresh_fonts();
	void restore_layout();

	// Devices menu: rebuilt on open (aboutToShow) from the active machine's media
	// slots, so it always reflects current images and power-gated editability.
	QMenu *menu_devices = nullptr;
	void populate_machine_menu(QMenu *menu);
	void populate_devices_menu(QMenu *menu);
	void add_media_slot(QMenu *menu, int chan, int dev, int slot, const QString &title, const char *image, bool powered);
	void open_terminal(int port, const QString &label);
	void launch_terminal_command(int port);
	void refresh_terminal_fonts();
	void show_cp_context_menu(const QPoint &pos);

	// One built-in terminal window per device port; the QPointer auto-nulls on
	// close so a re-open just makes a fresh one.
	QMap<int, QPointer<TerminalWindow>> terminals;

	QDockWidget *register_dock(QWidget *view, const QString &title, const QString &objname);
	void apply_default_layout();
	void sync_debugger_action();
	void update_debugger_menu_enabled(bool on);

private slots:
	void closeEvent(QCloseEvent* event);
	void slot_dasm_update();
	void slot_cpu_reg_changed(int reg, uint16_t val);
	void slot_ips_update(unsigned long ips);
	void slot_edit_mode_changed(bool editing, bool insert);

	void open_config();

public slots:
	void slot_debugger_enabled_changed(bool state);
	void slot_smallcp_changed(bool state);
	void slot_panel_theme_changed(bool state);

};

#endif // MAINWINDOW_H

// vim: tabstop=4 shiftwidth=4 autoindent
