#include <assert.h>
#include <climits>
#include <QMessageBox>

#include "navigationwidget.h"
#include "ui_navigationwidget.h"
#include "softProj\clientServer\structs.h"
#include "protocol.h"
#include "LocationTable.h"
#include "locationTableDistanceItem.h"
#include "softProj\settings.h"
#include "unitConvertor.h"
#include <sstream>
#include "../../streams/ErrorStream.h"
extern KODIAK_DEBUG_STREAM KODIAK_DEBUG_COUT;

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

    client_ = 0;

	navigationDialog_ = 0;

	selectedSunId_ = 0;
	targetFortressId_ = 0;
	targetSpaceObjectId_ = 0;

    ownedShipsTable_ = new OwnedShipsTable(this);
    ownedShipsTable_->setTable(ui_.ownedShipsTable);
    ownedShipsTable_->setTitleLabel(ui_.ownedShipsTitleLabel);
    ownedShipsTable_->setSearchButton(ui_.ownedShipsSearchButton);
    ownedShipsTable_->setShowAllButton(ui_.ownedShipsAllButton);
    ownedShipsTable_->setSearchEdit(ui_.ownedShipsSearchEdit);
    ownedShipsTable_->connectSignals();	

    enemyShipsTable_ = new EnemyShipsTable(this);
    enemyShipsTable_->setTable(ui_.enemyShipsTable);
    enemyShipsTable_->setTitleLabel(ui_.enemyShipsTitleLabel);
    enemyShipsTable_->setSearchButton(ui_.enemyShipsSearchButton);
    enemyShipsTable_->setShowAllButton(ui_.enemyShipsAllButton);
    enemyShipsTable_->setSearchEdit(ui_.enemyShipsSearchEdit);
    enemyShipsTable_->connectSignals();

	distantEnemyShipsTable_ = new DistantEnemyShipsTable(this);
    distantEnemyShipsTable_->setTable(ui_.distantEnemyShipsTable);
    distantEnemyShipsTable_->setTitleLabel(ui_.distantEnemyShipsTitleLabel);
    distantEnemyShipsTable_->connectSignals();

    systemsTable_ = new SystemsTable(this);
    systemsTable_->setTable(ui_.solarSystemsTable);
    systemsTable_->setTitleLabel(ui_.solarSystemsTitleLabel);
    systemsTable_->setSearchButton(ui_.solarSystemsSearchButton);
    systemsTable_->setShowAllButton(ui_.solarSystemsAllButton);
    systemsTable_->setSearchEdit(ui_.solarSystemsSearchEdit);
    systemsTable_->connectSignals();

    planetsTable_ = new PlanetsTable(this);
    planetsTable_->setTable(ui_.planetsTable);
    planetsTable_->setTitleLabel(ui_.planetsTitleLabel);
    planetsTable_->setSearchButton(ui_.planetsSearchButton);
    planetsTable_->setShowAllButton(ui_.planetsAllButton);
    planetsTable_->setSearchEdit(ui_.planetsSearchEdit);
    planetsTable_->connectSignals();

	ui_.ownedShipsTable->horizontalHeader()->setResizeMode(QHeaderView::Fixed);
	ui_.enemyShipsTable->horizontalHeader()->setResizeMode(QHeaderView::Fixed);
	ui_.solarSystemsTable->horizontalHeader()->setResizeMode(QHeaderView::Fixed);
	ui_.planetsTable->horizontalHeader()->setResizeMode(QHeaderView::Fixed);

	coordXValidator_ = new QRegExpValidator(QRegExp("-?[0-9]*"), ui_.coordXEdit);
	coordYValidator_ = new QRegExpValidator(QRegExp("-?[0-9]*"), ui_.coordYEdit);

    ui_.coordXEdit->setValidator(coordXValidator_);
    ui_.coordYEdit->setValidator(coordYValidator_);

    bool isConnected = connect(ui_.customSubmitStandardButton, SIGNAL(clicked(bool)), this, SLOT(submitCustomClickedSlot()));
    assert(isConnected);

    isConnected = isConnected && connect(ui_.orbitButton, SIGNAL(clicked(bool)), this, SLOT(orbitButtonClickedSlot()));
    assert(isConnected);

    isConnected = isConnected && connect(ui_.stopButton, SIGNAL(clicked(bool)), this, SLOT(stopButtonClickedSlot()));
    assert(isConnected);

	isConnected = isConnected && connect(ui_.breakWarpButton, SIGNAL(clicked(bool)), this, SLOT(breakWarpButtonClickedSlot()));
    assert(isConnected);

	isConnected = isConnected && connect(ui_.dockButton, SIGNAL(clicked(bool)), this, SLOT(unboundSlot()));
    assert(isConnected);	

	selectedItem_ = NULL;

	isInWarp_ = false;
	ui_.stackedWidget->setCurrentWidget(ui_.navigationPage);
}

NavigationWidget::~NavigationWidget()
{
    delete ownedShipsTable_;
    delete enemyShipsTable_;
    delete planetsTable_;
    delete systemsTable_;
	delete coordXValidator_;
	delete coordYValidator_;
}

void NavigationWidget::submitCustomClickedSlot() {

	if (ui_.coordXEdit->text().isEmpty() || ui_.coordYEdit->text().isEmpty()) {
        QMessageBox msgBox;
        msgBox.setWindowTitle(QString::fromUtf16(L"Špatné souřadnice"));
        msgBox.setText(QString::fromUtf16(L"Souřadnice nesmí být prázdné"));
        msgBox.setStandardButtons(QMessageBox::Ok);
        msgBox.setIcon(QMessageBox::Warning);
        msgBox.exec();
		return;
    }

	positionx = ui_.coordXEdit->text().toDouble();
    positiony = ui_.coordYEdit->text().toDouble();

	selectedItem_ = NULL;
	navigateTo_ = NAVIGATION_CUSTOM;

	showNavigationDialog(true);
}

LocationTable::LocationTable(NavigationWidget * parent) : QWidget(parent) {
    titleLabel_ = 0;
    tableWidget_ = 0;
    searchButton_ = 0;
	showAllButton_ = 0;
    searchEdit_ = 0;

	currentTargetId_ = 0;
	currentActualId_ = 0;
	currentSystemId_ = 0;

	currentFilter_ = NULL;

    navigationWidget_ = parent;	
}

void LocationTable::setTitleText(const std::wstring & text) {
	if (titleLabel_ != NULL) {
		titleLabel_->setText(QString::fromUtf16(text.c_str()));
	}
}

void PlanetsTable::setSunText(const std::string & text) {
	if (titleLabel_ != NULL) {
		titleLabel_->setText(QString::fromUtf16(L"Planety slunce ") + QString::fromUtf8(text.c_str()));
	}
}

void LocationTable::setTitleLabel(QLabel * titleLabel) {
    this->titleLabel_ = titleLabel;
}

void LocationTable::setTable(QTableWidget * tableWidget) {
    this->tableWidget_ = tableWidget;

	tableWidget_->setItemDelegate(new BackgroundDelegate(this));
}

void LocationTable::setSearchButton(QPushButton * searchButton) {
    this->searchButton_ = searchButton;
}

void LocationTable::setShowAllButton(QPushButton * showAllButton) {
    this->showAllButton_ = showAllButton;
}

void LocationTable::setSearchEdit(QLineEdit * searchEdit) {
    this->searchEdit_ = searchEdit;
}

void LocationTable::connectSignals() {
    bool isConnected = true;
	
	
	if (searchButton_ != NULL) {
		isConnected = isConnected && connect(searchButton_, SIGNAL(clicked()), this, SLOT(searchClickedSlot()));
		assert(isConnected);
	}

	if (showAllButton_ != NULL) {
		isConnected = isConnected && connect(showAllButton_, SIGNAL(clicked()), this, SLOT(showAllClickedSlot()));
		assert(isConnected);
	}
	
	isConnected = isConnected && connect(tableWidget_, SIGNAL(cellDoubleClicked(int,int)), this, SLOT(cellDoubleClickedSlot(int, int)));
    assert(isConnected);

	isConnected = isConnected && connect(tableWidget_, SIGNAL(cellClicked(int,int)), this, SLOT(cellClickedSlot(int, int)));
	assert(isConnected);
    
}

void LocationTable::showAllClickedSlot() {
	clearFilterString();

	std::map<id_t, GameItemRow *> allItems;

	for (std::map<id_t, GameItemRow *>::const_iterator it = rows_.begin(); it != rows_.end(); ++it) {
		allItems.insert(std::make_pair(it->first, it->second));
    }

	updateItems(allItems);
}

bool LocationTable::matchesFilterIfAny(const QString & name) {
	if (currentFilter_ == NULL) {
		return true;
	}
	else {
		return currentFilter_->exactMatch(name);
	}
}

void LocationTable::searchClickedSlot() {
	QString searchedString = searchEdit_->text();	

	if (currentFilter_ != NULL) {
		delete currentFilter_;
	} 

    currentFilter_ = new QRegExp(".*" + searchedString + ".*", Qt::CaseInsensitive);

    std::map<id_t, GameItemRow *> matchedItems;

	for (std::map<id_t, GameItemRow *>::const_iterator it = rows_.begin(); it != rows_.end(); ++it) {
		if (matchesFilterIfAny(it->second->getName())) {
			matchedItems.insert(std::make_pair(it->first, it->second));
        }
    }

	updateItems(matchedItems);
}

void LocationTable::insertItem(GameItemRow * item) {
    rows_.insert(std::make_pair(item->getId(), item));

	if (matchesFilterIfAny(item->getName())) {
		insertItemIntoTable(item);
	}
}

int LocationTable::insertItemIntoTable(GameItemRow * item) {
	tableWidget_->setSortingEnabled(false);

    const int targetRow = tableWidget_->rowCount();
    tableWidget_->insertRow(targetRow);

	QString name;
	if (item->getType() == FORTRESS_TYPE_BASE) {
		name = item->getName() + " (Z)";
	}
	else {
		name = item->getName();
	}

	rows_.insert(std::make_pair(item->getId(), item));

    QTableWidgetItem * tableItem = new QTableWidgetItem(name);
	tableItem->setData(Qt::UserRole, QVariant::fromValue(item->getId()));	
    tableWidget_->setItem(targetRow, 0, tableItem);

	QTableWidgetItem * distanceTableItem = new LocationTableDistanceItem(
		QString::fromUtf16(formatDistance(item->getDistance(), 2).c_str()), item->getDistance());

	tableWidget_->setItem(targetRow, 1, distanceTableItem);	

	if (item->getId() == currentActualId_) {
		tableItem->setBackgroundColor(Constants::ACTUAL_ROW_COLOR);
		distanceTableItem->setBackgroundColor(Constants::ACTUAL_ROW_COLOR);		
	}
	else if (item->getId() == currentTargetId_) {
		tableItem->setBackgroundColor(Constants::TARGET_ROW_COLOR);
		distanceTableItem->setBackgroundColor(Constants::TARGET_ROW_COLOR);
	}
	else if (item->getId() == currentSystemId_) {
		tableItem->setBackgroundColor(Constants::SYSTEM_ROW_COLOR);
		distanceTableItem->setBackgroundColor(Constants::SYSTEM_ROW_COLOR);
	}

	QString toolTip = QString::fromUtf16(formatDistance(item->getDistance(), 100).c_str());
	tableItem->setToolTip(toolTip);
	distanceTableItem->setToolTip(toolTip);

	tableWidget_->setSortingEnabled(true);

    return targetRow;
}

int OwnedShipsTable::insertItemIntoTable(GameItemRow * item) {
	tableWidget_->setSortingEnabled(false);

    const int targetRow = tableWidget_->rowCount();
    tableWidget_->insertRow(targetRow);

    QTableWidgetItem * tableItem = new QTableWidgetItem(item->getName());
	tableItem->setData(Qt::UserRole, QVariant::fromValue(item->getId()));
    rows_.insert(std::make_pair(item->getId(), item));

    tableWidget_->setItem(targetRow, 0, tableItem);

	QTableWidgetItem * distanceTableItem = new LocationTableDistanceItem(
		QString::fromUtf16(formatDistance(item->getDistance(), 2).c_str()), item->getDistance());

	tableWidget_->setItem(targetRow, 1, distanceTableItem);	

	if (item->getId() == currentActualId_) {
		tableItem->setBackgroundColor(Constants::ACTUAL_ROW_COLOR);
		distanceTableItem->setBackgroundColor(Constants::ACTUAL_ROW_COLOR);		
	}
	else if (item->getId() == currentTargetId_) {
		tableItem->setBackgroundColor(Constants::TARGET_ROW_COLOR);
		distanceTableItem->setBackgroundColor(Constants::TARGET_ROW_COLOR);
	}
	else if (item->getId() == currentSystemId_) {
		tableItem->setBackgroundColor(Constants::SYSTEM_ROW_COLOR);
		distanceTableItem->setBackgroundColor(Constants::SYSTEM_ROW_COLOR);
	}

	if (dynamic_cast<NavigationBaseObjectRow *>(item) != NULL) {
		NavigationBaseObjectRow * baseRow = dynamic_cast<NavigationBaseObjectRow *>(item);

		if (baseRow->canShipDockDown() == DR_OK) {	
			distanceTableItem->setText(QString::fromUtf16(L"Můžeš přistát"));
		}
	}

	QString toolTip = QString::fromUtf16(formatDistance(item->getDistance(), 100).c_str());
	tableItem->setToolTip(toolTip);
	distanceTableItem->setToolTip(toolTip);

	tableWidget_->setSortingEnabled(true);

    return targetRow;
}

int EnemyShipsTable::insertItemIntoTable(GameItemRow * item) {
	tableWidget_->setSortingEnabled(false);

    const int targetRow = tableWidget_->rowCount();
    tableWidget_->insertRow(targetRow);

    QTableWidgetItem * tableItem = new QTableWidgetItem(item->getName());
	tableItem->setData(Qt::UserRole, QVariant::fromValue(item->getId()));
    rows_.insert(std::make_pair(item->getId(), item));

    tableWidget_->setItem(targetRow, 0, tableItem);

	QTableWidgetItem * distanceTableItem = new LocationTableDistanceItem(
		QString::fromUtf16(formatDistance(item->getDistance(), 2).c_str()), item->getDistance());

	tableWidget_->setItem(targetRow, 1, distanceTableItem);	

	QString realmName;
	if (dynamic_cast<HighResolutionRow *>(item) != NULL) {
		HighResolutionRow * highResolutionRow = dynamic_cast<HighResolutionRow *>(item);
		realmName = QString::fromUtf8(highResolutionRow->getRealmName().c_str());
	}
	else {
		realmName = QString::fromUtf16(L"Hráč není známý");
	}

	QTableWidgetItem * realmTableItem = new QTableWidgetItem(realmName);
	tableWidget_->setItem(targetRow, 2, realmTableItem);	

	if (item->getId() == currentActualId_) {
		tableItem->setBackgroundColor(Constants::ACTUAL_ROW_COLOR);
		distanceTableItem->setBackgroundColor(Constants::ACTUAL_ROW_COLOR);	
		realmTableItem->setBackgroundColor(Constants::ACTUAL_ROW_COLOR);
	}
	else if (item->getId() == currentTargetId_) {
		tableItem->setBackgroundColor(Constants::TARGET_ROW_COLOR);
		distanceTableItem->setBackgroundColor(Constants::TARGET_ROW_COLOR);
		realmTableItem->setBackgroundColor(Constants::TARGET_ROW_COLOR);
	}
	else if (item->getId() == currentSystemId_) {
		tableItem->setBackgroundColor(Constants::SYSTEM_ROW_COLOR);
		distanceTableItem->setBackgroundColor(Constants::SYSTEM_ROW_COLOR);
		realmTableItem->setBackgroundColor(Constants::SYSTEM_ROW_COLOR);
	}

	QString toolTip = QString::fromUtf16(formatDistance(item->getDistance(), 100).c_str());
	tableItem->setToolTip(toolTip);
	distanceTableItem->setToolTip(toolTip);	
	realmTableItem->setToolTip(toolTip);	

	tableWidget_->setSortingEnabled(true);

    return targetRow;
}

int DistantEnemyShipsTable::insertItemIntoTable(GameItemRow * item) {
	tableWidget_->setSortingEnabled(false);

    const int targetRow = tableWidget_->rowCount();
    tableWidget_->insertRow(targetRow);

	QTableWidgetItem * distanceTableItem = new LocationTableDistanceItem(
		QString::fromUtf16(formatDistance(item->getDistance(), 2).c_str()), item->getDistance());

	distanceTableItem->setData(Qt::UserRole, QVariant::fromValue(item->getId()));
	tableWidget_->setItem(targetRow, 0, distanceTableItem);	

	if (item->getId() == currentActualId_) {
		distanceTableItem->setBackgroundColor(Constants::ACTUAL_ROW_COLOR);		
	}
	else if (item->getId() == currentTargetId_) {
		distanceTableItem->setBackgroundColor(Constants::TARGET_ROW_COLOR);
	}
	else if (item->getId() == currentSystemId_) {
		distanceTableItem->setBackgroundColor(Constants::SYSTEM_ROW_COLOR);
	}

	distanceTableItem->setTextAlignment(Qt::AlignCenter);

	QString toolTip = QString::fromUtf16(formatDistance(item->getDistance(), 100).c_str());
	distanceTableItem->setToolTip(toolTip);	

	tableWidget_->setSortingEnabled(true);

    return targetRow;
}

int SystemsTable::insertItemIntoTable(GameItemRow * item) {
    return LocationTable::insertItemIntoTable(item);
}

int PlanetsTable::insertItemIntoTable(GameItemRow * item) {
	return LocationTable::insertItemIntoTable(item);
}

void LocationTable::clearFilteredContentKeepFilter() {
    for (int i = tableWidget_->rowCount() - 1; i >= 0; --i) {
        tableWidget_->removeRow(i);
    }
}

void LocationTable::clearAllContentKeepFilter() {
    clearFilteredContentKeepFilter();
	rows_.clear();
}

void LocationTable::clearFilterString() {
	if (currentFilter_ != NULL) {
		delete currentFilter_;
		currentFilter_ = NULL;
	}

	searchEdit_->clear();
}

void NavigationWidget::setContextShip(const SimpleItem & item) {
    this->contextShip_ = item;

	setActualIdToFortress(item.id);
}

void NavigationWidget::clearContent() {
    clearAllPlanets();
    clearAllSystems();
    clearAllOwnedShips();
    clearAllEnemyShips();
}

void NavigationWidget::clearAllPlanets() {
    planetsTable_->clearAllContentKeepFilter();
	planetsTable_->setSunText("-");
}

void NavigationWidget::clearAllSystems() {
    systemsTable_->clearAllContentKeepFilter();
}

void NavigationWidget::clearAllOwnedShips() {
    ownedShipsTable_->clearAllContentKeepFilter();
}

void NavigationWidget::clearAllEnemyShips() {
    enemyShipsTable_->clearAllContentKeepFilter();
}

void NavigationWidget::clearAllDistantEnemyShips() {
	distantEnemyShipsTable_->clearAllContentKeepFilter();
}


void NavigationWidget::clearFilteredPlanets() {
    planetsTable_->clearFilteredContentKeepFilter();
}

void NavigationWidget::clearFilteredSystems() {
     systemsTable_->clearFilteredContentKeepFilter();
}

void NavigationWidget::clearFilteredOwnedShips() {
     ownedShipsTable_->clearFilteredContentKeepFilter();
}

void NavigationWidget::clearFilteredEnemyShips() {
     enemyShipsTable_->clearFilteredContentKeepFilter();
}

void LocationTable::cellDoubleClickedSlot(int row, int col) {
    GameItemRow * itemRow = findItemRow(row, col);

	if (itemRow == NULL) {
		KODIAK_DEBUG_COUT << "Item widget is NULL in void LocationTable::cellDoubleClickedSlot(int row, int col)";
		return;
	}

    cellDoubleClicked(itemRow);
 }

void SystemsTable::cellDoubleClicked(GameItemRow *destination) {
    navigationWidget_->systemDoubleClicked(destination);
}

void PlanetsTable::cellDoubleClicked(GameItemRow *destination) {
    navigationWidget_->planetDoubleClicked(destination);
}

void EnemyShipsTable::cellDoubleClicked(GameItemRow *destination) {
    navigationWidget_->enemyShipDoubleClicked(destination);
}

void OwnedShipsTable::cellDoubleClicked(GameItemRow *destination) {
    navigationWidget_->ownedShipDoubleClicked(destination);
}

void DistantEnemyShipsTable::cellDoubleClicked(GameItemRow *destination) {
	navigationWidget_->distantEnemyShipDoubleClicked(destination);
}

void NavigationWidget::planetDoubleClicked(GameItemRow * item) {
	selectedItem_ = item;
	navigateTo_ = NAVIGATION_PLANET;

	if (planets_.find(item->getId()) != planets_.end()) {
		showNavigationDialog(planets_[item->getId()]);
	}
	else {
		showNavigationDialog(true);
	}
}

void NavigationWidget::systemDoubleClicked(GameItemRow * item) {
	selectedItem_ = item;
	navigateTo_ = NAVIGATION_SYSTEM;
	showNavigationDialog(true);
}

void NavigationWidget::systemClicked(GameItemRow * item) {
	emit navigationPlanetsInSystemSignal(item->getId());
}

void NavigationWidget::enemyShipDoubleClicked(GameItemRow * item) {
	selectedItem_ = item;
	navigateTo_ = NAVIGATION_SHIP;	
	showNavigationDialog(false);   
}

void NavigationWidget::distantEnemyShipDoubleClicked(GameItemRow * item) {
	selectedItem_ = item;
	navigateTo_ = NAVIGATION_SHIP;
	showNavigationDialog(false);
}

void NavigationWidget::ownedShipDoubleClicked(GameItemRow * item) {
	selectedItem_ = item;

	if (item->getType() == GAME_ITEM_SHIP) {
		navigateTo_ = NAVIGATION_SHIP;
	}
	else if (item->getType() == GAME_ITEM_BASE) {
		navigateTo_ = NAVIGATION_BASE;
	}

	if (dynamic_cast<NavigationBaseObjectRow *>(item) != NULL) {
		NavigationBaseObjectRow * baseRow = (NavigationBaseObjectRow *) item;
		showNavigationDialog(baseRow->canShipDockDown());
	}
	else {	
		showNavigationDialog(false);
	}
}

OwnedShipsTable::OwnedShipsTable(NavigationWidget *parent) : LocationTable(parent) {
}

DistantEnemyShipsTable::DistantEnemyShipsTable(NavigationWidget *parent) : LocationTable(parent) {
}

EnemyShipsTable::EnemyShipsTable(NavigationWidget *parent) : LocationTable(parent) {
}

PlanetsTable::PlanetsTable(NavigationWidget *parent) : LocationTable(parent) {
}

SystemsTable::SystemsTable(NavigationWidget *parent) : LocationTable(parent) {
}

void NavigationWidget::stopButtonClickedSlot() {
	emit navigationStopSignal(contextShip_.id);
}

void NavigationWidget::breakWarpButtonClickedSlot() {
	emit navigationBreakWarpSignal(contextShip_.id);
}

void NavigationWidget::orbitButtonClickedSlot() {
	emit navigationOrbitSignal(contextShip_.id);
}

void NavigationWidget::setPlanets(const NavigationPlanetsInStarAreaDetails & details) {
	planets_.clear();

	planetsTable_->setSunText(details.sunName);
	selectedSunId_ = details.areaId;

	updateSpaceObjectTargetID(targetSpaceObjectId_);

	std::map<id_t, GameItemRow *> newItems;

	for (std::vector<NavigationPlanetDetails>::const_iterator itemIt = details.planets.begin(); itemIt != details.planets.end(); ++itemIt) {
		NavigationObject planet;
		planet.distance = itemIt->shipDistance;
		planet.id = itemIt->id;
		planet.name = itemIt->name;

		GameItemRow * row = new NavigationObjectRow(planet, GAME_ITEM_PLANET);
		newItems.insert(std::make_pair(row->getId(), row));

		planets_.insert(std::make_pair(itemIt->id, *itemIt));
	}

	planetsTable_->updateItems(newItems);
}

void NavigationWidget::setSystems(std::vector<NavigationObject> & items) {
	id_t idOfActualSystem = 0;
	dt_distance_t closestDistance = ULLONG_MAX;

	// If selected system from previous table set is located in new set, because if it is,
	// we want to update planets for it, otherwise update for home system
	bool selectedSunPersists_ = false;

	for (std::vector<NavigationObject>::const_iterator it = items.begin(); it != items.end(); ++it) {
		if (it->distance <= closestDistance) {
			closestDistance = it->distance;
			idOfActualSystem = it->id;
		}

		if (it->id == selectedSunId_) {
			selectedSunPersists_ = true;
		}
	}

	setActualIdToSpaceObject(idOfActualSystem);
	updateSpaceObjectTargetID(targetSpaceObjectId_);

	std::map<id_t, GameItemRow *> newItems;

	for (std::vector<NavigationObject>::iterator itemIt = items.begin(); itemIt != items.end(); ++itemIt) {
		GameItemRow * row = new NavigationObjectRow(*itemIt, GAME_ITEM_SYSTEM);
		newItems.insert(std::make_pair(row->getId(), row));
	}

	systemsTable_->updateItems(newItems);

	if (selectedSunPersists_) {
		emit navigationPlanetsInSystemSignal(selectedSunId_);
	}
	else {
		emit navigationPlanetsInSystemSignal(idOfActualSystem);
	}
}

void NavigationWidget::setOwnedFortresses(std::vector<NavigationObject> & ships, std::vector<NavigationBaseObject> & bases) {
	std::map<id_t, GameItemRow *> newItems;

	updateFortressTargetID(targetFortressId_);

	for (std::vector<NavigationObject>::iterator itemIt = ships.begin(); itemIt != ships.end(); ++itemIt) {
		GameItemRow * row = new NavigationObjectRow(*itemIt, GAME_ITEM_SHIP);
		newItems.insert(std::make_pair(row->getId(), row));
	}

	for (std::vector<NavigationBaseObject>::iterator itemIt = bases.begin(); itemIt != bases.end(); ++itemIt) {
		GameItemRow * row = new NavigationBaseObjectRow(*itemIt, GAME_ITEM_BASE);
		newItems.insert(std::make_pair(row->getId(), row));
	}

	ownedShipsTable_->updateItems(newItems);
}

void NavigationWidget::setEnemyShips(std::vector<NavigationHighResolutionDetails> & items) {
	std::map<id_t, GameItemRow *> newItems;

	updateFortressTargetID(targetFortressId_);

	for (std::vector<NavigationHighResolutionDetails>::iterator itemIt = items.begin(); itemIt != items.end(); ++itemIt) {
		GameItemRow * row = new HighResolutionRow(*itemIt, GAME_ITEM_SHIP);
		newItems.insert(std::make_pair(row->getId(), row));
	}

	enemyShipsTable_->updateItems(newItems);
}

void NavigationWidget::setDistantEnemyShip(std::vector<NavigationLongRangeDetails> & items) {
	std::map<id_t, GameItemRow *> newItems;

	updateFortressTargetID(targetFortressId_);

	for (std::vector<NavigationLongRangeDetails>::iterator itemIt = items.begin(); itemIt != items.end(); ++itemIt) {
		GameItemRow * row = new LongRangeRow(*itemIt, GAME_ITEM_SHIP);
		newItems.insert(std::make_pair(row->getId(), row));
	}

	distantEnemyShipsTable_->updateItems(newItems);
}

GameItemRow * LocationTable::findItemRow(int row, int) {
	QTableWidgetItem * itemRow = tableWidget_->item(row, 0);

	if (itemRow == NULL) {
		KODIAK_DEBUG_COUT << "Item widget is NULL in GameItemRow * LocationTable::findItemRow(int row, int)";
		return 0;
	}

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

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

void LocationTable::cellClickedSlot(int row, int col) {
    GameItemRow * itemRow = findItemRow(row, col);

	if (itemRow == NULL) {
		KODIAK_DEBUG_COUT << "Item widget is NULL in void LocationTable::cellClickedSlot(int row, int col)";
		return;
	}

    cellClicked(itemRow);    
}

void LocationTable::cellDoubleClicked(GameItemRow *) {
}

void LocationTable::cellClicked(GameItemRow *) {
}

void SystemsTable::cellClicked(GameItemRow * destination) {
    navigationWidget_->systemClicked(destination);
}

void NavigationWidget::setShipJourneyDetails(ShipJourneyDetailsFAIL & details) {
}

void NavigationWidget::updateWarpInformation(const std::string & state) {
	if (state == REQUEST_SHIP_JOURNEY_ANSWER_SMS_WARP) {
		isInWarp_ = true;
		ui_.stackedWidget->setCurrentWidget(ui_.warpPage);
	}
	else {
		isInWarp_ = false;
		ui_.stackedWidget->setCurrentWidget(ui_.navigationPage);
	}
}

void NavigationWidget::setShipJourneyDetails(ShipJourneyDetailsSTANDARD & details) {

	updateWarpInformation(details.state);

	clearJourneyDetails();
	setActualPosition(details.positionX, details.positionY);
	setTargetAction(details.target);
	setCurrentAction(details.state);
	setSpeed(details.speedInMetersPerSecond);
	setAcceleration(details.accelerationInMetersPerSquaredSecond);
	setMovementState(details.state);
	setDockingResult(details.isDockedInBase, details.docking);

	clearTargetIdToAll();
}

void NavigationWidget::setShipJourneyDetails(ShipJourneyDetailsPURSUIT & details) {

	updateWarpInformation(details.state);

	clearJourneyDetails();
	setActualPosition(details.positionX, details.positionY);
	setEstimationTime(details.estimationTimeInSeconds);
	setEstimationDistance(details.estimationDistanceInKilometers);
	setTargetAction(details.target);
	setCurrentAction(details.state);
	setSpeed(details.speedInMetersPerSecond);
	setAcceleration(details.accelerationInMetersPerSquaredSecond);
	setMovementState(details.state);
	setDockingResult(false, details.docking);

	setTargetIdToFortress(details.targetShip);
}

void NavigationWidget::setShipJourneyDetails(ShipJourneyDetailsMOVE_TO & details) {

	updateWarpInformation(details.state);

	clearJourneyDetails();
	setActualPosition(details.positionX, details.positionY);
	setTargetPosition(details.targetX, details.targetY);
	setEstimationTime(details.estimationTimeInSeconds);
	setEstimationDistance(details.estimationDistanceInKilometers);
	setTargetAction(details.target);
	setCurrentAction(details.state);
	setSpeed(details.speedInMetersPerSecond);
	setAcceleration(details.accelerationInMetersPerSquaredSecond);
	setMovementState(details.state);
	setDockingResult(false, details.docking);

	clearTargetIdToAll();
}

void NavigationWidget::setShipJourneyDetails(ShipJourneyDetailsMOVE_TO_SPACE_OBJECT & details) {
	
	updateWarpInformation(details.state);

	clearJourneyDetails();
	setActualPosition(details.positionX, details.positionY);
	setTargetPosition(details.targetSpaceObjectName);
	setTargetAction(details.target);
	setCurrentAction(details.state);
	setEstimationTime(details.estimationTimeInSeconds);
	setEstimationDistance(details.estimationDistanceInKilometers);
	setSpeed(details.speedInMetersPerSecond);
	setAcceleration(details.accelerationInMetersPerSquaredSecond);	
	setMovementState(details.state);
	setDockingResult(false, details.docking);

	setTargetIdToSpaceObject(details.targetSpaceObjectId);
}

void NavigationWidget::setActualPosition(position_t positionX, position_t positionY) {
	long long positionXLongLong = positionX;
	long long positionYLongLong = positionY;

	if (isInWarp_) {
		ui_.actualXValueWarp->setText(Settings::instance().formatNumber(positionXLongLong));
		ui_.actualYValueWarp->setText(Settings::instance().formatNumber(positionYLongLong));
	}
	else {
		ui_.actualXValue->setText(Settings::instance().formatNumber(positionXLongLong));
		ui_.actualYValue->setText(Settings::instance().formatNumber(positionYLongLong));
	}
}

void NavigationWidget::setTargetPosition(const std::string &targetSpaceObjectName) {
	if (isInWarp_) {
		ui_.targetPositionValueWarp->setText(QString::fromUtf8(targetSpaceObjectName.c_str()));
	}
	else {
		ui_.targetPositionValue->setText(QString::fromUtf8(targetSpaceObjectName.c_str()));
	}
}

void NavigationWidget::setTargetPosition(position_t positionX, position_t positionY) {
	if (isInWarp_) {
		ui_.targetPositionValueWarp->setText(QString::fromUtf8(createPosition(positionX, positionY).c_str()));
	}
	else {
		ui_.targetPositionValue->setText(QString::fromUtf8(createPosition(positionX, positionY).c_str()));
	}
}

void NavigationWidget::setEstimationTime(unsigned long long estimationTimeInSeconds) {
	if (isInWarp_) {
		ui_.estimateTimeValueWarp->setText(QString::fromUtf16(formatTime(estimationTimeInSeconds).c_str()));
	}
	else {
		ui_.estimateTimeValue->setText(QString::fromUtf16(formatTime(estimationTimeInSeconds).c_str()));
	}
}

void NavigationWidget::setEstimationDistance(unsigned long long estimationDistanceInKilometers) {
	if (isInWarp_) {
		ui_.estimateDistanceValueWarp->setText(QString::fromUtf16(formatDistance(estimationDistanceInKilometers, 4).c_str()));
	}
	else {
		ui_.estimateDistanceValue->setText(QString::fromUtf16(formatDistance(estimationDistanceInKilometers, 4).c_str()));
	}
}

void NavigationWidget::setSpeed(unsigned long long speedInMetersPerSecond) {
	if (isInWarp_) {
		ui_.speedValueWarp->setText(QString::fromUtf16(formatSpeed(speedInMetersPerSecond).c_str()));
	}
	else {
		ui_.speedValue->setText(QString::fromUtf16(formatSpeed(speedInMetersPerSecond).c_str()));
	}
}

void NavigationWidget::setAcceleration(unsigned long long accelerationInMetersPerSquaredSecond) {
	if (isInWarp_) {
		ui_.accelerationValueWarp->setText(QString::fromUtf16(formatAccelerance(accelerationInMetersPerSquaredSecond).c_str()));
	}
	else {
		ui_.accelerationValue->setText(QString::fromUtf16(formatAccelerance(accelerationInMetersPerSquaredSecond).c_str()));
	}
}

void NavigationWidget::clearJourneyDetails() {
	ui_.actualXValue->clear();
	ui_.actualYValue->clear();
	ui_.targetPositionValue->clear();
	ui_.estimateTimeValue->clear();
	ui_.estimateDistanceValue->clear();	
	ui_.targetActionValue->clear();
	ui_.currentActionValue->clear();
	ui_.speedValue->clear();
	ui_.accelerationValue->clear();
}	

std::string NavigationWidget::createPosition(position_t positionX, position_t positionY) {
	std::stringstream ss;
	ss << positionX << ":" << positionY;	
	return ss.str();
}

void NavigationWidget::setNavigationState(NavigationStatus & navigationStatus) {
	setSystems(navigationStatus.discoveredStars);
	setOwnedFortresses(navigationStatus.myShips, navigationStatus.myBases);
	setEnemyShips(navigationStatus.shipsInHighResolution);	
	setDistantEnemyShip(navigationStatus.shipsInLongRange);
}

void NavigationWidget::setCurrentAction(const std::string & state) {
	if (state == REQUEST_SHIP_JOURNEY_ANSWER_SMS_REGULAR) {
		ui_.currentActionValue->setText(QString::fromUtf16(L"Loď letí standardně"));
	}
	else if (state == REQUEST_SHIP_JOURNEY_ANSWER_SMS_STOPPED) {
		ui_.currentActionValue->setText(QString::fromUtf16(L"Loď je zastavená"));
	}
	else if (state == REQUEST_SHIP_JOURNEY_ANSWER_SMS_STOPPED) {
		ui_.currentActionValue->setText(QString::fromUtf16(L"Loď letí podprostorem"));
	}
	else if (state == REQUEST_SHIP_JOURNEY_ANSWER_SMS_STOPPED) {
		ui_.currentActionValue->setText(QString::fromUtf16(L"Loď obíhá planetu"));
	}
}

void NavigationWidget::setTargetAction(const std::string & target) {
	if (target == REQUEST_SHIP_JOURNEY_ANSWER_SMT_MOVE_TO_SPACE_OBJECT) {
		ui_.targetActionValue->setText(QString::fromUtf16(L"Požadavek: Letět k hvězdému objektu"));
	}
	else if (target == REQUEST_SHIP_JOURNEY_ANSWER_SMT_MOVE_TO_POSITION) {
		ui_.targetActionValue->setText(QString::fromUtf16(L"Požadavek: Letět na vlastní souřadnice"));
	}
	else if (target == REQUEST_SHIP_JOURNEY_ANSWER_SMT_ORBIT) {
		ui_.targetActionValue->setText(QString::fromUtf16(L"Požadavek: Obíhat planetu"));
	}
	else if (target == REQUEST_SHIP_JOURNEY_ANSWER_SMT_NONE) {
		ui_.targetActionValue->setText(QString::fromUtf16(L"Požadavek: Nedělat nic"));
	}
	else if (target == REQUEST_SHIP_JOURNEY_ANSWER_SMT_MOVE_TO_SHIP) {
		ui_.targetActionValue->setText(QString::fromUtf16(L"Požadavek: Pronásledovat loď"));
	}
	else if (target == REQUEST_SHIP_JOURNEY_ANSWER_SMT_STOP) {
		ui_.targetActionValue->setText(QString::fromUtf16(L"Požadavek: Zastavit loď"));
	}
}

void NavigationWidget::answerNavigationMoveToSpaceObject() {
}

void NavigationWidget::answerNavigationMoveToSpaceObjectByWarp() {
}

void NavigationWidget::answerNavigationMoveTo() {
}

void NavigationWidget::answerNavigationPursuit() {
}

void NavigationWidget::answerNavigationBreakWarp() {
}

void NavigationWidget::answerNavigationOrbit() {
}

void NavigationWidget::answerNavigationStop() {
}

void NavigationWidget::answerNavigationWarp() {
}

void NavigationWidget::answerNavigationMoveToSpaceObjectFAIL() {
}

void NavigationWidget::answerNavigationMoveToSpaceObjectByWarpFAIL() {
}

void NavigationWidget::answerNavigationMoveToFAIL() {
}

void NavigationWidget::answerNavigationPursuitFAIL() {
}

void NavigationWidget::answerNavigationBreakWarpFAIL() {
}

void NavigationWidget::answerNavigationOrbitFAIL() {
}

void NavigationWidget::answerNavigationStopFAIL() {  
}

void NavigationWidget::answerNavigationWarpFAIL() {
}

void LocationTable::refreshRowsColor() {

	for (int i = 0; i < tableWidget_->rowCount(); ++i ) {
		GameItemRow * itemRow = findItemRow(i, 0);

		if (itemRow == NULL) {
			continue;
		}

		if (itemRow->getId() == currentActualId_)  {
			QTableWidgetItem * tableItemAtCol0 = tableWidget_->item(i, 0);

			if (tableItemAtCol0 != NULL) {
				tableItemAtCol0->setBackgroundColor(Constants::ACTUAL_ROW_COLOR);
			}

			QTableWidgetItem * tableItemAtCol1 = tableWidget_->item(i, 1);

			if (tableItemAtCol1 != NULL) {
				tableItemAtCol1->setBackgroundColor(Constants::ACTUAL_ROW_COLOR);	
			}
		}
		else if (itemRow->getId() == currentTargetId_) {
			QTableWidgetItem * tableItemAtCol0 = tableWidget_->item(i, 0);

			if (tableItemAtCol0 != NULL) {
				tableItemAtCol0->setBackgroundColor(Constants::TARGET_ROW_COLOR);
			}

			QTableWidgetItem * tableItemAtCol1 = tableWidget_->item(i, 1);

			if (tableItemAtCol1 != NULL) {
				tableItemAtCol1->setBackgroundColor(Constants::TARGET_ROW_COLOR);	
			}
		}
		else if (itemRow->getId() == currentSystemId_) {
			QTableWidgetItem * tableItemAtCol0 = tableWidget_->item(i, 0);

			if (tableItemAtCol0 != NULL) {
				tableItemAtCol0->setBackgroundColor(Constants::SYSTEM_ROW_COLOR);
			}

			QTableWidgetItem * tableItemAtCol1 = tableWidget_->item(i, 1);

			if (tableItemAtCol1 != NULL) {
				tableItemAtCol1->setBackgroundColor(Constants::SYSTEM_ROW_COLOR);	
			}
		}
		else {
			QTableWidgetItem * tableItemAtCol0 = tableWidget_->item(i, 0);

			if (tableItemAtCol0 != NULL) {
				tableItemAtCol0->setBackgroundColor(QColor::fromRgb(0, 0, 0, 0));
			}

			QTableWidgetItem * tableItemAtCol1 = tableWidget_->item(i, 1);

			if (tableItemAtCol1 != NULL) {
				tableItemAtCol1->setBackgroundColor(QColor::fromRgb(0, 0, 0, 0));
			}
		}
	}
}

void LocationTable::setActualId(id_t actualId) {
	this->currentActualId_ = actualId;
	refreshRowsColor();
}

void LocationTable::setTargetId(id_t targetId) {
	this->currentTargetId_ = targetId;
	refreshRowsColor();
}

void LocationTable::setSystemId(id_t systemId) {
	this->currentSystemId_ = systemId;
	refreshRowsColor();
}

void NavigationWidget::updateSpaceObjectTargetID(id_t targetId) {
	targetSpaceObjectId_ = targetId;

	// Reset id in systems and planets
	systemsTable_->setTargetId(targetId);
	planetsTable_->setTargetId(targetId);
}

void NavigationWidget::updateFortressTargetID(id_t targetId) {
	enemyShipsTable_->setTargetId(targetId);
	distantEnemyShipsTable_->setTargetId(targetId);	
	ownedShipsTable_->setTargetId(targetId);
}

void NavigationWidget::setTargetIdToSpaceObject(id_t targetId) {
	targetSpaceObjectId_ = targetId;
	targetFortressId_ = 0;

	// Reset id in systems and planets
	systemsTable_->setTargetId(targetId);
	planetsTable_->setTargetId(targetId);

	// Clear id in ships and bases, because only one thing can be a target and it is
	// either system or planet 
	enemyShipsTable_->setTargetId(0);
	distantEnemyShipsTable_->setTargetId(0);	
	ownedShipsTable_->setTargetId(0);
}

void NavigationWidget::setTargetIdToFortress(id_t targetId) {
	targetFortressId_ = targetId;
	targetSpaceObjectId_ = 0;

	// Clear id in systems and planets, because only one thing can be a target and it is
	// either ship or base 
	systemsTable_->setTargetId(0);
	planetsTable_->setTargetId(0);

	// Reset id in ships and bases
	enemyShipsTable_->setTargetId(targetId);
	distantEnemyShipsTable_->setTargetId(targetId);	
	ownedShipsTable_->setTargetId(targetId);
}

void NavigationWidget::clearTargetIdToAll() {
	systemsTable_->setTargetId(0);
	planetsTable_->setTargetId(0);
	enemyShipsTable_->setTargetId(0);
	distantEnemyShipsTable_->setTargetId(0);	
	ownedShipsTable_->setTargetId(0);
}

void NavigationWidget::setActualIdToSpaceObject(id_t targetId) {
	// Reset id in systems
	systemsTable_->setActualId(targetId);

	// Do not reset or clear owned fortress, because it can still be actual
	// Do not reset or clear enemy fortress or planets, because they cannot be ever actual anyway
}

void NavigationWidget::setActualIdToFortress(id_t targetId) {
	ownedShipsTable_->setActualId(targetId);

	// Do not reset or clear systems, because it can still be actual
	// Do not reset or clear enemy fortress or planets, because they cannot be ever actual anyway
}

void NavigationWidget::clearActualIdToAll() {
	systemsTable_->setActualId(0);
	ownedShipsTable_->setActualId(0);

	// Do not reset or clear enemy fortress or planets, because they cannot be ever actual anyway
}

void NavigationWidget::setDockingResult(bool isDockedInBase, DockingResult result) {
	if (result == DR_OK) {
		ui_.dockButton->setEnabled(true);
		ui_.dockLabel->setText(QString::fromUtf16(L"Loď je na základně a může vzlétnout"));
	}
	else {
		ui_.dockButton->setEnabled(false);
		
		if (result == DR_NOT_DOCKING_SHIP) {
			ui_.dockLabel->setText(QString::fromUtf16(L"Loď není na základně"));
		}
		else if (result == DR_NOT_ENOUGH_DEUTERIUM) {
			ui_.dockLabel->setText(QString::fromUtf16(L"Loď je na základně, ale nemá dostatek deuteria na vzlétnutí"));
		}
		else if (result == DR_IMPULS_DRIVE_FAIL) {
			ui_.dockLabel->setText(QString::fromUtf16(L"Loď je na základně, ale nemá motory nebo jsou rozbité"));
		}
	}

	if (isDockedInBase) {
	}
}

void NavigationWidget::setMovementState(const std::string & action) {
	if (action == REQUEST_SHIP_JOURNEY_ANSWER_SMS_REGULAR) {
		changeMovementState(SHIP_MOVEMENT_STATE_REGULAR);
	}
	else if (action == REQUEST_SHIP_JOURNEY_ANSWER_SMS_STOPPED) {
		changeMovementState(SHIP_MOVEMENT_STATE_STOPPED);
	}
	else if (action == REQUEST_SHIP_JOURNEY_ANSWER_SMS_WARP) {
		changeMovementState(SHIP_MOVEMENT_STATE_WARP);
	}
	else if (action == REQUEST_SHIP_JOURNEY_ANSWER_SMS_ORBITING) {
		changeMovementState(SHIP_MOVEMENT_STATE_ORBITING);
	}
}

void NavigationWidget::changeMovementState(EShipMovementState movementState) {
	this->shipMovementState_ = movementState;

	switch (movementState) {
	case SHIP_MOVEMENT_STATE_REGULAR:
		ui_.currentActionValue->setText(QString::fromUtf16(L"Loď letí impulsem"));

		ui_.stopButton->setText(QString::fromUtf16(L"Zastavit loď"));
		ui_.stopButton->setProperty("shipMode", "notwarp");
		ui_.stopButton->setStyleSheet(ui_.stopButton->styleSheet());
		ui_.stopButton->setEnabled(true);

		ui_.orbitButton->setEnabled(true);

		break;

	case SHIP_MOVEMENT_STATE_STOPPED:
		ui_.currentActionValue->setText(QString::fromUtf16(L"Loď stojí na místě"));

		ui_.stopButton->setText(QString::fromUtf16(L"Loď už stojí"));
		ui_.stopButton->setProperty("shipMode", "notwarp");
		ui_.stopButton->setStyleSheet(ui_.stopButton->styleSheet());
		ui_.stopButton->setEnabled(false);

		ui_.orbitButton->setEnabled(true);

		break;

	case SHIP_MOVEMENT_STATE_ORBITING:
		ui_.currentActionValue->setText(QString::fromUtf16(L"Loď obíhá planetu"));

		ui_.stopButton->setText(QString::fromUtf16(L"Zastavit loď"));
		ui_.stopButton->setProperty("shipMode", "notwarp");
		ui_.stopButton->setStyleSheet(ui_.stopButton->styleSheet());
		ui_.stopButton->setEnabled(true);

		ui_.orbitButton->setEnabled(true);

		break;

	case SHIP_MOVEMENT_STATE_WARP:
		ui_.currentActionValue->setText(QString::fromUtf16(L"Loď letí warpem"));

		ui_.stopButton->setText(QString::fromUtf16(L"Zastavit warp"));
		ui_.stopButton->setProperty("shipMode", "warp");		
		ui_.stopButton->setStyleSheet(ui_.stopButton->styleSheet());
		ui_.stopButton->setEnabled(true);

		ui_.orbitButton->setEnabled(false);

		break;

	}
}

id_t LocationTable::getCurrentID() {
	return currentActualId_;
}

void LocationTable::updateItems(std::map<id_t, GameItemRow *> & newItems) {
	clearAllContentKeepFilter();

	for (std::map<id_t, GameItemRow *>::const_iterator it = newItems.begin(); it != newItems.end(); ++it) {
		insertItem(it->second);
	}
}

void NavigationWidget::createNavigationDialog() {
	navigationDialog_ = new NavigationDialog(this);
		
	bool connected = true;		
	connected = connected && connect(navigationDialog_, SIGNAL(moveStandardSignal()), this, SLOT(moveStandardNavigationDialogSlot()));
	connected = connected && connect(navigationDialog_, SIGNAL(moveSubspaceSignal()), this, SLOT(moveSubspaceNavigationDialogSlot()));
	connected = connected && connect(navigationDialog_, SIGNAL(dockDownSignal()), this, SLOT(dockDownNavigationDialogSlot()));
	connected = connected && connect(navigationDialog_, SIGNAL(cancelSignal()), this, SLOT(cancelNavigationSlot()));
	connected = connected && connect(navigationDialog_, SIGNAL(rejected()), this, SLOT(rejectDialogSlot()));
	assert(connected && "Signals not connected");

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

void NavigationWidget::rejectDialogSlot() {
	emit hideDialogSignal();
}

void NavigationWidget::moveStandardNavigationDialogSlot() {
	int hours = navigationDialog_->getHours();
	int minutes = navigationDialog_->getMinutes();
	int seconds = navigationDialog_->getSeconds();

	unsigned long secondsTotal = seconds + minutes * 60 + hours * 3600;

	bool isInOneDay = secondsTotal < 24 * 60 * 60;

	if (!(isInOneDay && secondsTotal > 0)) {	
		return;
	}

	switch (navigateTo_) {
		case NAVIGATION_SYSTEM:
			emit navigationMoveToSpaceObjectSignal(contextShip_.id, selectedItem_->getId(), secondsTotal);
			break;
		case NAVIGATION_SHIP:
			emit navigationPursuitSignal(contextShip_.id, selectedItem_->getId(), secondsTotal);
			break;
		case NAVIGATION_BASE:
			emit navigationMoveToSpaceObjectSignal(contextShip_.id, selectedItem_->getId(), secondsTotal);
			break;
		case NAVIGATION_PLANET:
			emit navigationMoveToSpaceObjectSignal(contextShip_.id, selectedItem_->getId(), secondsTotal);
			break;
		case NAVIGATION_CUSTOM:
			emit navigationMoveToSignal(contextShip_.id, positionx, positiony, secondsTotal);
			break;
	}

	emit hideDialogSignal();
	navigationDialog_->accept();
}

void NavigationWidget::moveSubspaceNavigationDialogSlot() {
	if (selectedItem_ == NULL) {
		KODIAK_DEBUG_COUT << "Null pointer in void NavigationWidget::moveSubspaceNavigationDialogSlot()";
		return;
	}

	switch (navigateTo_) {
		case NAVIGATION_SYSTEM:
			emit navigationMoveToSpaceObjectByWarpSignal(contextShip_.id, selectedItem_->getId());
			break;
		case NAVIGATION_CUSTOM:
			emit navigationWarpSignal(contextShip_.id, positionx, positiony);
			break;
		case NAVIGATION_PLANET:
			emit navigationMoveToSpaceObjectByWarpSignal(contextShip_.id, selectedItem_->getId());
			break;
	}

	emit hideDialogSignal();
	navigationDialog_->accept();
}

void NavigationWidget::dockDownNavigationDialogSlot() {
	if (selectedItem_ == NULL) {
		KODIAK_DEBUG_COUT << "Null pointer in void NavigationWidget::moveSubspaceNavigationDialogSlot()";
		return;
	}

	emit hideDialogSignal();
	navigationDialog_->accept();

	emit navigationDockDownSignal(selectedItem_->getId());
}

void NavigationWidget::unboundSlot() {
	emit navigationUnboundSignal();
}

void NavigationWidget::showNavigationDialog(bool showWarp) {
	if (navigationDialog_ == NULL) {
		createNavigationDialog();
	}

	emit showDialogSignal();

	navigationDialog_->setDialog(showWarp);

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

void NavigationWidget::showNavigationDialog(DockingResult canDockDown) {
	if (navigationDialog_ == NULL) {
		createNavigationDialog();
	}

	emit showDialogSignal();

	navigationDialog_->setDialog(canDockDown);

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

void NavigationWidget::showNavigationDialog(const NavigationPlanetDetails & planet) {
	if (navigationDialog_ == NULL) {
		createNavigationDialog();
	}

	emit showDialogSignal();

	navigationDialog_->setDialog(planet);

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

void NavigationWidget::cancelNavigationSlot() {
	emit hideDialogSignal();
	navigationDialog_->reject();
}

void NavigationWidget::answerNavigationDockDown(id_t shipId, id_t baseId, DockingResult result) {
}

void NavigationWidget::answerNavigationUnbound(id_t shipId, DockingResult result) {
}

std::wstring NavigationWidget::dockingResult2WString(DockingResult result) {
	std::wstring reason;

	switch (result) {
	case DR_OK:
		reason = L"Vše v pořádku";
		break;
	case DR_BAD_SOURCE_FORTRESS_TYPE:
		reason = L"Zdrojová pevnost nemá správný typ";
		break;
	case DR_BAD_TARGET_FORTRESS_TYPE:
		reason = L"Cílová pevnost nemá správný typ";
		break;
	case DR_UNCONTROLLABLE_TARGET:
		reason = L"Cílová základna je nekontrolovatelná, lze ji obsadit, ale ne na ni přistát";
		break;
	case DR_NOT_YOUR_DOCK:
		reason = L"Cílovou základnu vlastní jiný hráč, nelze tam proto přistát";
		break;
	case DR_OUT_OF_RANGE:
		reason = L"Cílová základna není v dosahu";
		break;
	case DR_IMPULS_DRIVE_FAIL:
		reason = L"Loď nemá motory či tlumiče nebo je něco z toho rozbité";
		break;
	case DR_NOT_ENOUGH_DEUTERIUM:
		reason = L"loď nemá dost paliva na přistání";
		break;
	case DR_NO_FREE_HANGAR:
		reason = L"Cílová základna nemá žádný volný hangár";
		break;
	case DR_NOT_DOCKING_SHIP:
		reason = L"Zdrojová pevnost není na základně";
		break;
	case DR_UNKNOWN_FAIL:
		reason = L"Příčina není známa";
	}

	return reason;
}

bool NavigationWidget::isInWarp() {
	return isInWarp_;
}