#include <QtGui>
#include <vector>
#include <cassert>
#include "ui_DetailsWidget.h"
#include "DetailsWidget.h"
#include "SimpleItem.h"
#include "ComplexItem.h"
#include "softProj\helpers.h"
#include "styles.h"
#include "softProj\settings.h"
#include "softProj\WeaponsWidget\weaponItem.h"

void DetailsWidget::changeSelectedFortressSlot(int row, int column)
{
 	SimpleItem * clickedItem = findItemRow(row);
	
	if (clickedItem == NULL) {
		return;
	}

	changeSelectedFortress(*clickedItem);

	ui_.renameButton->setEnabled(true);

	emit changeSelectedFortressSignal(*clickedItem);
}

void DetailsWidget::changeSelectedFortress(SimpleItem & item)
{
	setItemRowAsSelected(item);	
}

DetailsWidget::DetailsWidget(QWidget * parent) : NotifyWidget(parent)
{
	ui_.setupUi(this);
	ui_.itemsListView->setRowCount(4);

	currentWidget_ = NULL;
		
	bool connected = true;

	connected = connected && QObject::connect(
		ui_.itemsListView, SIGNAL(cellClicked(int, int)),
		this, SLOT(changeSelectedFortressSlot(int, int))
	);

	shipButtonsLayout_ = new QGridLayout(ui_.shipButtonsFrame);
	baseButtonsLayout_ = new QGridLayout(ui_.baseButtonsFrame);

	ParamsHolder * params = new ParamsHolder();
	int shipParamsCount = params->getShipParamsCount();

	for (int i = 0; i < 16 && i < shipParamsCount; ++i)
	{
		ShipParam * param = params->getShipParam(i);
		setShipButton(shipButtonsLayout_, ui_.shipButtonsFrame, param, i, 4);
	}

	shipMoreButtonsLayout_ = new QGridLayout(ui_.shipMoreButtonsFrame);

	for (int i = 16; i < shipParamsCount; ++i)
	{
		ShipParam * param = params->getShipParam(i);
		setShipButton(shipMoreButtonsLayout_, ui_.shipMoreButtonsFrame, param, i, 1);
	}

	int baseParamsCount = params->getBaseParamsCount();

	for (int i = 0; i < 16 && i < baseParamsCount; ++i)
	{
		BaseParam * param = params->getBaseParam(i);
		setBaseButton(baseButtonsLayout_, ui_.baseButtonsFrame, param, i, 4);
	}	

	baseMoreButtonsLayout_ = new QGridLayout(ui_.baseMoreButtonsFrame);

	for (int i = 16; i < baseParamsCount; ++i)
	{
		BaseParam * param = params->getBaseParam(i);
		setBaseButton(baseMoreButtonsLayout_, ui_.baseMoreButtonsFrame, param, i, 1);
	}	

	ui_.itemsListView->setFocusPolicy(Qt::NoFocus);

	hideItemsPanel();
	hideDetailsPanel();

	ui_.paramsPanelStack->setCurrentWidget(ui_.weaponsPage);
}

void DetailsWidget::setShipButton(QGridLayout * layout, QFrame * frame, ShipParam * param, int index, int itemsInRow) {
	QPushButton * button = new QShipButton(wstringToQString(param->getDescription()), ui_.baseButtonsFrame, param->getEnum());
	button->setMinimumHeight(18);

	layout->addWidget(button, (int)(index / itemsInRow), index % itemsInRow, 1, 1);

	Settings::instance().connectSound(button);

	bool ok = QObject::connect(
		button, SIGNAL(clicked(EShipSectionState)),
		this, SLOT(showShipSectionSlot(EShipSectionState))
	);

	assert(ok && "Qt signal not connected");

	button->setEnabled(param->isEnabled());			
	setButtonIconFromResources(button, param->getFilePath());
}

void DetailsWidget::setBaseButton(QGridLayout * layout, QFrame * frame, BaseParam * param, int index, int itemsInRow) {
	QPushButton * button = new QBaseButton(wstringToQString(param->getDescription()), ui_.baseButtonsFrame, param->getEnum());
	button->setMinimumHeight(18);

	layout->addWidget(button, (int)(index / itemsInRow), index % itemsInRow, 1, 1);

	Settings::instance().connectSound(button);

	bool ok = QObject::connect(
		button, SIGNAL(clicked(EBaseSectionState)),
		this, SLOT(showBaseSectionSlot(EBaseSectionState))
	);

	assert(ok && "Qt signal not connected");

	button->setEnabled(param->isEnabled());			
	setButtonIconFromResources(button, param->getFilePath());
}

DetailsWidget::~DetailsWidget()
{
}

void DetailsWidget::setItemsTableRow(const SimpleItem & item)
{
    const int targetRow = ui_.itemsListView->rowCount();
    ui_.itemsListView->insertRow(targetRow);

	QTableWidgetItem * tableItem = new QTableWidgetItem(QString::fromUtf8(item.name.c_str()));
    tableItem->setData(Qt::UserRole, QVariant::fromValue(item.id));
	ui_.itemsListView->setItem(targetRow, 0, tableItem);
    rows_.insert(std::make_pair(item.id, item));	
}

void DetailsWidget::setItemsTable(GameItemsVector & items)
{
	rows_.clear();

	int rowCount = ui_.itemsListView->rowCount();
	
	for (int i = rowCount; i >= 0; --i) {
		ui_.itemsListView->removeRow(i);
	}

	for (GameItemsVector::iterator it = items.begin(); it != items.end(); ++it)
	{
		setItemsTableRow(*it);
	}

	showItemsPanel();
}

void DetailsWidget::showShipsTable(GameItemsVector & items)
{
	setItemsTable(items);
	ui_.itemsLabel->setText("Seznam lodí");

	ui_.buttonsPanelStack->setCurrentWidget(ui_.shipButtonsPage);
	ui_.moreButtonsPanelStack->setCurrentWidget(ui_.shipMoreButtonsPage);
}

SimpleItem * DetailsWidget::findFortressById(id_t fortressId) {
	if (rows_.find(fortressId) != rows_.end()) {
		return &rows_[fortressId];
	}
	else {
		return NULL;
	}
}

void DetailsWidget::showBasesTable(GameItemsVector & items)
{
	setItemsTable(items);
	ui_.itemsLabel->setText("Seznam základen");

	ui_.buttonsPanelStack->setCurrentWidget(ui_.baseButtonsPage);
	ui_.moreButtonsPanelStack->setCurrentWidget(ui_.baseMoreButtonsPage);
}

QString DetailsWidget::createDetailsTitle(int id, const std::string & name)
{
	return QString(name.c_str()) + QString(", ID ") + QString::number(id);
}

void DetailsWidget::setItemRowAsSelected(SimpleItem & item) {
	selectedFortress_ = item;

	ui_.itemsListView->clearSelection();

	for (int i = 0; i < ui_.itemsListView->rowCount(); ++i) {
		SimpleItem * gameItem = findItemRow(i);

		QTableWidgetItem * tableItem = ui_.itemsListView->item(i, 0);

		if (tableItem == NULL) {
			continue;
		}

		if (gameItem != NULL) {
			if (gameItem->id == item.id) {
				tableItem->setSelected(true);
			}
			else {
				tableItem->setSelected(false);
			}
		}
		else {
			tableItem->setSelected(false);
		}
	}
}

void DetailsWidget::hideDetailsPanel()
{
	ui_.detailsPanel->setVisible(false);
}

void DetailsWidget::showDetailsPanel()
{
	ui_.detailsPanel->setVisible(true);
}

void DetailsWidget::hideItemsPanel()
{
	ui_.itemsPanel->setVisible(false);
}

void DetailsWidget::showItemsPanel()
{
	ui_.itemsPanel->setVisible(true);
}

void DetailsWidget::showShipSectionSlot(EShipSectionState data)
{
	emit changeShipSectionSignal(selectedFortress_, data);
}

void DetailsWidget::showBaseSectionSlot(EBaseSectionState data)
{
	emit changeBaseSectionSignal(selectedFortress_, data);
}

void DetailsWidget::showNavigation() {
	showPageWidget(ui_.navigationPage, ui_.navigationWidget);
	ui_.navigationWidget->setContextShip(selectedFortress_);
}

void DetailsWidget::showHangar() {
	showPageWidget(ui_.hangarPage, ui_.hangarWidget);
}

void DetailsWidget::showDevices() {
	showPageWidget(ui_.devicesPage, ui_.devicesWidget);
}

void DetailsWidget::showWeapons() {
	showPageWidget(ui_.weaponsPage, ui_.weaponsWidget);
}

void DetailsWidget::showShields() {
	showPageWidget(ui_.shieldsPage, ui_.shieldsWidget);
}

void DetailsWidget::showSensors() {
	showPageWidget(ui_.sensorsPage, ui_.sensorsWidget);
}

void DetailsWidget::showCloaking() {
	showPageWidget(ui_.cloakingPage, ui_.cloakingWidget);
}

void DetailsWidget::showCentralInfo() {
	showPageWidget(ui_.centralInfoPage, ui_.centralInfoWidget);
}

void DetailsWidget::showSubspaceDrive() {
	showPageWidget(ui_.subspaceDrivePage, ui_.subspaceDriveWidget);
}

void DetailsWidget::showMainframe() {
	showPageWidget(ui_.mainframePage, ui_.mainframeWidget);
}

void DetailsWidget::showQuarrying() {
	showPageWidget(ui_.miningPage, ui_.miningWidget);
}

void DetailsWidget::showCrew() {
	showPageWidget(ui_.crewPage, ui_.crewWidget);
}

void DetailsWidget::showImpulsDrive() {
	showPageWidget(ui_.impulsDrivePage, ui_.impulsDriveWidget);
}

void DetailsWidget::showAccommodations() {
	showPageWidget(ui_.accommodationsPage, ui_.accommodationsWidget);
}

void DetailsWidget::showRender() {
	showPageWidget(ui_.modelViewPage, NULL);
}

void DetailsWidget::showOtherEquipment() {
	showPageWidget(ui_.otherEquipmentPage, ui_.otherEquipmentWidget);
}

void DetailsWidget::showFactories() {
	showPageWidget(ui_.factoriesPage, ui_.factoriesWidget);
}

void DetailsWidget::showWarehouses() {
	showPageWidget(ui_.warehousesPage, ui_.warehousesWidget, false);
}

void DetailsWidget::showAndroids() {
	showPageWidget(ui_.androidsPage, ui_.androidsWidget, false);
}

void DetailsWidget::showPageWidget(QWidget * widgetPage, NotifyWidget * widget, bool resizeParentToFit) {
	showDetailsPanel();

	this->currentWidget_ = widget;

	ui_.paramsPanelStack->setCurrentWidget(widgetPage);

	if (widget != NULL && resizeParentToFit) {
		ui_.paramsPanelStack->resize(ui_.paramsPanelStack->width(), widget->height() + widget->y() + 6);
	}
	else {
		ui_.paramsPanelStack->resize(ui_.paramsPanelStack->width(), 650);
	}

	if (ui_.paramsPanelStack->height() > 650) {
		ui_.paramsPanelStack->resize(ui_.paramsPanelStack->width(), 650);
	}
}

SimpleItem * DetailsWidget::findItemRow(int row) {
	QTableWidgetItem * item = ui_.itemsListView->item(row, 0);

	if (item == NULL) {
		return NULL;
	}

	int id = item->data(Qt::UserRole).toInt();

    if (rows_.find(id) != rows_.end()) {
        return &rows_[id];
    }
    else {
        return NULL;
    }
}

void DetailsWidget::notifyUpdate() {
	if (currentWidget_ != NULL) {
		currentWidget_->notifyUpdate();
	}
}

void DetailsWidget::clearState() {
	rows_.clear();

	int rowCount = ui_.itemsListView->rowCount();
	
	for (int i = rowCount; i >= 0; --i) {
		ui_.itemsListView->removeRow(i);
	}
}