#ifndef ALL_WEAPON_WIDGET
#define ALL_WEAPON_WIDGET

#include <QtGui>
#include "ui_allWeaponsWidget.h"
#include "laserWeaponWidget.h"
#include "droneWeaponWidget.h"
#include "softProj\clientServer\structs.h"
#include "protocol.h"
#include "softProj\Main\INotifyUpdate.h"
#include <sstream>

class WeaponLayout : public QObject {
	Q_OBJECT
public:
	static const int MAX_WEAPON_COUNT = 9;
private:
	int actColumn;
	int actRow;

	QGridLayout * layout;

	QWidget * parent_;
	
	int displayedWeaponCount_;
	BasicWeaponWidget * weapons_[MAX_WEAPON_COUNT];
signals:
	void settingsChangedSignal(const std::pair<id_t, unsigned long long> & state);
	void unmountDroneWeaponSignal(id_t itemId);
	void unmountLaserWeaponSignal(id_t itemId);
private slots:
	void settingsChangedSlot(const std::pair<id_t, unsigned long long> & state) {
		emit settingsChangedSignal(state);
	}

	void unmountDroneWeaponSlot(id_t itemId) {
		emit unmountDroneWeaponSignal(itemId);
	}

	void unmountLaserWeaponSlot(id_t itemId) {
		emit unmountLaserWeaponSignal(itemId);
	}
public: 
	WeaponLayout(QWidget * parent) {
		actRow = 0;
		actColumn = 0;

		this->parent_ = parent;

		displayedWeaponCount_ = 0;

		layout = new QGridLayout(parent_);
		parent_->setLayout(layout);		

		layout->setGeometry(QRect(0, 0, parent_->width(), parent_->height()));
		layout->setHorizontalSpacing(0);
		layout->setVerticalSpacing(0);
		layout->setMargin(0);

		for (int i = 0; i < MAX_WEAPON_COUNT; ++i) {
			weapons_[i] = NULL;
		}
	}

	~WeaponLayout() {		
		delete layout;
	}

	void createLaserWeapons() {
		for (int i = 0; i < MAX_WEAPON_COUNT; ++i) {
			BasicWeaponWidget * deviceWidget = new LaserWeaponWidget(parent_);
			initWeapon(deviceWidget);
			weapons_[i] = deviceWidget;

			bool connected = true;
			connected = connected && connect(deviceWidget, SIGNAL(unmountSignal(id_t)), this, SLOT(unmountLaserWeaponSlot(id_t)));
			assert(connected && "Signals not connected");
		}
	}

	void createDroneWeapons() {
		for (int i = 0; i < MAX_WEAPON_COUNT; ++i) {
			BasicWeaponWidget * deviceWidget = new DroneWeaponWidget(parent_);
			initWeapon(deviceWidget);
			weapons_[i] = deviceWidget;

			bool connected = true;
			connected = connected && connect(deviceWidget, SIGNAL(unmountSignal(id_t)), this, SLOT(unmountDroneWeaponSlot(id_t)));
			assert(connected && "Signals not connected");
		}
	}

	void initWeapon(BasicWeaponWidget * deviceWidget) {

		layout->addWidget(deviceWidget, actRow, actColumn);

		actColumn++;

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

		layout->setSpacing(1);
		layout->setRowStretch(0, 2);
		layout->setRowStretch(1, 2);
		layout->setRowStretch(2, 2);

		deviceWidget->setEnergyUnit(L"TJ");

		bool connected = true;		
		connected = connected && connect(deviceWidget, SIGNAL(settingsChangedSignal(const std::pair<id_t, unsigned long long> &)),
			this, SLOT(settingsChangedSlot(const std::pair<id_t, unsigned long long> &)));

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

	void unmountAllWeapons() {
		for (int i = 0; i < MAX_WEAPON_COUNT; ++i) {
			weapons_[i]->setAsMounted(false);
		}

		displayedWeaponCount_ = 0;
	}

	BasicWeaponWidget * getWeapon(int order) {
		if (order >= 0 && order < MAX_WEAPON_COUNT) {
			return weapons_[order];
		}
		else {
			return NULL;
		}
	}

	int getDisplayedWeaponCount() {
		return displayedWeaponCount_;
	}

	void setDisplayedWeaponCount(int value) {
		this->displayedWeaponCount_ = value;
	}

	void setAsSmall() {
		for (int i = 0; i < MAX_WEAPON_COUNT; ++i) {
			if (weapons_[i] != NULL) {
				weapons_[i]->setAsSmall();
			}
		}
	}

	void setAsBig() {
		for (int i = 0; i < MAX_WEAPON_COUNT; ++i) {
			if (weapons_[i] != NULL) {
				weapons_[i]->setAsBig();
			}
		}
	}
};

///Manages and displayes all suported weapons. */
class AllWeaponsWidget : public NotifyWidget {
Q_OBJECT
private:
	Ui::AllWeaponsWidget ui_;

	int energySupply;
	int energyAccumulator;

	bool isSmall_;

	WeaponLayout * laserLayout_; 
	WeaponLayout * droneLayout_;

	bool isLockedForUpdate_;
	void lockForUpdate(bool lock);
	bool isSynchronizing_;

	weapons_status state_;

	QString availableButtonStyle_;
	QString unavailableButtonStyle_;

	QString availableSmallButtonStyle_;
	QString unavailableSmallButtonStyle_;
private slots:
	void weaponsSubmitedSlot(bool);
	void weaponsResetedSlot(bool);

	void droneSettingsChangedSlot(const std::pair<id_t, unsigned long long> & state);
	void laserSettingsChangedSlot(const std::pair<id_t, unsigned long long> & state);

	void unmountDronesButtonClickedSlot();
	void unmountCircuitButtonClickedSlot();

	void unmountDroneWeaponSlot(id_t itemId);
	void unmountLaserWeaponSlot(id_t itemId);
signals:
	void submitWeaponsSignal(WeaponsChangeDetails & state);
	void resetWeaponsSignal();

	/** Signals that user wants to unmount items
	@param patternName Name of pattern for device to unmount
	*/
	void unmountSignal(const std::string & patternName);

	/** Signals that user wants to unmount items
	@param patternName Name of pattern for device to unmount
	@param maxWorking Maximum number of working items to unmount
	@param maxDamaged Maximum number of damaged items to unmount
	*/
	void unmountSignal(const std::string & patternName, unsigned long long maxWorking, unsigned long long maxDamaged);

	/** Signals that user wants to unmount items
	@param patternName Name of pattern for device to unmount
	@param itemId Id of item to unmount
	*/
	void unmountSignal(const std::string & patternName, id_t itemId);
public:
	AllWeaponsWidget(QWidget * parent);
	~AllWeaponsWidget();

	void unmountAllWeapons();

	void setState(weapons_status & state);

	WeaponsChangeDetails getState();

	void notifyUpdate();

	void setAsBig();
	void setAsSmall();
};


#endif