#include "warehousesWidget.h"
#include "stockTableWidget.h"
#include <cassert>

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

	std::map<id_t, warehouse_item_status> allItems;

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

	updateItems(allItems);
}

void StockTableWidget::searchClickedSlot() {
	QString searchedString = ui_.warehouseItemsSearchEdit->text();

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

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

    std::map<id_t, warehouse_item_status> matchedItems;

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

	updateItems(matchedItems);
}

void StockTableWidget::clearFilteredContentKeepFilter() {
    for (int i = ui_.warehouseItemsTable->rowCount() - 1; i >= 0; --i) {
        ui_.warehouseItemsTable->removeRow(i);
    }    
}

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

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

	ui_.warehouseItemsSearchEdit->clear();
}

void StockTableWidget::insertItem(const warehouse_item_status & item) {
	
	rows_.insert(std::make_pair(item.id, item));

	if (matchesFilterIfAny(item.patternName)) {
		ui_.warehouseItemsTable->setSortingEnabled(false);

		const int targetRow = ui_.warehouseItemsTable->rowCount();
		ui_.warehouseItemsTable->insertRow(targetRow);

		WarehouseItemWidget * itemWidget = new WarehouseItemWidget(ui_.warehouseItemsTable, item, false);

		for (warehouse_item_status::parameters_list_t::const_iterator paramIt = item.parameters.begin(); paramIt != item.parameters.end(); ++paramIt) {
			itemWidget->addParameter(*paramIt);
		}

		ui_.warehouseItemsTable->setRowHeight(targetRow, itemWidget->height());
		ui_.warehouseItemsTable->setCellWidget(targetRow, 0, itemWidget);	
		ui_.warehouseItemsTable->setItem(targetRow, 0, new WarehouseTableItemWidget(item.patternName));	

		bool connected = connect(itemWidget, SIGNAL(clickedSignal(const warehouse_item_status &)), this, SLOT(itemClickedSlot(const warehouse_item_status &)));
		assert(connected && "Signals not connected");

		ui_.warehouseItemsTable->setSortingEnabled(true);	
	}	
}

bool StockTableWidget::matchesFilterIfAny(const std::string & name) {
	if (currentFilter_ == NULL) {
		return true;
	}
	else {
		return currentFilter_->exactMatch(QString::fromUtf8(name.c_str()));
	}
}

void StockTableWidget::removeRowAndItem(id_t itemId) {
	rows_.erase(itemId);

	int row = findRowOfItem(itemId);

	if (row != -1) {
		removeRow(row);
	}
}

void StockTableWidget::removeRow(int row) {
	ui_.warehouseItemsTable->removeRow(row);
}

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

	ui_.warehouseItemsTable->verticalHeader()->setResizeMode(QHeaderView::Interactive);

	currentFilter_ = NULL;

	connectSignals();
}

void StockTableWidget::connectSignals() {
	bool isConnected = connect(ui_.warehouseItemsSearchButton, SIGNAL(clicked()), this, SLOT(searchClickedSlot()));
    assert(isConnected);

    isConnected = connect(ui_.warehouseItemsAllButton, SIGNAL(clicked()), this, SLOT(showAllClickedSlot()));
    assert(isConnected && "Signals not connected");

	isConnected = connect(ui_.warehouseItemsTable, SIGNAL(cellClicked(int,int)), this, SLOT(cellClickedSlot(int, int)));
	assert(isConnected && "Signals not connected");
}

void StockTableWidget::itemClickedSlot(const warehouse_item_status & item) {
	emit itemClickedSignal(item);
}

int StockTableWidget::findRowOfItem(id_t id) {
	int rowCount = ui_.warehouseItemsTable->rowCount();

	for (int row = 0; row < rowCount; ++row) {
		WarehouseItemWidget * itemWidget = dynamic_cast<WarehouseItemWidget *>(ui_.warehouseItemsTable->cellWidget(row, 0));

		if (itemWidget != NULL) {
			if (itemWidget->getItemId() == id) {
				return row;
			}
		}
	}
	 
	return -1;
}

void StockTableWidget::updateItems(std::map<id_t, warehouse_item_status> & newItems) {
	for (int row = ui_.warehouseItemsTable->rowCount() - 1; row >= 0; --row){
		WarehouseItemWidget * itemWidget = dynamic_cast<WarehouseItemWidget *>(ui_.warehouseItemsTable->cellWidget(row, 0));

		bool isUpdated = false;

		if (itemWidget != NULL) {
			std::map<id_t, warehouse_item_status>::iterator it = newItems.find(itemWidget->getItemId());

			if (it != newItems.end()) {
				newItems.erase(it);
				isUpdated = true;
			}
		}		

		if (!isUpdated) {
			removeRow(row);
		}
	}

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

void StockTableWidget::cellClickedSlot(int row, int col) {
	WarehouseItemWidget * itemWidget = (WarehouseItemWidget *) ui_.warehouseItemsTable->cellWidget(row, 0);

    if (itemWidget != 0) {
		emit itemClickedSignal(itemWidget->getItem());
    }
}