package ch.sahits.game.openpatrician.model.building;
import ch.sahits.game.openpatrician.model.IBalanceSheet;
import ch.sahits.game.openpatrician.model.IPlayer;
import ch.sahits.game.openpatrician.model.building.impl.Storage;
import ch.sahits.game.openpatrician.model.building.impl.WeaponStorage;
import ch.sahits.game.openpatrician.model.city.ICity;
import ch.sahits.game.openpatrician.model.impl.BalanceSheet;
import ch.sahits.game.openpatrician.model.impl.WareHolding;
import ch.sahits.game.openpatrician.model.product.AmountablePrice;
import ch.sahits.game.openpatrician.model.product.EWare;
import ch.sahits.game.openpatrician.model.product.IWare;
import ch.sahits.game.openpatrician.model.time.DateObject;
import ch.sahits.game.openpatrician.model.time.EUpdateIntervalRegistration;
import ch.sahits.game.openpatrician.model.time.IPeriodicalUpdate;
import ch.sahits.game.openpatrician.model.time.PeriodicalTimeUpdater;
import ch.sahits.game.openpatrician.model.weapon.IWeapon;
/**
* Implementation of the trading office
* @author Andi Hotz, (c) Sahits GmbH, 2011
* Created on Dec 17, 2011
*
*/
class TradingOffice extends WareHolding implements ITradingOffice, IPeriodicalUpdate {
/**
* Maximal capacity of the trading office in barrels
*/
private static final int MAX_CAPACITY = 500;
/**
* Reference to the player
*/
private final IPlayer player;
/** Reference to the city the trading office is located in */
private final ICity city;
/** Value of the building (building costs */
private final int baseValue;
/** Weapons storage */
private final IWeaponStorage weapons;
private final IStorage storage;
private IBalanceSheet lastWeek;
private IBalanceSheet currentWeek;
public TradingOffice(IPlayer player, ICity city, int value){
this.player=player;
this.city = city;
this.baseValue = value;
this.weapons = new WeaponStorage();
this.storage = new Storage(player, city);
lastWeek = new BalanceSheet(city, player);
currentWeek = new BalanceSheet((BalanceSheet) lastWeek);
currentWeek.startUpdate();
new PeriodicalTimeUpdater(EUpdateIntervalRegistration.WEEK, this);
}
@Override
public IPlayer getOwner() {
return player;
}
@Override
public int getCapacity() {
return MAX_CAPACITY; // TODO consider additional storage
}
@Override
public int getStored() {
int totalAmount = 0;
EWare[] wares = EWare.values();
for (EWare ware : wares) {
AmountablePrice amount = getWare(ware);
if (amount!=null){
totalAmount += amount.getAmount()*ware.getSizeAsBarrels();
}
}
return totalAmount;
}
@Override
public boolean hasWeapons() {
return weapons.hasWeapons();
}
/**
/**
* {@inheritDoc}
* This method is thread save.
*/
public int move(IWeapon weapon, int amount) {
synchronized (weapon) { // There is still a problem with networked solution where the model of the city is replicated.
return weapons.update(weapon, amount);
}
}
/**
* Compute the average price for ware that is to be purchased in the specified
* amount. The price is computed based on the amount that is available in the city.
* @param ware for which the average price is to be computed
* @param amount amount that is bought
* @return
*/
protected int computeAVGPrice(IWare ware, int amount) {
int available = city.getWare(ware).getAmount();
return ware.computeSellPrice(available, amount);
}
/**
* {@inheritDoc}
*/
@Override
public int move(IWare ware, int amount, int avgPrice) {
synchronized (ware) { // There is still a problem with networked solution where the model of the city is replicated.
AmountablePrice amounted = getWare(ware);
if (amount<0 && containsWare(ware) && amounted!=null && -amount>amounted.getAmount()){ // remove more than is available
amount = -amounted.getAmount();
}
if (amount<0 && !containsWare(ware)){
amount = 0;
}
if (!containsWare(ware)){ // If the ware does not exist add it with amount 0
new IllegalStateException("All wares should be initialized, allowed in test").printStackTrace();
}
if (amount>0){ // amount was bought
amounted.add(amount, avgPrice);
} else { // amount sold
amounted.remove(amount);
}
return amount;
}
}
@Override
public IBalanceSheet getBalanceLastWeek() {
return lastWeek;
}
@Override
public IBalanceSheet getCurrentWeek() {
return currentWeek;
}
@Override
public ISteward getSteward() {
// TODO Auto-generated method stub
return null;
}
@Override
public int getPropertyTax() {
// TODO check the values for this, make this dependent on the difficulty
return 5;
}
@Override
public IAutomatedTrading getOfficeTrading() {
// TODO Auto-generated method stub
return null;
}
@Override
public void notify(DateObject date) {
this.currentWeek.startUpdate();
IBalanceSheet newWeek = new BalanceSheet((BalanceSheet) currentWeek);
newWeek.startUpdate();
this.lastWeek = this.currentWeek;
this.currentWeek = newWeek;
}
@Override
public int move(IWare ware, int amount) {
return super.move(ware, amount, player);
}
@Override
public int getValue() {
return baseValue;
}
@Override
public IWeaponStorage getWeaponStorage() {
return weapons;
}
@Override
public IStorage getStorage() {
return storage;
}
}