StimPack* DroidStimpackModuleDataComponent::findStimPack() {
	StimPack* pack = NULL;
	float biggest = 0;
	DroidComponent* container = cast<DroidComponent*>(getParent());

	if (container == NULL)
		return NULL;

	ManagedReference<SceneObject*> craftingComponents = container->getSlottedObject("crafted_components");

	if (craftingComponents != NULL) {
		SceneObject* satchel = craftingComponents->getContainerObject(0);

		for (int i = 0; i < satchel->getContainerObjectsSize(); ++i) {
			ManagedReference<SceneObject*> sceno = satchel->getContainerObject(i);

			// is a stimpack
			if (sceno->isPharmaceuticalObject()) {
				PharmaceuticalObject* pharma = sceno.castTo<PharmaceuticalObject*>();

				if (pharma->isStimPack() && !pharma->isPetStimPack() && !pharma->isDroidRepairKit()) {
					StimPack* stim = cast<StimPack*>(pharma);

					if (stim->getEffectiveness() > biggest) {
						biggest = stim->getEffectiveness();
						pack = stim;
					}
				}
			}
		}
	}

	return pack;
}
StimPack* DroidStimpackModuleDataComponent::compatibleStimpack(float power) {
    DroidComponent* droidComponent = cast<DroidComponent*>(getParent());
    if (droidComponent == NULL) {
        info("droidComponent was null");
        return NULL;
    }
    DroidObject* droid = getDroidObject();
    if (droid == NULL) {
        return NULL;
    }
    Locker dlock(droid);
    ManagedReference<SceneObject*> craftingComponents = droidComponent->getSlottedObject("crafted_components");
    if(craftingComponents != NULL) {
        SceneObject* satchel = craftingComponents->getContainerObject(0);
        if(satchel == NULL) {
            return NULL;
        }
        for (int i = 0; i < satchel->getContainerObjectsSize(); ++i) {
            SceneObject* item = satchel->getContainerObject(i);
            if (!item->isTangibleObject())
                continue;

            TangibleObject* tano = cast<TangibleObject*>( item);
            if (tano->isPharmaceuticalObject()) {
                StimPack* stim = cast<StimPack*>(tano);
                if(stim->getEffectiveness() == power) {
                    return stim;
                }
            }
        }
    }
    return NULL;
}
void DroidStimpackModuleDataComponent::initialize(CreatureObject* droid) {
    // grab the crafted components in this module and remove then
    // then change capacity to the new capacity so we store the stims directly in the component.
    DroidComponent* droidComponent = cast<DroidComponent*>(getParent());
    if (droidComponent == NULL) {
        info("droidComponent was null");
        return;
    }
    droidComponent->dropSlottedObject("crafted_components");
    ManagedReference<SceneObject*> craftingComponents = droidComponent->getSlottedObject("crafted_components");
    if(craftingComponents == NULL) {
        // create the satchel and container as it would not be present as this object doesnt use components.
        ManagedReference<SceneObject*> craftingComponentsSatchel = NULL;
        String craftingComponentsPath = "object/tangible/crafting/crafting_components_container.iff";
        craftingComponents = droidComponent->getZoneServer()->createObject(craftingComponentsPath.hashCode(), 1);
        craftingComponents->removeAllContainerObjects();
        craftingComponents->setSendToClient(false);
        droidComponent->transferObject(craftingComponents, 4, false);
        Locker locker(craftingComponents);
        craftingComponents->setContainerDefaultDenyPermission(ContainerPermissions::OPEN + ContainerPermissions::MOVEIN + ContainerPermissions::MOVEOUT + ContainerPermissions::MOVECONTAINER);
        craftingComponents->setContainerDefaultAllowPermission(0);
        craftingComponents->setContainerDenyPermission("owner", ContainerPermissions::OPEN + ContainerPermissions::MOVEIN + ContainerPermissions::MOVEOUT + ContainerPermissions::MOVECONTAINER);
        craftingComponents->setContainerDenyPermission("admin", ContainerPermissions::OPEN + ContainerPermissions::MOVEIN + ContainerPermissions::MOVEOUT + ContainerPermissions::MOVECONTAINER);
        craftingComponents->setContainerAllowPermission("owner", 0);
        craftingComponents->setContainerAllowPermission("admin", 0);
        craftingComponents->setContainerInheritPermissionsFromParent(false);
        locker.release();

        String craftingComponentsSatchelPath = "object/tangible/hopper/crafting_station_hopper/crafting_station_ingredient_hopper_large.iff";
        craftingComponentsSatchel = droidComponent->getZoneServer()->createObject(craftingComponentsSatchelPath.hashCode(), 1);
        Locker locker2(craftingComponentsSatchel);
        craftingComponentsSatchel->setContainerVolumeLimit(capacity);
        craftingComponentsSatchel->setContainerInheritPermissionsFromParent(false);
        craftingComponentsSatchel->setContainerDefaultDenyPermission(ContainerPermissions::OPEN + ContainerPermissions::MOVEIN + ContainerPermissions::MOVEOUT + ContainerPermissions::MOVECONTAINER);
        craftingComponentsSatchel->setContainerDefaultAllowPermission(0);
        craftingComponentsSatchel->setContainerAllowPermission("admin", ContainerPermissions::OPEN);
        craftingComponentsSatchel->setContainerDenyPermission("admin", ContainerPermissions::MOVEIN + ContainerPermissions::MOVEOUT + ContainerPermissions::MOVECONTAINER);
        craftingComponentsSatchel->setContainerAllowPermission("owner", 0);
        craftingComponentsSatchel->setContainerDenyPermission("owner", ContainerPermissions::OPEN + ContainerPermissions::MOVEIN + ContainerPermissions::MOVEOUT + ContainerPermissions::MOVECONTAINER);
        craftingComponentsSatchel->sendTo(droid, true);
        craftingComponents->transferObject(craftingComponentsSatchel, -1, false);
    }
}
void DroidStimpackModuleDataComponent::countUses() {
	DroidComponent* droidComponent = cast<DroidComponent*>(getParent());
	if (droidComponent == NULL) {
		info("droidComponent was null");
		return;
	}

	DroidObject* droid = getDroidObject();
	if (droid == NULL) {
		return ;
	}

	Locker dlock(droid);

	ManagedReference<SceneObject*> craftingComponents = droidComponent->getSlottedObject("crafted_components");
	if (craftingComponents == NULL) {
		return;
	}

	SceneObject* satchel = craftingComponents->getContainerObject(0);
	if (satchel == NULL) {
		return;
	}

	loaded = 0;

	for (int i = 0; i < satchel->getContainerObjectsSize(); ++i) {
		ManagedReference<SceneObject*> item = satchel->getContainerObject(i);
		if (!item->isPharmaceuticalObject())
			continue;

		PharmaceuticalObject* pharma = item.castTo<PharmaceuticalObject*>();

		if (pharma->isStimPack())
			loaded += pharma->getUseCount();
	}
}
void DroidStimpackModuleDataComponent::handleInsertStimpack(CreatureObject* player, StimPack* pack) {
	// we need to send the invalid stimpack message just where is a good question
	countUses();

	if (player == NULL)
		return;

	if (!player->hasSkill("science_medic_ability_04")) {
		return;
	}

	ManagedReference<DroidObject*> droid = getDroidObject();
	if (droid == NULL) {
		return;
	}

	if (pack == NULL) {
		player->sendSystemMessage("@pet/droid_modules:invalid_stimpack");
		return;
	}

	if (!pack->isClassA()) {
		player->sendSystemMessage("@pet/droid_modules:invalid_stimpack");
		return;
	}

	if (droid->getLinkedCreature().get() != player) {
		return;
	}

	// we have the player and the stim to add to ourselves.
	// code should goes as follow, count total use of all stims, then deduct amount form capacity
	DroidComponent* droidComponent = cast<DroidComponent*>(getParent());

	if (droidComponent == NULL) {
		return;
	}

	ManagedReference<SceneObject*> craftingComponents = droidComponent->getSlottedObject("crafted_components");

	if (craftingComponents == NULL) {
		return;
	}

	SceneObject* satchel = craftingComponents->getContainerObject(0);

	if (satchel == NULL) {
		return;
	}

	int allowedAmount = capacity - loaded;

	if (allowedAmount <= 0) {
		player->sendSystemMessage("@pet/droid_modules:stimpack_capacity_full");
		return;
	}

	Locker plocker(pack);

	int amountOnStim = pack->getUseCount();
	StimPack* targetStim = compatibleStimpack(pack->getEffectiveness());

	if (targetStim != NULL) {
		Locker tlocker(targetStim);

		if (allowedAmount > amountOnStim) {
			targetStim->setUseCount(targetStim->getUseCount() + amountOnStim, true);
			pack->decreaseUseCount(pack->getUseCount());
		} else {
			targetStim->setUseCount(targetStim->getUseCount() + allowedAmount, true);
			pack->decreaseUseCount(allowedAmount);
		}
	} else {
		// can we take it all?
		if (allowedAmount > amountOnStim) {
			pack->destroyObjectFromWorld(true);
			// transfer to the droid and broadcast, then send the satchel to the player
			satchel->transferObject(pack, -1, true);
			satchel->broadcastObject(pack, true);
			pack->sendTo(player, true);
			droid->sendTo(player, true);
			player->sendSystemMessage("@pet/droid_modules:stimpack_loaded");
		} else {
			// we cant load it all so split the diff
			StimPack* newStim = pack->split(allowedAmount);

			if (newStim != NULL) {
				Locker slocker(newStim);
				satchel->transferObject(newStim, -1, true);
				satchel->broadcastObject(newStim, true);
				player->sendSystemMessage("@pet/droid_modules:stimpack_loaded");
			}
		}
	}

	countUses();
}