#include "itemwidget.h"
#include "ui_itemwidget.h"

#include <QCheckBox>
#include <QComboBox>
#include <QDebug>
#include <QSlider>
#include "itemsettingsdialog.h"

ItemWidget::ItemWidget(std::weak_ptr<Item> item, bool noGroupEdit, QWidget *parent) :
	QWidget(parent),
	item_(item),
	noGroupEdit_(noGroupEdit),
	ui(new Ui::ItemWidget)
{
	ui->setupUi(this);

	if(auto workingItem = item_.lock())
	{
		if(workingItem->getValueType() == ITEM_VALUE_UINT)
		{
			ui->horizontalSpacer->changeSize(0,0);
			ui->checkBox->hide();
			ui->comboBox->hide();
		}
		else if(workingItem->getValueType() == ITEM_VALUE_NO_VALUE)
		{
			ui->checkBox->hide();
			ui->slider->hide();
			ui->comboBox->hide();
		}
		else if(workingItem->getValueType() == ITEM_VALUE_ENUM)
		{
			ui->slider->hide();
			ui->checkBox->hide();
			QStringList list;
			for(const QString& name : workingItem->getValueNames())
				list.append(name);
			ui->comboBox->addItems(list);
			ui->comboBox->setCurrentIndex(workingItem->getValue());
		}
		else
		{
			ui->slider->hide();
			ui->comboBox->hide();
		}

		ui->checkBox->setChecked(workingItem->getValue());

		ui->label->setText(workingItem->getName());

		if(workingItem->getValueType() == ITEM_VALUE_UINT)
			connect(ui->slider, &QSlider::valueChanged, this, &ItemWidget::moveToValue);
		else if(workingItem->getValueType() == ITEM_VALUE_ENUM)
			connect(ui->comboBox, QOverload<int>::of(&QComboBox::currentIndexChanged), this, &ItemWidget::moveToValue);
		else
			connect(ui->checkBox, &QCheckBox::toggled, this, &ItemWidget::moveToState);
		connect(ui->pushButton, &QPushButton::clicked, this, &ItemWidget::showSettingsDialog);
		connect(workingItem.get(), &Item::updated, this, &ItemWidget::onItemUpdated);
		connect(ui->pushButton_Remove, &QPushButton::clicked, this, &ItemWidget::deleteItem);
	}
	else
	{
		disable();
	}

	setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed);
}

void ItemWidget::deleteItem()
{
	if(auto workingItem = item_.lock())
	{
		deleteRequest(*workingItem);
	}
}

void ItemWidget::moveToValue(int value)
{
	if(auto workingItem = item_.lock())
	{
		ItemUpdateRequest request = workingItem->createValueUpdateRequest(ITEM_UPDATE_USER);
		request.payload.setValueData(value);
		request.changes.value = true;
		workingItem->requestUpdate(request);
	}
	else
	{
		disable();
	}
}

void ItemWidget::moveToState(bool state)
{
	moveToValue(state);
}

void ItemWidget::disable()
{
	ui->checkBox->setEnabled(false);
	ui->label->setEnabled(false);
	ui->slider->setEnabled(false);
	ui->comboBox->setEnabled(false);
	ui->pushButton_Remove->setEnabled(false);
}

bool ItemWidget::controles(const ItemData& relay)
{
	if(auto workingItem = item_.lock())
	{
		if(relay == *workingItem) return  true;
		else return false;
	}
	return true;
}

void ItemWidget::showSettingsDialog()
{
	if(auto workingItem = item_.lock())
	{
		ItemSettingsDialog dialog(workingItem, noGroupEdit_, this);
		dialog.exec();

	}
	else disable();
}

std::weak_ptr<Item> ItemWidget::getItem()
{
	return item_;
}

void ItemWidget::onItemUpdated(ItemUpdateRequest update)
{
	if(update.changes.valueNames)
	{
		ui->comboBox->blockSignals(true);
		ui->comboBox->clear();
		QStringList list;
		for(const QString& name : update.payload.getValueNames())
			list.append(name);
		ui->comboBox->addItems(list);
		ui->comboBox->blockSignals(false);
	}
	stateChanged(update.payload.getValue());
}

void ItemWidget::stateChanged(int state)
{
	ui->slider->blockSignals(true);
	ui->slider->setValue(state);
	ui->slider->blockSignals(false);
	ui->checkBox->blockSignals(true);
	ui->checkBox->setChecked(state);
	ui->checkBox->blockSignals(false);
	ui->comboBox->blockSignals(true);
	ui->comboBox->setCurrentIndex(state);
	ui->comboBox->blockSignals(false);
}

ItemWidget::~ItemWidget()
{
	delete ui;
}
