#include "AllDevicesWidget.h"
#include "combinedSlider.h"
#include <map>
#include <algorithm>
#include "softProj\Main\MessageDialog.h"
#include <cassert>

DeviceItemWidget * AllDevicesWidget::addDevice(EDeviceType deviceType, const std::wstring & name, const std::string & deviceIconPath) {

	DeviceItemWidget * deviceWidget = new DeviceItemWidget(name, this, backgroundsHolder_);

	deviceWidget->setDeviceIcon(deviceIconPath);

	devices_.insert(std::pair<EDeviceType, DeviceItemWidget *>(deviceType, deviceWidget));

	ui_.devicesLayout->addWidget(deviceWidget, actRow, actColumn);

	actColumn++;

	if (actColumn == 3) {
		actColumn = 0;
		actRow++;
	}

	bool ok = connect(deviceWidget, SIGNAL(settingsChangedSignal()), this, SLOT(settingsChangedSlot()));
	assert(ok && "Signals not connected");

	return deviceWidget;
}

void AllDevicesWidget::lockForUpdate(bool lock) {
	isLockedForUpdate_ = lock;

	if (lock) {
		ui_.devicesSection->setAsChanged();
	}
	else {
		ui_.devicesSection->setAsNormal();
	}
}

void AllDevicesWidget::settingsChangedSlot() {
	lockForUpdate(true);
}

void AllDevicesWidget::setState(const answerDeviceEnergy & state) {

	if (!isLockedForUpdate_) {
		backgroundsHolder_->setLimits(state.MIN_ENERGY_PRIORITY, state.MAX_ENERGY_PRIORITY);

		devices_[ANDROIDS]->setState(state.ANDROIDS, state);
		devices_[HR_SENSORS]->setState(state.HR_SENSORS, state);
		devices_[LIFE_SUPPORT]->setState(state.LIFE_SUPPORT, state);
		devices_[LR_SENSORS]->setState(state.LR_SENSORS, state);
		devices_[MAINFRAME]->setState(state.MAINFRAME, state);
		devices_[MASKING]->setState(state.MASKING, state);
		devices_[SHIELDS]->setState(state.SHIELDS, state);
		devices_[TRANSPORT]->setState(state.TRANSPORT, state);
		devices_[WEAPONS]->setState(state.WEAPONS, state);

		lockForUpdate(false);
	}

	this->state_ = state;
	this->rememberUpdateTime();

	setMaximumEnergySupply(state.MAX_ENERGY);
	setCurrentEnergySupply(state.CURR_ENERGY);	

	setMaximumEnergyAccumulator(state.ACC_MAX_ENERGY);
	setCurrentEnergyAccumulator(state.ACC_CURR_ENERGY);	
}
 
void AllDevicesWidget::setCurrentEnergySupply(unsigned long long value) {
	ui_.energySupplySlider->setValue(value);
}

void AllDevicesWidget::setMaximumEnergySupply(unsigned long long value) {
	ui_.energySupplySlider->setMaximum(value);
}

void AllDevicesWidget::setCurrentEnergyAccumulator(unsigned long long value) {
	ui_.energyAccumulatorSlider->setValue(value);
}

void AllDevicesWidget::setMaximumEnergyAccumulator(unsigned long long value) {
	ui_.energyAccumulatorSlider->setMaximum(value);
}

AllDevicesWidget::~AllDevicesWidget() {
	if (messageDialog_ != NULL) {
		delete messageDialog_;
	}

	for (std::map<EDeviceType, DeviceItemWidget *>::iterator it = devices_.begin(); it != devices_.end(); ++it) {
		delete it->second;
	}

	delete backgroundsHolder_;
}

AllDevicesWidget::AllDevicesWidget(QWidget * parent) : NotifyWidget(parent) {
	ui_.setupUi(this);

	actRow = 0;
	actColumn = 0;

	backgroundsHolder_ = new DeviceBackgroundsHolder();

	ui_.devicesSection->setName(L"Rozdělení energie mezi zařízení");

	messageDialog_ = 0;

	addDevice(SHIELDS, L"Štíty", ":/pictures/images/details/stity.png");
	addDevice(WEAPONS, L"Zbraňový energetický\nokruh", ":/pictures/images/details/zbrane.png");
	addDevice(TRANSPORT, L"Transportní\npaprsek", ":/pictures/images/details/transport.png");

	addDevice(HR_SENSORS, L"Senzory s vysokým\nrozlišením", ":/pictures/images/details/senzory.png");
	addDevice(LR_SENSORS, L"Dálkové senzory", ":/pictures/images/details/pruzkum.png");
	addDevice(MASKING, L"Maskování", ":/pictures/images/details/maskovani.png");

	addDevice(ANDROIDS, L"Androidi", ":/pictures/images/details/androidi.png");
	addDevice(MAINFRAME, L"Mainframe", ":/pictures/images/details/pocitac.png");
	addDevice(LIFE_SUPPORT, L"Podpora života", ":/pictures/images/details/ubykace.png");

	ui_.energySupplySlider->setUnit(L"TJ");
	ui_.energySupplySlider->setName(L"Celková zásoba energie");
	ui_.energySupplySlider->setMaximumPrefix(L"Maximum\n");
	ui_.energySupplySlider->setCurrentPrefix(L"Aktuálně\n");
	
	ui_.energyAccumulatorSlider->setUnit(L"TJ");
	ui_.energyAccumulatorSlider->setName(L"Energie v akumulátoru");
	ui_.energyAccumulatorSlider->setMaximumPrefix(L"Maximum\n");
	ui_.energyAccumulatorSlider->setCurrentPrefix(L"Aktuálně\n");	

	bool ok = QObject::connect(ui_.devicesSection->submitButton, SIGNAL(clicked(bool)), this, SLOT(devicesSubmitedSlot(bool)));
	ok = ok && QObject::connect(ui_.devicesSection->cancelButton, SIGNAL(clicked(bool)), this, SLOT(devicesResetedSlot(bool)));

	assert(ok && "Signals not connected");

	ui_.energySupplySlider->setInvertedAppearance(false);
	ui_.energySupplySlider->setInvertedControls(false);
	ui_.energyAccumulatorSlider->setInvertedAppearance(false);
	ui_.energyAccumulatorSlider->setInvertedControls(false);

	ui_.energyAccumulatorSlider->setFontSize(8, QFont::Normal);
	ui_.energyAccumulatorSlider->setFontColor(QColor::fromRgb(240, 240, 240));
	ui_.energySupplySlider->setFontSize(8, QFont::Normal);
	ui_.energySupplySlider->setFontColor(QColor::fromRgb(240, 240, 240));

	lockForUpdate(false);
}

void AllDevicesWidget::initWidget() {
	for (DevicesIterator it = devices_.begin(); it != devices_.end(); ++it) {
		it->second->refreshBackgroundColor();
	}
}

void AllDevicesWidget::devicesSubmitedSlot(bool) {
	lockForUpdate(false);

	requestDeviceEnergy state = getState();
	emit submitDevicesSignal(state);
}

void AllDevicesWidget::devicesResetedSlot(bool) {
	lockForUpdate(false);

	emit resetDevicesSignal();
}

void AllDevicesWidget::setStateERROR(unsigned long shipId, const std::string & reason) {
	lockForUpdate(false);
}

void AllDevicesWidget::showMessageDialog(const std::string & title, const std::string & message) {
	if (messageDialog_ == NULL) {
		messageDialog_ = new MessageDialog(this);
																						   
		bool ok = connect(messageDialog_, SIGNAL(submitSignal()), this, SLOT(submitMessageDialogSlot()));

		assert(ok && "Signals not connected");

		messageDialog_->setWindowFlags(Qt::SplashScreen);
     }

	 messageDialog_->setTitle(title);
	 messageDialog_->setMessage(message);

     messageDialog_->show();
     messageDialog_->raise();
     messageDialog_->activateWindow();
}

void AllDevicesWidget::submitMessageDialogSlot() {
	messageDialog_->accept();
}

void AllDevicesWidget::notifyUpdate() { 
	double difference = getDifferenceFromUpdateTime();

	ui_.energyAccumulatorSlider->setValue(getUpdatedValue(state_.ACC_CURR_ENERGY, state_.accumulatorGradient, difference));
	ui_.energySupplySlider->setValue(getUpdatedValue(state_.CURR_ENERGY, state_.totalEnergyGradient, difference));
}