package ch.sahits.game.openpatrician.model.impl;
import java.util.List;
import ch.sahits.game.openpatrician.model.IBalanceSheet;
import ch.sahits.game.openpatrician.model.IPlayer;
import ch.sahits.game.openpatrician.model.building.IAutomatedTrading;
import ch.sahits.game.openpatrician.model.building.IBuilding;
import ch.sahits.game.openpatrician.model.building.ISteward;
import ch.sahits.game.openpatrician.model.building.IStorage;
import ch.sahits.game.openpatrician.model.building.ITownHouse;
import ch.sahits.game.openpatrician.model.building.ITradingOffice;
import ch.sahits.game.openpatrician.model.building.IWorkShop;
import ch.sahits.game.openpatrician.model.city.ICity;
import ch.sahits.game.openpatrician.model.time.DateObject;
import ch.sahits.game.openpatrician.model.time.EUpdateIntervalRegistration;
import ch.sahits.game.openpatrician.model.time.PeriodicalTimeUpdater;
public class BalanceSheet implements IBalanceSheet {
// private final Calendar start;
private final ICity city;
private final IPlayer player;
private PeriodicalTimeUpdater notifier;
private int rentalIncome;
private int[] rentalIncomeDays;
private int wageCosts;
private int[] wageCostsDays;
private int propertyTaxes;
private int[] propertyTaxesDays;
private int officeTrading;
private int[] officeTradingDays;
private int stewardCosts;
private int[] stewardCostsDays;
private int otherCosts;
private int[] otherCostsDays;
/**
* Initialize a blank sheet
*/
public BalanceSheet(ICity city, IPlayer player) {
super();
this.city = city;
this.player = player;
notifier = null;
this.rentalIncome = 0;
this.rentalIncomeDays = new int[]{0,0,0,0,0,0,0};
this.wageCosts = 0;
this.wageCostsDays = new int[]{0,0,0,0,0,0,0};
this.propertyTaxes = 0;
this.propertyTaxesDays = new int[]{0,0,0,0,0,0,0};
this.officeTrading = 0;
this.officeTradingDays = new int[]{0,0,0,0,0,0,0};
this.stewardCosts = 0;
this.stewardCostsDays = new int[]{0,0,0,0,0,0,0};
this.otherCosts = 0;
this.otherCostsDays = new int[]{0,0,0,0,0,0,0};
}
/**
* Initialize a forcast balance sheet by using the balance sheet of the previous week
* @param prevWeek
*/
public BalanceSheet(BalanceSheet prevWeek){
this.city = prevWeek.city;
this.player = prevWeek.player;
notifier = null;
this.rentalIncome = prevWeek.rentalIncomeDays[6]*7;
this.rentalIncomeDays = new int[]{prevWeek.rentalIncomeDays[6],prevWeek.rentalIncomeDays[6],prevWeek.rentalIncomeDays[6],prevWeek.rentalIncomeDays[6],prevWeek.rentalIncomeDays[6],prevWeek.rentalIncomeDays[6],prevWeek.rentalIncomeDays[6]};
this.wageCosts = prevWeek.wageCostsDays[6]*7;
this.wageCostsDays = new int[]{ prevWeek.wageCostsDays[6], prevWeek.wageCostsDays[6], prevWeek.wageCostsDays[6], prevWeek.wageCostsDays[6], prevWeek.wageCostsDays[6], prevWeek.wageCostsDays[6], prevWeek.wageCostsDays[6]};
this.propertyTaxes = prevWeek.propertyTaxesDays[6]*7;
this.propertyTaxesDays = new int[]{prevWeek.propertyTaxesDays[6],prevWeek.propertyTaxesDays[6],prevWeek.propertyTaxesDays[6],prevWeek.propertyTaxesDays[6],prevWeek.propertyTaxesDays[6],prevWeek.propertyTaxesDays[6],prevWeek.propertyTaxesDays[6]};
this.officeTrading = prevWeek.officeTradingDays[6]*7;
this.officeTradingDays = new int[]{prevWeek.officeTradingDays[6],prevWeek.officeTradingDays[6],prevWeek.officeTradingDays[6],prevWeek.officeTradingDays[6],prevWeek.officeTradingDays[6],prevWeek.officeTradingDays[6],prevWeek.officeTradingDays[6]};
this.stewardCosts = prevWeek.stewardCostsDays[6]*7;
this.stewardCostsDays = new int[]{prevWeek.stewardCostsDays[6],prevWeek.stewardCostsDays[6],prevWeek.stewardCostsDays[6],prevWeek.stewardCostsDays[6],prevWeek.stewardCostsDays[6],prevWeek.stewardCostsDays[6],prevWeek.stewardCostsDays[6]};
this.otherCosts = prevWeek.otherCosts;
this.otherCostsDays = new int[]{prevWeek.otherCosts/7,prevWeek.otherCosts/7,prevWeek.otherCosts/7,prevWeek.otherCosts/7,prevWeek.otherCosts/7,prevWeek.otherCosts/7,prevWeek.otherCosts/7};
}
@Override
public int getRentalIncome() {
return rentalIncome;
}
@Override
public int getWageCosts() {
return wageCosts;
}
@Override
public int getPropertyTaxes() {
return propertyTaxes;
}
@Override
public int getOfficeTrading() {
return officeTrading;
}
@Override
public int getStewardCost() {
return stewardCosts;
}
@Override
public int getOtherCosts() {
return otherCosts;
}
@Override
public void notify(DateObject date) {
ITradingOffice office = player.findTradingOffice(city);
int weekIndex = date.getDayInWeek();
ISteward steward = office.getSteward();
int dailyCost=0;
if (steward!=null){
dailyCost = (int) Math.rint(steward.getSalary()/7.0);
}
for (int i = weekIndex; i<stewardCostsDays.length;i++){
this.stewardCostsDays[i] = dailyCost;
}
int sum = 0;
for (int cost : stewardCostsDays) {
sum += cost;
}
this.stewardCosts=sum;
List<IBuilding> buildings = player.findBuildings(city,ITownHouse.class);
dailyCost=0;
for (IBuilding building : buildings) {
dailyCost += ((ITownHouse)building).computeRentalIncome();
}
for (int i = weekIndex; i<rentalIncomeDays.length;i++){
this.rentalIncomeDays[i] = dailyCost;
}
sum = 0;
for (int cost : rentalIncomeDays) {
sum += cost;
}
this.rentalIncome=sum;
buildings = player.findBuildings(city);
dailyCost=0;
for (IBuilding building : buildings) {
dailyCost += building.getPropertyTax();
}
for (int i = weekIndex; i<propertyTaxesDays.length;i++){
this.propertyTaxesDays[i] = dailyCost;
}
sum = 0;
for (int cost : propertyTaxesDays) {
sum += cost;
}
this.propertyTaxes=sum;
buildings = player.findBuildings(city,IWorkShop.class);
IStorage storage = office.getStorage();
dailyCost=0;
for (IBuilding building : buildings) {
dailyCost += (int)Math.rint(((IWorkShop)building).getSalaryPerWorker()/7.0);
}
for (int i = weekIndex; i<wageCostsDays.length;i++){
this.wageCostsDays[i] = dailyCost+storage.getGuardCostsPerDay();
}
sum = 0;
for (int cost : wageCostsDays) {
sum += cost;
}
this.wageCosts=sum;
IAutomatedTrading automaticTrading = office.getOfficeTrading();
if (automaticTrading!=null){
// TODO implement this when implementing office traiding
} else {
for (int i = weekIndex; i<officeTradingDays.length;i++){
this.officeTradingDays[i] = 0;
}
}
sum = 0;
for (int cost : officeTradingDays) {
sum += cost;
}
this.officeTrading=sum;
// TODO update other expences
for (int i = weekIndex; i<otherCostsDays.length;i++){
this.otherCostsDays[i] = storage.getCostsPerDay();
}
}
@Override
public void stopUpdate() {
notifier.stop();
notifier = null;
}
@Override
public void startUpdate() {
notifier = new PeriodicalTimeUpdater(EUpdateIntervalRegistration.DAY, this);
}
}