// Copyright (c) 2026 - 2026 kio@little-bat.de
// BSD-2-Clause license
// https://opensource.org/licenses/BSD-2-Clause

#include "MainWindow.h"
#include <QActionGroup>
#include <QApplication>
#include <QMainWindow>
#include <QMenuBar>
#include <QPushButton>
#include <QSettings>
#include <thread>
//
#include "common.h"
#include "graphics.h"
#include "usb_host.h"
#include "video.h"

//QSettings				settings("kio@little-bat.de", "kilipili_emulator");
QApplication*			appl			   = nullptr;
int						mbar_height		   = 20;
static bool				gui_thread_running = false;
extern thread_local int core_num;

void __noreturn gui_runner()
{
	core_num = 2; // for trace()

	char		 arg1[] = "kilipili_emulator";
	char*		 argv[] = {arg1};
	int			 argc	= 1;
	QApplication a(argc, argv);
	MainWindow	 w(800, 600);
	appl = &a;

	QMenuBar* mbar	   = new QMenuBar(nullptr);
	QMenu*	  fileMenu = mbar->addMenu("File");
	QMenu*	  editMenu = mbar->addMenu("Edit");

	// file menu:

	QAction* action = fileMenu->addAction("Quit");
	action->setShortcut(Qt::CTRL | Qt::Key_Q);
	QObject::connect(action, &QAction::triggered, appl->quit);

	// edit menu:

	action = editMenu->addAction("reset");
	action->setShortcut(Qt::CTRL | Qt::Key_R);

	w.setMenuBar(mbar);

	w.show();
	mbar_height = mbar->height();
	fprintf(stderr, "mbarheight = %i\n", mbar_height);

	int rval = a.exec();
	exit(rval);
}

int stdio_getchar_timeout_us(int) { return -1; } // TODO

void stdio_init_all()
{
	core_num = 0;
	if (gui_thread_running == false)
	{
		gui_thread_running = true;
		std::thread(&gui_runner).detach();
	}
}


// ------------------


int main(int argc, char* argv[])
{
	using namespace kilipili;

	stdio_init_all();
	printf("Hello world\n"); // print to stdio
	USB::initUSBHost();

	RCPtr pixmap	  = new Pixmap_a1w8(800, 600);
	RCPtr framebuffer = new FrameBuffer(pixmap);
	RCPtr printer	  = new Printer(pixmap);

	addVideoPlane(framebuffer);
	startVideo(vga_mode_800x600_60);

	printer->cls();
	printer->printf("Hello world ... %s mode\n", debug ? "DEBUG" : "RELEASE"); // print on video screen
	printer->printf("%s\n", printer->identification());						   // print on video screen
	pixmap->drawRect(100, 50, 400, 300, red);								   // draw on video screen

	Dispatcher::addHandler(&blinkOnboardLed);
	Dispatcher::addHandler(&USB::pollUSB);

	for (;;)
	{
		int c = stdio_getchar_timeout_us(0); // get input from stdin (UART)
		if (c < 0) c = USB::getChar();		 // get input from usb keyboard
		if (c == '\r') c = '\n';
		if (c == uchar(c)) printer->putc(char(c));

		Dispatcher::run(1000); // run the registered Dispatcher handlers
		purge_tempmem();	   // house keeping
	}
}

/*



















































*/
