/**
 * Moves all the items (as much as possible) to the craft on right-click.
 * @param action Pointer to an action.
 */
void CraftEquipmentState::lstEquipmentRightArrowClick(Action *action)
{
	if (action->getDetails()->button.button == SDL_BUTTON_RIGHT)
	{
		Craft *c = _base->getCrafts()->at(_craft);
		RuleItem *item = _game->getRuleset()->getItem(_items[_sel]);
		int bqty = _base->getItems()->getItem(_items[_sel]);
		if (bqty > 0)
		{
			// Do we need to convert item to vehicle?
			if (item->isFixed())
			{
				// Check if there's enough room
				int room = std::min(c->getRules()->getVehicles() - c->getNumVehicles(), c->getSpaceAvailable() / 4);
				if (room > 0)
				{
					RuleItem *ammo = _game->getRuleset()->getItem(item->getCompatibleAmmo()->front());
					int baqty = _base->getItems()->getItem(ammo->getType());
					int vehiclesCount = std::min(std::min(bqty, room), baqty);
					if (vehiclesCount > 0)
					{
						int newAmmoPerVehicle = std::min(baqty / vehiclesCount, ammo->getClipSize());;
						int remainder = baqty - (vehiclesCount * newAmmoPerVehicle);
						if (ammo->getClipSize() == newAmmoPerVehicle) remainder = 0;
						int newAmmo;
						for (int i=0; i < vehiclesCount; ++i)
						{
							newAmmo = newAmmoPerVehicle;
							if (i<remainder) ++newAmmo;
							c->getVehicles()->push_back(new Vehicle(item, newAmmo));
							_base->getItems()->removeItem(ammo->getType(), newAmmo);
							_base->getItems()->removeItem(_items[_sel]);
						}
					}
				}
			}
			else
			{
				_base->getItems()->removeItem(_items[_sel],bqty);
				c->getItems()->addItem(_items[_sel],bqty);
			}
			updateQuantity();
		}
	}
}
/**
 * Moves the selected item to the craft.
 */
void CraftEquipmentState::moveRight()
{
	Craft *c = _base->getCrafts()->at(_craft);
	RuleItem *item = _game->getRuleset()->getItem(_items[_sel]);
	if (_base->getItems()->getItem(_items[_sel]) > 0)
	{
		// Convert item to vehicle
		if (item->isFixed())
		{
			// Check if there's enough room
			if (c->getNumVehicles() < c->getRules()->getVehicles() && c->getSpaceAvailable() >= 4)
			{
				RuleItem *ammo = _game->getRuleset()->getItem(item->getCompatibleAmmo()->front());
				int qty = _base->getItems()->getItem(ammo->getType());
				if (qty == 0)
				{
					std::wstringstream ss;
					ss << _game->getLanguage()->getString("STR_NOT_ENOUGH");
					ss << _game->getLanguage()->getString(ammo->getType());
					ss << _game->getLanguage()->getString("STR_TO_ARM_HWP");
					_game->pushState(new ErrorMessageState(_game, ss.str(), Palette::blockOffset(15)+1, "BACK04.SCR", 2));
					_timerRight->stop();
				}
				else
				{
					int newAmmo = std::min(qty, ammo->getClipSize());
					c->getVehicles()->push_back(new Vehicle(item, newAmmo));
					_base->getItems()->removeItem(ammo->getType(), newAmmo);
					_base->getItems()->removeItem(_items[_sel]);
				}
			}
		}
		else
		{
			_base->getItems()->removeItem(_items[_sel]);
			c->getItems()->addItem(_items[_sel]);
		}
		updateQuantity();
	}
}
/**
 * Moves the given number of items (selected) to the craft.
 */
void CraftEquipmentState::moveRight(int change)
{
	Craft *c = _base->getCrafts()->at(_craft);
	RuleItem *item = _game->getRuleset()->getItem(_items[_sel]);
	int bqty = _base->getItems()->getItem(_items[_sel]);
	if (0 >= change || 0 >= bqty) return;
	change = std::min(bqty, change);
	// Do we need to convert item to vehicle?
	if (item->isFixed())
	{
		// Check if there's enough room
		int room = std::min(c->getRules()->getVehicles() - c->getNumVehicles(), c->getSpaceAvailable() / 4);
		if (room > 0)
		{
			change = std::min(room, change);
			if(item->getClipSize() != -1)
			{
				// We want to redistribute all the available ammo among the vehicles,
				// so first we note the total number of vehicles we want in the craft
				int oldVehiclesCount = c->getVehicleCount(_items[_sel]);
				int newVehiclesCount = oldVehiclesCount + change;
				// ...and we move back all of this vehicle-type to the base.
				if (0 < oldVehiclesCount) moveLeft(INT_MAX);
				// And now let's see if we can add the total number of vehicles.
				RuleItem *ammo = _game->getRuleset()->getItem(item->getCompatibleAmmo()->front());
				int baqty = _base->getItems()->getItem(ammo->getType()); // Ammo Quantity for this vehicle-type on the base
				int canBeAdded = std::min(newVehiclesCount, baqty);
				if (canBeAdded > 0)
				{
					int newAmmoPerVehicle = std::min(baqty / canBeAdded, ammo->getClipSize());;
					int remainder = 0;
					if (ammo->getClipSize() > newAmmoPerVehicle) remainder = baqty - (canBeAdded * newAmmoPerVehicle);
					int newAmmo;
					for (int i=0; i < canBeAdded; ++i)
					{
						newAmmo = newAmmoPerVehicle;
						if (i<remainder) ++newAmmo;
						c->getVehicles()->push_back(new Vehicle(item, newAmmo));
						_base->getItems()->removeItem(ammo->getType(), newAmmo);
						_base->getItems()->removeItem(_items[_sel]);
					}
				}
				if (oldVehiclesCount >= canBeAdded)
				{
					// So we haven't managed to increase the count of vehicles because of the ammo
					_timerRight->stop();
					LocalizedText msg(tr("STR_NOT_ENOUGH_ammotype_TO_ARM_HWP").arg(tr(ammo->getType())));
					_game->pushState(new ErrorMessageState(_game, msg, Palette::blockOffset(15)+1, "BACK04.SCR", 2));
				}
			}
			else
				for (int i=0; i < change; ++i)
				{
					c->getVehicles()->push_back(new Vehicle(item, 255));
					_base->getItems()->removeItem(_items[_sel]);
				}
		}
	}
	else
	{
		_base->getItems()->removeItem(_items[_sel],change);
		c->getItems()->addItem(_items[_sel],change);
	}
	updateQuantity();
}
/**
 * The craft info can change
 * after going into other screens.
 */
void CraftInfoState::init()
{
    // Set palette
    _game->setPalette(_game->getResourcePack()->getPalette("BACKPALS.DAT")->getColors(Palette::blockOffset(3)), Palette::backPos, 16);

    Craft *c = _base->getCrafts()->at(_craft);

    _edtCraft->setText(c->getName(_game->getLanguage()));

    SurfaceSet *texture = _game->getResourcePack()->getSurfaceSet("BASEBITS.PCK");
    texture->getFrame(c->getRules()->getSprite() + 33)->setX(0);
    texture->getFrame(c->getRules()->getSprite() + 33)->setY(0);
    texture->getFrame(c->getRules()->getSprite() + 33)->blit(_sprite);

    std::wstringstream ss;
    ss << tr("STR_DAMAGE_UC_").arg(Text::formatPercentage(c->getDamagePercentage()));
    if (c->getStatus() == "STR_REPAIRS")
    {
        int damageDays = (int)ceil((float)c->getDamage() / c->getRules()->getRepairRate() / 24.0f);
        ss << L"\n(" << tr("STR_DAY", damageDays) << ")";
    }
    _txtDamage->setText(ss.str());

    std::wstringstream ss2;
    ss2 << tr("STR_FUEL").arg(Text::formatPercentage(c->getFuelPercentage()));
    if (c->getStatus() == "STR_REFUELLING")
    {
        int fuelDays = (int) ceil((float)(c->getRules()->getMaxFuel() - c->getFuel()) / c->getRules()->getRefuelRate() / 48.0f);
        ss2 << L"\n(" << tr("STR_DAY", fuelDays) << ")";
    }
    _txtFuel->setText(ss2.str());

    if (c->getRules()->getSoldiers() > 0)
    {
        _crew->clear();
        _equip->clear();

        Surface *frame1 = texture->getFrame(38);
        frame1->setY(0);
        for (int i = 0, x = 0; i < c->getNumSoldiers(); ++i, x += 10)
        {
            frame1->setX(x);
            frame1->blit(_crew);
        }

        Surface *frame2 = texture->getFrame(40);
        frame2->setY(0);
        int x = 0;
        for (int i = 0; i < c->getNumVehicles(); ++i, x += 10)
        {
            frame2->setX(x);
            frame2->blit(_equip);
        }
        Surface *frame3 = texture->getFrame(39);
        for (int i = 0; i < c->getNumEquipment(); i += 4, x += 10)
        {
            frame3->setX(x);
            frame3->blit(_equip);
        }
    }
    else
    {
        _crew->setVisible(false);
        _equip->setVisible(false);
        _btnCrew->setVisible(false);
        _btnEquip->setVisible(false);
        _btnArmor->setVisible(false);
    }

    if (c->getRules()->getWeapons() > 0)
    {
        CraftWeapon *w1 = c->getWeapons()->at(0);

        if (w1 != 0)
        {
            Surface *frame = texture->getFrame(w1->getRules()->getSprite() + 48);
            frame->setX(0);
            frame->setY(0);
            frame->blit(_weapon1);

            _txtW1Name->setText(tr(w1->getRules()->getType()));
            _txtW1Ammo->setText(tr("STR_AMMO_").arg(w1->getAmmo()));
            _txtW1Max->setText(tr("STR_MAX").arg(w1->getRules()->getAmmoMax()));
        }
        else
        {
            _weapon1->clear();
            _txtW1Name->setText(L"");
            _txtW1Ammo->setText(L"");
            _txtW1Max->setText(L"");
        }
    }
    else
    {
        _weapon1->setVisible(false);
        _btnW1->setVisible(false);
        _txtW1Name->setVisible(false);
        _txtW1Ammo->setVisible(false);
        _txtW1Max->setVisible(false);
    }

    if (c->getRules()->getWeapons() > 1)
    {
        CraftWeapon *w2 = c->getWeapons()->at(1);

        if (w2 != 0)
        {
            Surface *frame = texture->getFrame(w2->getRules()->getSprite() + 48);
            frame->setX(0);
            frame->setY(0);
            frame->blit(_weapon2);

            _txtW2Name->setText(tr(w2->getRules()->getType()));
            _txtW2Ammo->setText(tr("STR_AMMO_").arg(w2->getAmmo()));
            _txtW2Max->setText(tr("STR_MAX").arg(w2->getRules()->getAmmoMax()));
        }
        else
        {
            _weapon2->clear();
            _txtW2Name->setText(L"");
            _txtW2Ammo->setText(L"");
            _txtW2Max->setText(L"");
        }
    }
    else
    {
        _weapon2->setVisible(false);
        _btnW2->setVisible(false);
        _txtW2Name->setVisible(false);
        _txtW2Ammo->setVisible(false);
        _txtW2Max->setVisible(false);
    }
}
/**
 * Moves the given number of items (selected) to the craft.
 * @param change Item difference.
 */
void CraftEquipmentState::moveRightByValue(int change)
{
	Craft *c = _base->getCrafts()->at(_craft);
	RuleItem *item = _game->getMod()->getItem(_items[_sel]);
	int bqty = _base->getStorageItems()->getItem(_items[_sel]);
	if (_game->getSavedGame()->getMonthsPassed() == -1)
	{
		if (change == INT_MAX)
		{
			change = 10;
		}
		bqty = change;
	}
	if (0 >= change || 0 >= bqty) return;
	change = std::min(bqty, change);
	// Do we need to convert item to vehicle?
	if (item->isFixed())
	{
		int size = 4;
		if (_game->getMod()->getUnit(item->getType()))
		{
			size = _game->getMod()->getArmor(_game->getMod()->getUnit(item->getType())->getArmor())->getSize();
			size *= size;
		}
		// Check if there's enough room
		int room = std::min(c->getRules()->getVehicles() - c->getNumVehicles(), c->getSpaceAvailable() / size);
		if (room > 0)
		{
			change = std::min(room, change);
			if (!item->getCompatibleAmmo()->empty())
			{
				// And now let's see if we can add the total number of vehicles.
				RuleItem *ammo = _game->getMod()->getItem(item->getCompatibleAmmo()->front());
				int ammoPerVehicle, clipSize;
				if (ammo->getClipSize() > 0 && item->getClipSize() > 0)
				{
					clipSize = item->getClipSize();
					ammoPerVehicle = clipSize / ammo->getClipSize();
				}
				else
				{
					clipSize = ammo->getClipSize();
					ammoPerVehicle = clipSize;
				}

				int baseQty = _base->getStorageItems()->getItem(ammo->getType()) / ammoPerVehicle;
				if (_game->getSavedGame()->getMonthsPassed() == -1)
					baseQty = 1;
				int canBeAdded = std::min(change, baseQty);
				if (canBeAdded > 0)
				{
					for (int i=0; i < canBeAdded; ++i)
					{
						if (_game->getSavedGame()->getMonthsPassed() != -1)
						{
							_base->getStorageItems()->removeItem(ammo->getType(), ammoPerVehicle);
							_base->getStorageItems()->removeItem(_items[_sel]);
						}
						c->getVehicles()->push_back(new Vehicle(item, clipSize, size));
					}
				}
				else
				{
					// So we haven't managed to increase the count of vehicles because of the ammo
					_timerRight->stop();
					LocalizedText msg(tr("STR_NOT_ENOUGH_AMMO_TO_ARM_HWP").arg(tr(ammo->getType())));
					_game->pushState(new ErrorMessageState(msg, _palette, _game->getMod()->getInterface("craftEquipment")->getElement("errorMessage")->color, "BACK04.SCR", _game->getMod()->getInterface("craftEquipment")->getElement("errorPalette")->color));
				}
			}
			else
				for (int i=0; i < change; ++i)
				{
					c->getVehicles()->push_back(new Vehicle(item, item->getClipSize(), size));
					if (_game->getSavedGame()->getMonthsPassed() != -1)
					{
						_base->getStorageItems()->removeItem(_items[_sel]);
					}
				}
		}
	}
	else
	{
		if (c->getRules()->getMaxItems() > 0 && _totalItems + change > c->getRules()->getMaxItems())
		{
			_timerRight->stop();
			LocalizedText msg(tr("STR_NO_MORE_EQUIPMENT_ALLOWED", c->getRules()->getMaxItems()));
			_game->pushState(new ErrorMessageState(msg, _palette, _game->getMod()->getInterface("craftEquipment")->getElement("errorMessage")->color, "BACK04.SCR", _game->getMod()->getInterface("craftEquipment")->getElement("errorPalette")->color));
			change = c->getRules()->getMaxItems() - _totalItems;
		}
		c->getItems()->addItem(_items[_sel],change);
		_totalItems += change;
		if (_game->getSavedGame()->getMonthsPassed() > -1)
		{
			_base->getStorageItems()->removeItem(_items[_sel],change);
		}
	}
	updateQuantity();
}
/**
 * The craft info can change
 * after going into other screens.
 */
void CraftInfoState::init()
{
	// Set palette
	_game->setPalette(_game->getResourcePack()->getPalette("BACKPALS.DAT")->getColors(Palette::blockOffset(3)), Palette::backPos, 16);

	Craft *c = _base->getCrafts()->at(_craft);

	_edtCraft->setText(c->getName(_game->getLanguage()));

	SurfaceSet *texture = _game->getResourcePack()->getSurfaceSet("BASEBITS.PCK");
	texture->getFrame(c->getRules()->getSprite() + 33)->setX(0);
	texture->getFrame(c->getRules()->getSprite() + 33)->setY(0);
	texture->getFrame(c->getRules()->getSprite() + 33)->blit(_sprite);

	std::wstringstream ss;
	ss << _game->getLanguage()->getString("STR_DAMAGE_UC_") << L'\x01' << c->getDamagePercentage() << "%";
	_txtDamage->setText(ss.str());

	std::wstringstream ss2;
	ss2 << _game->getLanguage()->getString("STR_FUEL") << L'\x01' << c->getFuelPercentage() << "%";
	_txtFuel->setText(ss2.str());

	if (c->getRules()->getSoldiers() > 0)
	{
		_crew->clear();
		_equip->clear();

		Surface *frame1 = texture->getFrame(38);
		frame1->setY(0);
		for (int i = 0, x = 0; i < c->getNumSoldiers(); ++i, x += 10)
		{
			frame1->setX(x);
			frame1->blit(_crew);
		}

		Surface *frame2 = texture->getFrame(39);
		frame2->setY(0);
		int x = 0;
		for (int i = 0; i < c->getNumEquipment(); i += 4, x += 10)
		{
			frame2->setX(x);
			frame2->blit(_equip);
		}
		Surface *frame3 = texture->getFrame(40);
		for (int i = 0; i < c->getNumVehicles(); ++i, x += 10)
		{
			frame3->setX(x);
			frame3->blit(_equip);
		}
	}
	else
	{
		_crew->setVisible(false);
		_equip->setVisible(false);
		_btnCrew->setVisible(false);
		_btnEquip->setVisible(false);
		_btnArmor->setVisible(false);
	}

	if (c->getRules()->getWeapons() > 0)
	{
		CraftWeapon *w1 = c->getWeapons()->at(0);

		if (w1 != 0)
		{
			Surface *frame = texture->getFrame(w1->getRules()->getSprite() + 48);
			frame->setX(0);
			frame->setY(0);
			frame->blit(_weapon1);

			_txtW1Name->setText(_game->getLanguage()->getString(w1->getRules()->getType()));

			std::wstringstream ss3;
			ss3 << _game->getLanguage()->getString("STR_AMMO_") << L'\x01' << w1->getAmmo();
			_txtW1Ammo->setText(ss3.str());

			std::wstringstream ss4;
			ss4 << _game->getLanguage()->getString("STR_MAX") << L'\x01' << w1->getRules()->getAmmoMax();
			_txtW1Max->setText(ss4.str());
		}
		else
		{
			_weapon1->clear();
			_txtW1Name->setText(L"");
			_txtW1Ammo->setText(L"");
			_txtW1Max->setText(L"");
		}
	}
	else
	{
		_weapon1->setVisible(false);
		_btnW1->setVisible(false);
		_txtW1Name->setVisible(false);
		_txtW1Ammo->setVisible(false);
		_txtW1Max->setVisible(false);
	}

	if (c->getRules()->getWeapons() > 1)
	{
		CraftWeapon *w2 = c->getWeapons()->at(1);

		if (w2 != 0)
		{
			Surface *frame = texture->getFrame(w2->getRules()->getSprite() + 48);
			frame->setX(0);
			frame->setY(0);
			frame->blit(_weapon2);

			_txtW2Name->setText(_game->getLanguage()->getString(w2->getRules()->getType()));

			std::wstringstream ss5;
			ss5 << _game->getLanguage()->getString("STR_AMMO_") << L'\x01' << w2->getAmmo();
			_txtW2Ammo->setText(ss5.str());

			std::wstringstream ss6;
			ss6 << _game->getLanguage()->getString("STR_MAX") << L'\x01' << w2->getRules()->getAmmoMax();
			_txtW2Max->setText(ss6.str());
		}
		else
		{
			_weapon2->clear();
			_txtW2Name->setText(L"");
			_txtW2Ammo->setText(L"");
			_txtW2Max->setText(L"");
		}
	}
	else
	{
		_weapon2->setVisible(false);
		_btnW2->setVisible(false);
		_txtW2Name->setVisible(false);
		_txtW2Ammo->setVisible(false);
		_txtW2Max->setVisible(false);
	}
}