/*
 * Copyright (C) 2023 Adrien Destugues <pulkomandy@pulkomandy.tk>
 *
 * Distributed under terms of the MIT license.
 */

#include <private/interface/AboutWindow.h>
#include <Application.h>
#include <Clipboard.h>
#include <private/interface/ColumnListView.h>
#include <private/interface/ColumnTypes.h>
#include <GroupLayout.h>
#include <LayoutBuilder.h>
#include <MenuBar.h>
#include <Window.h>

#include <ctype.h>

#include "../BeDC.h"


class BColorStringField: public BStringField
{
public:
	BColorStringField(const char* string, rgb_color color)
		: BStringField(string)
		, fColor(color)
	{
	}

	rgb_color fColor;
};


class BColorStringColumn: public BStringColumn
{
public:
	BColorStringColumn(const char* title, float w, float minw, float maxw)
		: BStringColumn(title, w, minw, maxw, false)
	{
	}

	void DrawField(BField* field, BRect rect, BView* parent) override
	{
		BColorStringField* csField = dynamic_cast<BColorStringField*>(field);
		if (csField) {
			parent->SetHighColor(csField->fColor);
		}
		BStringColumn::DrawField(field, rect, parent);
	}
};


static char sanechar(int32 input) {
	input = input & 0xff;
	if (isprint(input))
		return (char)input;
	else
		return '.';
}


class LoggerWindow: public BWindow
{
public:
	LoggerWindow()
		: BWindow(BRect(100, 100, 900, 700), "Dev console", B_DOCUMENT_WINDOW,
			B_QUIT_ON_WINDOW_CLOSE | B_AUTO_UPDATE_SIZE_LIMITS)
	{
		BGroupLayout* layout = new BGroupLayout(B_VERTICAL);
		SetLayout(layout);
		layout->SetSpacing(0);

		fEventList = new BColumnListView("messages", 0, B_NO_BORDER);
		fEventList->AddColumn(new BColorStringColumn("Name", 100, 50, 200), 0);
		fEventList->AddColumn(new BColorStringColumn("Text", INT16_MAX, 50, INT16_MAX), 1);

		BMenuBar* mainMenu = new BMenuBar("main menu");

		BMessage* separatorMessage = new BMessage(BEDC_MESSAGE);
		separatorMessage->AddInt8("bedc_type", DC_SEPARATOR);

		BMessage* clearMessage = new BMessage(BEDC_MESSAGE);
		clearMessage->AddInt8("bedc_type", DC_CLEAR);

		BLayoutBuilder::Menu<>(mainMenu)
			.AddMenu("File")
				.AddItem("New window", new BMessage(), 'N')
				.AddItem("Activate window", new BMessage(), 'S')
					.SetEnabled(false)
				.AddSeparator()
				.AddItem("About…", new BMessage(B_ABOUT_REQUESTED))
				.AddSeparator()
				.AddItem("Quit", new BMessage(B_QUIT_REQUESTED), 'Q')
			.End()
			.AddMenu("Edit")
				.AddItem("Cut", new BMessage(B_CUT), 'X')
				.AddItem("Copy", new BMessage(B_COPY), 'C')
				.AddItem("Delete", new BMessage(), 'D')
				.AddSeparator()
				.AddItem("Clear", clearMessage, 'E')
				.AddItem("Select all", new BMessage(B_SELECT_ALL), 'A')
				.AddSeparator()
				.AddItem("Preferences", new BMessage())
			.End()
			.AddMenu("Tools")
				.AddItem("Add separator", separatorMessage, 'S')
				.AddSeparator()
				.AddItem("Save to file…", new BMessage())
				.AddItem("Save selection to file…", new BMessage())
			.End()
		.End();

		BLayoutBuilder::Group<>(layout)
			.SetInsets(0, -1, -1, -1)
			.Add(mainMenu)
			.Add(fEventList)
		.End();

		// TODO make all menu items work
		// TODO add status bar with online/offline status and line counter
		//      Newest created window becomes active, deactivates all other
		//      Actve window can be switched from menu
		//      Active window has its 'activate window' menu disabled, using the shortcut adds a
		//      separator instead
		// TODO add line numbers in list view
	}

	void MessageReceived(BMessage* message) override
	{
		switch(message->what) {
			case BEDC_MESSAGE:
			{
				// TODO parse bedc_ver to handle mulitple protocol versions
				BString name = message->FindString("bedc_name");
				BString text = message->FindString("bedc_text");
				int8 colorEnum = message->FindInt8("bedc_color");
				int8 type = message->FindInt8("bedc_type");
				int8 main_type = message->FindInt8("bedc_main_type");

				if (type == DC_CLEAR) {
					fEventList->Clear();
					return;
				}

				if (main_type == BEDC_BMESSAGE && text.IsEmpty()) {
					int32 what = message->FindInt32("bedc_what");
					BString description = message->FindString("bedc_desc");
					if (description.IsEmpty())
						description = "BMessage";

					text.SetToFormat("%s(what=%#010x, %d, '%c%c%c%c')", description.String(),
						what, what,
						sanechar(what >> 24), sanechar(what >> 16),
						sanechar(what >>  8), sanechar(what >>  0));
				}

				BRow* row = new BRow();
				if (colorEnum == 0) {
					row->SetField(new BStringField(name), 0);
				} else {
					rgb_color color;
					switch(colorEnum) {
						case DC_WHITE:
							color = make_color(128, 128, 128, 255);
							break;
						case DC_BLACK:
							color = make_color(64, 64, 64, 255);
							break;
						case DC_BLUE:
							color = make_color(0, 0, 128, 255);
							break;
						case DC_RED:
							color = make_color(0, 128, 0, 255);
							break;
						case DC_YELLOW:
							color = make_color(128, 128, 0, 255);
							break;
						case DC_GREEN:
							color = make_color(128, 0, 0, 255);
							break;
					}
					row->SetField(new BColorStringField(name, color), 0);
				}

				if (type == DC_SUCCESS)
					row->SetField(new BColorStringField(text, ui_color(B_SUCCESS_COLOR)), 1);
				else if (type == DC_ERROR)
					row->SetField(new BColorStringField(text, ui_color(B_FAILURE_COLOR)), 1);
				else if (type == DC_MESSAGE)
					row->SetField(new BStringField(text), 1);
				else if (type == DC_SEPARATOR)
					row->SetField(new BStringField("-----"), 1);
				else {
					message->PrintToStream();
				}
				fEventList->AddRow(row, -1);

				// For BEDC_MESSAGE, there is no bedc_text, but instead all non-bedc fields of the
				// message should be added to the view. We add them in subrows that can be folded.
				if (main_type == BEDC_BMESSAGE) {
					int index = 0;
					char* nameFound;
					type_code typeFound;
					int32 countFound;
					while (message->GetInfo(B_ANY_TYPE, index++, &nameFound, &typeFound, &countFound) == B_OK) {
						// Don't display all the bedc_ internal stuff
						if (BString(nameFound).StartsWith("bedc_"))
							continue;

						for (int j = 0; j < countFound; j++) {
							name.SetToFormat("%s[%d] (%c%c%c%c)", nameFound, j,
								(typeFound >> 24) & 0xFF, (typeFound >> 16) & 0xFF,
								(typeFound >>  8) & 0xFF, (typeFound >>  0) & 0xFF
							);

							switch(typeFound) {
#if 0
	B_AFFINE_TRANSFORM_TYPE			= 'AMTX',
	B_ALIGNMENT_TYPE				= 'ALGN',
	B_ANY_TYPE						= 'ANYT',
	B_ATOM_TYPE						= 'ATOM',
	B_ATOMREF_TYPE					= 'ATMR',
	B_BOOL_TYPE						= 'BOOL',
	B_CHAR_TYPE						= 'CHAR',
	B_COLOR_8_BIT_TYPE				= 'CLRB',
	B_DOUBLE_TYPE					= 'DBLE',
	B_FLOAT_TYPE					= 'FLOT',
	B_GRAYSCALE_8_BIT_TYPE			= 'GRYB',
	B_INT16_TYPE					= 'SHRT',
	B_INT64_TYPE					= 'LLNG',
	B_INT8_TYPE						= 'BYTE',
	B_LARGE_ICON_TYPE				= 'ICON',
	B_MEDIA_PARAMETER_GROUP_TYPE	= 'BMCG',
	B_MEDIA_PARAMETER_TYPE			= 'BMCT',
	B_MEDIA_PARAMETER_WEB_TYPE		= 'BMCW',
	B_MESSAGE_TYPE					= 'MSGG',
	B_MESSENGER_TYPE				= 'MSNG',
	B_MIME_TYPE						= 'MIME',
	B_MINI_ICON_TYPE				= 'MICN',
	B_MONOCHROME_1_BIT_TYPE			= 'MNOB',
	B_OBJECT_TYPE					= 'OPTR',
	B_OFF_T_TYPE					= 'OFFT',
	B_PATTERN_TYPE					= 'PATN',
	B_POINTER_TYPE					= 'PNTR',
	B_PROPERTY_INFO_TYPE			= 'SCTD',
	B_RAW_TYPE						= 'RAWT',
	B_RECT_TYPE						= 'RECT',
	B_REF_TYPE						= 'RREF',
	B_NODE_REF_TYPE					= 'NREF',
	B_RGB_32_BIT_TYPE				= 'RGBB',
	B_RGB_COLOR_TYPE				= 'RGBC',
	B_SIZE_TYPE						= 'SIZE',
	B_SIZE_T_TYPE					= 'SIZT',
	B_SSIZE_T_TYPE					= 'SSZT',
	B_STRING_LIST_TYPE				= 'STRL',
	B_TIME_TYPE						= 'TIME',
	B_UINT16_TYPE					= 'USHT',
	B_UINT32_TYPE					= 'ULNG',
	B_UINT64_TYPE					= 'ULLG',
	B_UINT8_TYPE					= 'UBYT',
	B_VECTOR_ICON_TYPE				= 'VICN',
	B_XATTR_TYPE					= 'XATR',
	B_NETWORK_ADDRESS_TYPE			= 'NWAD',
	B_MIME_STRING_TYPE				= 'MIMS',
#endif
								case B_STRING_TYPE:
									text = message->FindString(nameFound, j);
									break;
								case B_INT32_TYPE:
								{
									int32 val = message->FindInt32(nameFound, j);
									text.SetToFormat("%d (%#010x)", val, val);
									break;
								}
								case B_POINT_TYPE:
								{
									BPoint val = message->FindPoint(nameFound, j);
									text.SetToFormat("X: %f Y: %f", val.x, val.y);
									break;
								}
								default:
									text.SetTo("TODO: unhandled message content type");
									break;
							}

							BRow* subRow = new BRow();
							subRow->SetField(new BStringField(name), 0);
							subRow->SetField(new BStringField(text), 1);
							fEventList->AddRow(subRow, row);
						}

					}
				}

				break;
			}
			case B_CUT:
			case B_COPY:
			{
				BRow* row = nullptr;

				BString fullMessage;

				// TODO copy all if selection is empty
				while (row = fEventList->CurrentSelection(row)) {
					BStringField* field = dynamic_cast<BStringField*>(row->GetField(1));
					const char* string = field->String();
					fullMessage.Prepend("\n");
					fullMessage.Prepend(string);
				}

				be_clipboard->Lock();
				be_clipboard->Clear();
				BMessage* clip = be_clipboard->Data();

				clip->AddData("text/plain", B_MIME_TYPE, fullMessage.String(), fullMessage.Length());

				be_clipboard->Commit();
				be_clipboard->Unlock();

				if (message->what == B_CUT) {
					while (row = fEventList->CurrentSelection(nullptr)) {
							fEventList->RemoveRow(row);
							delete row;
					}
				}

				break;
			}
			case B_ABOUT_REQUESTED:
			{
				be_app_messenger.SendMessage(B_ABOUT_REQUESTED);
				break;
			}
			default:
				BWindow::MessageReceived(message);
				break;
		}
	}

private:
	BColumnListView* fEventList;
};


class LoggerApp: public BApplication
{
public:
	LoggerApp()
		: BApplication("application/x-vnd.ml-BeDCApp")
	{
	}

	void ReadyToRun() override
	{
		BApplication::ReadyToRun();
		fActiveLogWindow = new LoggerWindow();
		fActiveLogWindow->Show();
	}

	void AboutRequested() override
	{
		BAboutWindow* about = new BAboutWindow("Dev Console", "application/x-vnd.ml-BeDCApp");
		about->AddDescription("Display log messages from other applications");
		about->AddCopyright(2023, "Adrien Destugues");
		about->Show();
	}

	void MessageReceived(BMessage* message) override
	{
		switch(message->what) {
			case BEDC_MESSAGE:
				DetachCurrentMessage();
				fActiveLogWindow->PostMessage(message);
				break;
			default:
				BApplication::MessageReceived(message);
				break;
		}
	}

private:
	BWindow* fActiveLogWindow;
};


int main(void)
{
	LoggerApp app;
	app.Run();
}
