#include "../../Headers/GUI/ComponentPanel.h"
#include <wx/sizer.h>
#include <wx/dcclient.h>
#include <wx/artprov.h>

/**
* Builds the component tile: stores the component data and lays out the icon and the name/status/data text fields
* in a vertical sizer.
*
* @author Eddie O'Hagan
* @date 8/13/2026
*
* @code
*	ComponentPanel* panel = new ComponentPanel(parent, componentData);
* @endcode
*
* @param [in] theParentWindow  The parent window.
* @param [in] theComponentData The component this panel displays.
*/
ComponentPanel::ComponentPanel(wxWindow* theParentWindow, const ComponentData& theComponentData)
	: wxPanel(theParentWindow, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxBORDER_SUNKEN)
{
	myComponentData = theComponentData;

	//Main layout for this individual panel
	wxBoxSizer* mainSizer = new wxBoxSizer(wxVERTICAL);

	//Image Field
	myComponentIconField = new wxStaticBitmap(this, wxID_ANY, wxArtProvider::GetBitmap(wxART_MISSING_IMAGE));

	//Three Text Boxes (StaticText for labels or TextCtrl for input)
	myDeviceNameField = new wxTextCtrl(this, wxID_ANY, "Device Name", wxDefaultPosition, wxDefaultSize, wxTE_MULTILINE | wxTE_READONLY | wxTE_NO_VSCROLL);
	myStatusField = new wxTextCtrl(this, wxID_ANY, "Status", wxDefaultPosition, wxDefaultSize, wxTE_MULTILINE | wxTE_READONLY | wxTE_NO_VSCROLL);
	myDataField = new wxTextCtrl(this, wxID_ANY, "Data", wxDefaultPosition, wxDefaultSize, wxTE_MULTILINE | wxTE_READONLY | wxTE_NO_VSCROLL);

	//Add elements to the sizer.
	mainSizer->Add(myComponentIconField, 0, wxALIGN_CENTER | wxALL, 5);
	mainSizer->Add(myDeviceNameField, 0, wxEXPAND | wxALL, 2);
	mainSizer->Add(myStatusField, 0, wxEXPAND | wxALL, 2);
	mainSizer->Add(myDataField, 0, wxEXPAND | wxALL, 2);

	this->SetSizer(mainSizer);
}

/**
* Refreshes the tile's controls from the current component data (icon, name, enabled/disabled status, data) and
* re-sizes the data field to fit.
*
* @author Eddie O'Hagan
* @date 8/13/2026
*
* @code
*	panel.UpdateUI();
* @endcode
*/
void ComponentPanel::UpdateUI()
{
	myComponentIconField->SetBitmap(myComponentData.GetIcon());

	myDeviceNameField->SetValue(myComponentData.GetName());

	if (myComponentData.GetIsEnabled() == true)
	{
		myStatusField->SetValue("ENABLED");
	}
	else
	{
		myStatusField->SetValue("DISABLED");
	}

	myDataField->SetValue(myComponentData.GetData());

	AdjustDataFieldHeight();
}

/**
* Adjusts the height of the data field so all the text can be shown, then re-lays out this panel and its parent.
*
* @author Eddie O'Hagan
* @date 8/13/2026
*
* @code
*	//Called by UpdateUI() after the data field's text changes.
* @endcode
*/
void ComponentPanel::AdjustDataFieldHeight()
{
	int finalHeight;
	int heightPadding = 30;
	wxString currDataFieldText;
	wxSize multilineTextSize;

	//Get the client device contex so we can manipulate the number of lines or the pixel size of the text of the field.
	wxClientDC dataFieldDeviceContext(myDataField);
	dataFieldDeviceContext.SetFont(myDataField->GetFont());

	currDataFieldText = myDataField->GetValue();
	multilineTextSize = dataFieldDeviceContext.GetMultiLineTextExtent(currDataFieldText);

	//Add some padding for the text control borders
	finalHeight = multilineTextSize.y + heightPadding;

	//Set the minimum size so the sizer respects the new height.
	myDataField->SetMinSize(wxSize(-1, finalHeight));

	//Force the panel to re-calculate the layout
	this->Layout();

	//Tells the GridSizer to re-space the panels
	this->GetParent()->Layout();
}

/**
* Gets the component data this panel displays.
*
* @author Eddie O'Hagan
* @date 8/13/2026
*
* @code
*	ComponentData& data = panel.GetComponentData();
* @endcode
*
* @return A reference to the panel's component data.
*/
ComponentData& ComponentPanel::GetComponentData()
{
	return myComponentData;
}
