/*******************************************************************************
* Copyright (c) 2015 - 2017
* <p>
* Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
* <p>
* The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
* <p>
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*******************************************************************************/
package jsettlers.logic.map.grid.partition.manager.materials.offers;
import jsettlers.common.material.EMaterialType;
import jsettlers.common.position.ShortPoint2D;
import jsettlers.logic.map.grid.partition.data.MaterialCounts;
import jsettlers.logic.map.grid.partition.manager.materials.interfaces.IOfferEmptiedListener;
import jsettlers.logic.map.grid.partition.manager.materials.offers.list.PrioritizedPositionableList;
import java.io.Serializable;
/**
* This class builds a data structure to hold {@link MaterialOffer}s and access them with range searches.
*
* @author Andreas Eberle
*/
public final class OffersList implements Serializable {
private static final long serialVersionUID = 3747575330300586115L;
private final PrioritizedPositionableList<EOfferPriority, MaterialOffer>[] offersLists;
private final MaterialCounts materialCounts;
/**
* Constructor to create a new {@link OffersList}.
*/
@SuppressWarnings("unchecked")
public OffersList(IOffersCountListener countsListener) {
offersLists = new PrioritizedPositionableList[EMaterialType.NUMBER_OF_MATERIALS];
for (int i = 0; i < EMaterialType.NUMBER_OF_MATERIALS; i++) {
offersLists[i] = new PrioritizedPositionableList<>(EOfferPriority.NUMBER_OF_PRIORITIES);
}
this.materialCounts = new MaterialCounts(countsListener);
}
/**
* Insert an offered material at the given position.
*
* @param position
* The position the offered material is located.
* @param material
* The material that is offered at the given position.
* @param offerPriority
*/
public void addOffer(ShortPoint2D position, EMaterialType material, EOfferPriority offerPriority) {
PrioritizedPositionableList<EOfferPriority, MaterialOffer> list = offersLists[material.ordinal];
MaterialOffer existingOffer = list.getObjectAt(position, offerPriority);
if (existingOffer != null) {
existingOffer.incrementAmount();
} else {
list.insert(new MaterialOffer(position, material, materialCounts, offerPriority, (byte) 1));
}
}
/**
* Insert an offered material at the given position.
*
* @param position
* The position the offered material is located.
* @param material
* The material that is offered at the given position.
* @param offerPriority
* The priority of the offer
* @param offerListener
* A listener that will be set to the offer
*/
public void addOffer(ShortPoint2D position, EMaterialType material, EOfferPriority offerPriority, IOfferEmptiedListener offerListener) {
PrioritizedPositionableList<EOfferPriority, MaterialOffer> list = offersLists[material.ordinal];
MaterialOffer existingOffer = list.getObjectAt(position, offerPriority);
if (existingOffer != null && existingOffer instanceof ListenableMaterialOffer) {
existingOffer.incrementAmount();
} else {
list.insert(new ListenableMaterialOffer(position, material, materialCounts, offerPriority, (byte) 1, offerListener));
}
}
/**
* Checks if there are any offers for the given {@link EMaterialType}.
*
* @param materialType
* The {@link EMaterialType} to be checked.
* @param minimumIncludedPriority
* The lowest priority to be included in
* @return Returns true if there are no offers for the given {@link EMaterialType},<br>
* false otherwise.
*/
public boolean isEmpty(EMaterialType materialType, EOfferPriority minimumIncludedPriority) {
return offersLists[materialType.ordinal].isEmpty(minimumIncludedPriority);
}
/**
* @param materialType
* {@link EMaterialType} of the offer.
* @param position
* The position to be used for the search.
* @return Returns an offer of the given {@link EMaterialType} that's close to the given position or <br>
* null if no offer for the given {@link EMaterialType} exists.
*/
public MaterialOffer getOfferCloseTo(EMaterialType materialType, EOfferPriority minimumIncludedPriority, ShortPoint2D position) {
PrioritizedPositionableList<EOfferPriority, MaterialOffer> offerSlot = offersLists[materialType.ordinal];
return offerSlot.getObjectCloseTo(position, minimumIncludedPriority);
}
/**
* FOR TESTS ONLY!
*
* @param position
* position to look for the offer
* @param materialType
* type of material of the offer
* @param offerPriority
* offerPriority of the offer
* @return
*/
public MaterialOffer getOfferObjectAt(ShortPoint2D position, EMaterialType materialType, EOfferPriority offerPriority) {
PrioritizedPositionableList<EOfferPriority, MaterialOffer> offerSlot = offersLists[materialType.ordinal];
return offerSlot.getObjectAt(position, offerPriority);
}
public void moveOffersAtPositionTo(ShortPoint2D position, final OffersList otherList) {
for (int materialTypeIndex = 0; materialTypeIndex < EMaterialType.NUMBER_OF_MATERIALS; materialTypeIndex++) {
offersLists[materialTypeIndex].moveObjectsAtPositionTo(position, otherList.offersLists[materialTypeIndex], movedOffer -> movedOffer.changeOffersCountListener(otherList.materialCounts));
}
}
public void moveAll(OffersList otherList) {
for (int materialTypeIndex = 0; materialTypeIndex < EMaterialType.NUMBER_OF_MATERIALS; materialTypeIndex++) {
offersLists[materialTypeIndex].moveAll(otherList.offersLists[materialTypeIndex], movedOffer -> movedOffer.changeOffersCountListener(materialCounts));
}
}
public void updateOfferPriority(ShortPoint2D position, EMaterialType materialType, EOfferPriority newPriority) {
PrioritizedPositionableList<EOfferPriority, MaterialOffer> offerSlot = offersLists[materialType.ordinal];
offerSlot.updatePriorityAt(position, newPriority);
}
public MaterialCounts getMaterialCounts() {
return materialCounts;
}
}