#include "buildWidget.h"
#include <cassert>
#include "softProj\settings.h"
#include "softProj\WeaponsWidget\fightWidgetRow.h"
#include "../../streams/ErrorStream.h"

extern KODIAK_DEBUG_STREAM KODIAK_DEBUG_COUT;

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

	isSynchronizing_ = false;

	ownedFortressesTable_ = new BuildWidgetTable(this, FORTRESS_BUILD_TABLE_OWNED);
	ownedFortressesTable_->setTable(ui_.ownedFortressesTable);
	ownedFortressesTable_->setTitle(ui_.ownedFortressesNameButton);
	ownedFortressesTable_->setSearchButton(ui_.ownedFortressesSearchButton);
    ownedFortressesTable_->setShowAllButton(ui_.ownedFortressesAllButton);
	ownedFortressesTable_->setSearchEdit(ui_.ownedFortressesSearchEdit);
    ownedFortressesTable_->connectSignals();

	classesTable_ = new BuildWidgetTable(this, FORTRESS_BUILD_TABLE_CLASSES);
	classesTable_->setTable(ui_.shipsTable);
	classesTable_->setTitle(ui_.shipsNameButton);
	classesTable_->setSearchButton(ui_.shipsSearchButton);
    classesTable_->setShowAllButton(ui_.shipsAllButton);
	classesTable_->setSearchEdit(ui_.shipsSearchEdit);
    classesTable_->connectSignals();

	uncontrolledTable_ = new BuildWidgetTable(this, FORTRESS_BUILD_TABLE_UNCONTROLLED);
	uncontrolledTable_->setTable(ui_.basesTable);
	uncontrolledTable_->setTitle(ui_.basesNameButton);
	uncontrolledTable_->setSearchButton(ui_.basesSearchButton);
    uncontrolledTable_->setShowAllButton(ui_.basesAllButton);
	uncontrolledTable_->setSearchEdit(ui_.basesSearchEdit);
    uncontrolledTable_->connectSignals();

	selectedRow_ = 0;

	bool connected = true;
	connected = connected && connect(ui_.conquerButton, SIGNAL(clicked(bool)), this, SLOT(conquerButtonClickedSlot()));
	connected = connected && connect(ui_.buildButton, SIGNAL(clicked(bool)), this, SLOT(buildButtonClickedSlot()));
	connected = connected && connect(ui_.tradeButton, SIGNAL(clicked(bool)), this, SLOT(tradeButtonClickedSlot()));

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

	ui_.titaniumSlider->setName(L"Titan");
	ui_.titaniumSlider->setFontColor(QColor::fromRgb(40, 40, 40));

	normalStyle_ = QString::fromUtf8("background-color: rgb(35, 35, 35, 140); color: rgb(255, 255, 255); font-size: 10px; padding: 0; padding-right: 3px; padding-left: 3px;");
	normalBigStyle_ = QString::fromUtf8("background-color: rgb(35, 35, 35, 140); color: rgb(255, 255, 255); font-size: 11px; padding: 0; padding-right: 3px; padding-left: 3px;");
	yesStyle_ = QString::fromUtf8("background-color: rgb(35, 35, 35, 140); color: rgb(110, 155, 80); font-size: 10px; padding: 0; padding-right: 3px; padding-left: 3px;");
	yesBigStyle_ = QString::fromUtf8("background-color: rgb(35, 35, 35, 140); color: rgb(110, 155, 80); font-size: 11px; padding: 0; padding-right: 3px; padding-left: 3px;");
	noStyle_ = QString::fromUtf8("background-color: rgb(35, 35, 35, 140); color: rgb(180, 50, 80); font-size: 10px; padding: 0; padding-right: 3px; padding-left: 3px;");
	noBigStyle_ = QString::fromUtf8("background-color: rgb(35, 35, 35, 140); color: rgb(180, 50, 80); font-size: 11px; padding: 0; padding-right: 3px; padding-left: 3px;");

	hiddenIcon_ = QIcon();
    yesIcon_.addFile(QString::fromUtf8(":/pictures/images/trade/ok-big.png"), QSize(12, 12), QIcon::Normal, QIcon::Off);
	noIcon_.addFile(QString::fromUtf8(":/pictures/images/trade/not-ok-big.png"), QSize(12, 12), QIcon::Normal, QIcon::Off);

	stepSelectOwnedFortress(false);
}

void BuildWidget::clearState() {
	ownedFortressesTable_->clearAllContent();
	uncontrolledTable_->clearAllContent();
	classesTable_->clearAllContent();

	stepSelectOwnedFortress(false);
}

void BuildWidget::setUncontrolledFortresses(id_t fortressId, const std::vector<FortressInRangeData> & ships, const std::vector<FortressInRangeData> & bases) {
    clearAllUncontrollableFortresses();

    for (std::vector<FortressInRangeData>::const_iterator it = ships.begin(); it != ships.end(); ++it) {
		insertUncontrollableFortress(new FightWidgetRow(*it, FORTRESS_TYPE_SHIP));
    }

    for (std::vector<FortressInRangeData>::const_iterator it = bases.begin(); it != bases.end(); ++it) {
		insertUncontrollableFortress(new FightWidgetRow(*it, FORTRESS_TYPE_BASE));
    }
}

BuildWidget::~BuildWidget()
{
	delete ownedFortressesTable_;
	delete uncontrolledTable_;
}

void BuildWidget::ownedFortressClicked(FightWidgetRow * item, int row) {
	if (item == 0) { return; }

	selectedRow_ = row;
	setSelfPartner(item);	
	setNoEnemyPartner();

	ownedFortressesTable_->setRowAsClicked(row);
	uncontrolledTable_->setNoRowAsClicked();
	classesTable_->setNoRowAsClicked();

	ui_.helpStackedWidget->setCurrentWidget(ui_.helpPage);

	emit fortressesInConquerRangeSignal(item->getId());
	emit fortressClassesSignal(item->getId());

	ui_.buttonsStackedWidget->setCurrentWidget(ui_.infoPage);
	
	fortress_build_information buildData = buildInformation_[item->getId()];

	if (buildData.isTherePlanetToBuildABase) {
		ui_.planetValue->setText(QString::fromUtf8(buildData.planetToBuildABaseName.c_str()));
		ui_.planetValue->setStyleSheet(yesStyle_);
		ui_.planetLabel->setIcon(yesIcon_);
	}
	else {
		ui_.planetValue->setText(QString::fromUtf16(L"Není planeta v dosahu"));
		ui_.planetValue->setStyleSheet(noStyle_);	
		ui_.planetLabel->setIcon(noIcon_);
	}

	ui_.shipTitanValue->setText(Settings::instance().formatNumber(buildData.fortressTitan));
	ui_.shellRequiredTitanValue->setText(Settings::instance().formatNumber(buildData.requiredTitan));

	if (buildData.fortressTitan >= buildData.requiredTitan) {
		ui_.shellRequiredTitanValue->setStyleSheet(yesStyle_);
		ui_.shellRequiredTitanLabel->setIcon(yesIcon_);
	}
	else {		
		ui_.shellRequiredTitanValue->setStyleSheet(noStyle_);
		ui_.shellRequiredTitanLabel->setIcon(noIcon_);
	}

	ui_.buttonsStackedWidget->setCurrentWidget(ui_.infoPage);

	if (buildData.fortressTitan >= buildData.requiredTitan && buildData.isTherePlanetToBuildABase) {
		
		ui_.infoLabel->setText(QString::fromUtf16(L"Vybraná pevnost může stavět novou základnu na planetě ") + QString::fromUtf8(item->getPlanetName().c_str())
			+ QString::fromUtf16(L". Pokud chceš stavět, vyber si třídu pevnosti pro postavení. "));
		ui_.infoLabel->setStyleSheet(normalBigStyle_);
	}
	else {		
		QString reason = QString::fromUtf16(L"Vybraná pevnost nemůže stavět novou základnu. ");

		if (buildData.fortressTitan < buildData.requiredTitan) {
			reason += QString::fromUtf16(L"Pevnost má méně titanu, než je minimální množství na stavbu skořápky. ");
		}

		if (!buildData.isTherePlanetToBuildABase) {
			reason += QString::fromUtf16(L"Pevnost nemá v dosahu planetu, na které by mohla základnu postavit. ");
		}

		ui_.infoLabel->setText(reason);
		ui_.infoLabel->setStyleSheet(noBigStyle_);
	}

	ui_.minimumTitanValue->setText(QString::fromUtf16(L"Žádná vybraná třída pevnosti"));
	ui_.minimumTitanValue->setStyleSheet(normalStyle_);
	ui_.minimumTitanLabel->setIcon(hiddenIcon_);
	ui_.maximumTitanValue->setText(QString::fromUtf16(L"Žádná vybraná třída pevnosti"));
	ui_.maximumTitanValue->setStyleSheet(normalStyle_);
	ui_.maximumTitanLabel->setIcon(hiddenIcon_);
	ui_.baseClassValue->setText(QString::fromUtf16(L"Žádná vybraná třída pevnosti"));
	ui_.baseClassValue->setStyleSheet(normalStyle_);
	ui_.baseClassLabel->setIcon(hiddenIcon_);
}

void BuildWidget::uncontrolledFortressClicked(FightWidgetRow * item, int row) {
	selectedRow_ = row;	
	setEnemyPartner(item);

	uncontrolledTable_->setRowAsClicked(row);

	ui_.helpStackedWidget->setCurrentWidget(ui_.helpPage);

	ui_.buttonsStackedWidget->setCurrentWidget(ui_.uncontrolledPage);
	ui_.conquerHeader->setText(QString::fromUtf16(L"Nyní můžeš převzít kontrolu nad vybranou pevností, nebo s ní můžeš zahájit výměnu předmětů."));

	ui_.minimumTitanValue->setText(QString::fromUtf16(L"Žádná vybraná třída pevnosti"));
	ui_.minimumTitanValue->setStyleSheet(normalStyle_);
	ui_.minimumTitanLabel->setIcon(hiddenIcon_);
	ui_.baseClassValue->setText(QString::fromUtf16(L"Žádná vybraná třída pevnosti"));
	ui_.baseClassValue->setStyleSheet(normalStyle_);
	ui_.baseClassLabel->setIcon(hiddenIcon_);
}

void BuildWidget::fortressClassClicked(FightWidgetRow * item, int row) {
	selectedRow_ = row;	
	classesTable_->setRowAsClicked(row);
	ui_.enemyPartner->setFortressClass(item->getId(), item->getName(), item->isShip());
	emit fortressClassDetailsSignal(item->getId());	
}

void BuildWidget::clearAllOwnedFortresses() {
    ownedFortressesTable_->clearAllContent();
}

void BuildWidget::clearAllUncontrollableFortresses() {
	uncontrolledTable_->clearAllContent();
}

void BuildWidget::clearAllFortressClasses() {
	classesTable_->clearAllContent();
}

void BuildWidget::insertOwnedFortress(FightWidgetRow * item) {
	ownedFortressesTable_->insertItem(item);
}

void BuildWidget::insertUncontrollableFortress(FightWidgetRow * item) {
	uncontrolledTable_->insertItem(item);
}

void BuildWidget::insertFortressClass(FightWidgetRow * item) {
	classesTable_->insertItem(item);
}

void BuildWidget::setSelfPartner(FightWidgetRow * item) {
	ui_.selfPartner->setPartner(item->getId(), item->getName(), item->getRealmName(), item->isOwned(), item->isShip());
}

void BuildWidget::setEnemyPartner(FightWidgetRow * item) {
	ui_.enemyPartner->setPartner(item->getId(), item->getName(), item->getRealmName(), item->isOwned(), item->isShip());
}

void BuildWidget::conquerButtonClickedSlot() {
	emit conquerSignal(ui_.selfPartner->getFortressId(), ui_.enemyPartner->getFortressId());
}

void BuildWidget::buildButtonClickedSlot() {
	emit buildNewBaseShellSignal(ui_.selfPartner->getFortressId(), ui_.enemyPartner->getFortressId(), ui_.titaniumSlider->getValue());
}

void BuildWidget::tradeButtonClickedSlot() {
	emit tradeSignal(ui_.selfPartner->getFortressId(), ui_.enemyPartner->getFortressId());
}

void BuildWidget::setNoSelfPartner() {
	ui_.selfPartner->setNone();
}

void BuildWidget::setNoEnemyPartner() {
	ui_.enemyPartner->setNone();
}

void BuildWidget::answerBuildNewBaseShell(id_t selfFortressId, BaseBuildingResult result, unsigned long long newTitan) {
	if (result == BBR_SHELL_BUILT) {
		ui_.shipTitanValue->setText(Settings::instance().formatNumber(newTitan));
		emit fortressesInConquerRangeSignal(ui_.selfPartner->getFortressId());
	}
}

void BuildWidget::answerAvailableFortressClasses(id_t selfFortressId, const std::list<fortress_class_simple_data> & shipClasses, const std::list<fortress_class_simple_data> & baseClasses) {
    clearAllFortressClasses();

    for (std::list<fortress_class_simple_data>::const_iterator it = shipClasses.begin(); it != shipClasses.end(); ++it) {
		insertFortressClass(new FightWidgetRow(*it, FORTRESS_TYPE_SHIP));
    }

    for (std::list<fortress_class_simple_data>::const_iterator it = baseClasses.begin(); it != baseClasses.end(); ++it) {
		insertFortressClass(new FightWidgetRow(*it, FORTRESS_TYPE_BASE));
	}
}

void BuildWidget::answerFortressClassData(const fortress_class_complex_data & data) {
	ui_.massRatingValue->setText(Settings::instance().formatNumber(data.massRating));
	ui_.maxDroneLaunchersValue->setText(Settings::instance().formatNumber(data.maxDroneMissileLaunchers));
	ui_.maxHeightValue->setText(Settings::instance().formatNumber(data.maxHeight) + " m");
	ui_.maxWidthValue->setText(Settings::instance().formatNumber(data.maxWidth) + " m");
	ui_.maxLaserGunsValue->setText(Settings::instance().formatNumber(data.maxLaserGuns));
	ui_.maxLengthValue->setText(Settings::instance().formatNumber(data.maxLength) + " m");
	ui_.maxStructuralIntegrityValue->setText(Settings::instance().formatNumber(data.maxTotalStructuralIntegrity));
	ui_.maxWeaponsValue->setText(Settings::instance().formatNumber(data.maxWeapons));
	ui_.minStructuralIntegrityValue->setText(Settings::instance().formatNumber(data.minTotalStructuralIntegrity));
	ui_.minWeightValue->setText(Settings::instance().formatNumber(data.minWeight) + " kg");
	ui_.maxWeightValue->setText(Settings::instance().formatNumber(data.maxWeight) + " kg");
	ui_.nameLabel->setText(QString::fromUtf8(data.name.c_str()));
	ui_.qualityValue->setText(Settings::instance().formatNumber(data.qualityRating));

	ui_.helpStackedWidget->setCurrentWidget(ui_.detailsPage);

	fortress_build_information buildData = buildInformation_[ui_.selfPartner->getFortressId()];

	if (buildData.isTherePlanetToBuildABase) {
		ui_.planetValue->setText(QString::fromUtf8(buildData.planetToBuildABaseName.c_str()));
		ui_.planetValue->setStyleSheet(yesStyle_);
		ui_.planetLabel->setIcon(yesIcon_);
	}
	else {
		ui_.planetValue->setText(QString::fromUtf16(L"Není planeta v dosahu"));
		ui_.planetValue->setStyleSheet(noStyle_);	
		ui_.planetLabel->setIcon(noIcon_);
	}

	ui_.shipTitanValue->setText(Settings::instance().formatNumber(buildData.fortressTitan));

	if (buildData.fortressTitan >= buildData.requiredTitan) {
		ui_.shellRequiredTitanValue->setStyleSheet(yesStyle_);
		ui_.shellRequiredTitanLabel->setIcon(yesIcon_);
	}
	else {
		ui_.shipTitanValue->setStyleSheet(noStyle_);	
	
		ui_.shellRequiredTitanValue->setText(Settings::instance().formatNumber(buildData.requiredTitan));
		ui_.shellRequiredTitanValue->setStyleSheet(noStyle_);
		ui_.shellRequiredTitanLabel->setIcon(noIcon_);
	}

	if (buildData.fortressTitan >= buildData.requiredTitan && buildData.isTherePlanetToBuildABase && data.isBaseClass) {
		ui_.buttonsStackedWidget->setCurrentWidget(ui_.buildPage);
		ui_.buildLabel->setText(QString::fromUtf16(L"Můžeš postavit novou základnu na planetě ") + QString::fromUtf8(buildData.planetToBuildABaseName.c_str()));
		ui_.buildLabel->setStyleSheet(yesBigStyle_);		

		ui_.titaniumSlider->setMaximum(data.maxWeight);
		ui_.titaniumSlider->setMinimum(data.minWeight);
		ui_.titaniumSlider->setValue(data.minWeight);
	}
	else {		
		ui_.buttonsStackedWidget->setCurrentWidget(ui_.infoPage);

		QString reason = QString::fromUtf16(L"Nemůžeš postavit novou základnu.");

		if (buildData.fortressTitan < buildData.requiredTitan) {
			reason += QString::fromUtf16(L"Pevnost má méně titanu, než je minimální množství na stavbu skořápky. ");
		}

		if (!buildData.isTherePlanetToBuildABase) {
			reason += QString::fromUtf16(L"Pevnost nemá v dosahu planetu, na které by mohla základnu postavit. ");
		}

		if (!data.isBaseClass) {
			reason += QString::fromUtf16(L"Nevybral jsi třídu základny. ");
		}

		ui_.infoLabel->setText(reason);
		ui_.infoLabel->setStyleSheet(noBigStyle_);
	}	
	
	if (data.isBaseClass) {
		ui_.baseClassValue->setText("Ano");
		ui_.baseClassValue->setStyleSheet(yesStyle_);	
		ui_.baseClassLabel->setIcon(yesIcon_);
	}
	else {
		ui_.baseClassValue->setText("Ne");
		ui_.baseClassValue->setStyleSheet(noStyle_);	
		ui_.baseClassLabel->setIcon(noIcon_);
	}

	ui_.minimumTitanValue->setText(Settings::instance().formatNumber(data.minWeight));
	ui_.maximumTitanValue->setText(Settings::instance().formatNumber(data.maxWeight));
}

void BuildWidget::setOwnedFortresses(const std::list<fortress_build_information> & ships, const std::list<fortress_build_information> & bases) {
    clearAllOwnedFortresses();
	buildInformation_.clear();

    for (std::list<fortress_build_information>::const_iterator it = ships.begin(); it != ships.end(); ++it) {
		insertOwnedFortress(new FightWidgetRow(*it, FORTRESS_TYPE_SHIP));
		buildInformation_[it->fortressId] = *it;
    }

    for (std::list<fortress_build_information>::const_iterator it = bases.begin(); it != bases.end(); ++it) {
		insertOwnedFortress(new FightWidgetRow(*it, FORTRESS_TYPE_BASE));
		buildInformation_[it->fortressId] = *it;
    }
}

void BuildWidget::answerConquerFortress(const ConquerResultData & data) {
	if (data.isConquered) {
		stepSelectOwnedFortress(true);
	}
}

void BuildWidget::stepSelectOwnedFortress(bool reloadData) {
	ui_.planetValue->setText(QString::fromUtf16(L"Žádná vybraná pevnost"));
	ui_.planetValue->setStyleSheet(normalStyle_);
	ui_.planetLabel->setIcon(hiddenIcon_);
	ui_.shellRequiredTitanValue->setText(QString::fromUtf16(L"Žádná vybraná pevnost"));
	ui_.shellRequiredTitanValue->setStyleSheet(normalStyle_);
	ui_.shellRequiredTitanLabel->setIcon(hiddenIcon_);
	ui_.shipTitanValue->setText(QString::fromUtf16(L"Žádná vybraná pevnost"));
	ui_.shipTitanValue->setStyleSheet(normalStyle_);
	ui_.shipTitanLabel->setIcon(hiddenIcon_);
	
	ui_.buttonsStackedWidget->setCurrentWidget(ui_.infoPage);
	ui_.infoLabel->setText(QString::fromUtf16(L"Vyber si některou ze svých pevností, se kterou pak budeš chtít stavět novou základnu, nebo převzít kontrolu nad jinou pevností."));
	ui_.infoLabel->setStyleSheet(normalBigStyle_);
	
	ui_.minimumTitanValue->setText(QString::fromUtf16(L"Žádná vybraná třída pevnosti"));
	ui_.minimumTitanValue->setStyleSheet(normalStyle_);
	ui_.minimumTitanLabel->setIcon(hiddenIcon_);
	ui_.baseClassValue->setText(QString::fromUtf16(L"Žádná vybraná třída pevnosti"));
	ui_.baseClassValue->setStyleSheet(normalStyle_);
	ui_.baseClassLabel->setIcon(hiddenIcon_);

	setNoEnemyPartner();
	setNoSelfPartner();

	clearAllFortressClasses();
	clearAllUncontrollableFortresses();

	ui_.helpStackedWidget->setCurrentWidget(ui_.helpPage);

	if (reloadData) {
		emit ownedFortressesSignal();
	}
}