:: EconomyJS [script]

window.LivingRule = Object.freeze({LUXURIOUS: 'luxurious', NORMAL: 'normal', SPARSE: 'sparse'});
window.Job = Object.freeze({
	DAIRY: 'work in the dairy', MASTER_SUITE: 'serve in the master suite', CONCUBINE: 'be your concubine',
	BABY_FACTORY: 'labor in the production line', BROTHEL: 'work in the brothel', ARCADE: 'be confined in the arcade',
	SERVANT: 'work as a servant', SERVER: 'be a servant', CLUB: 'serve in the club'});
window.PersonalAttention = Object.freeze({TRADE: 'trading', WAR: 'warfare', SLAVEING: 'slaving', ENGINEERING: 'engineering', MEDICINE: 'medicine', MAID: 'upkeep'});

window.getCost = function(array) {
	var rulesCost = State.variables.rulesCost;
	var foodCost = State.variables.foodCost;
	var drugsCost = State.variables.drugsCost;
	var facilityCost = State.variables.facilityCost;
	var economy = State.variables.economy;
	var brothel = State.variables.brothel;
	var arcade = State.variables.arcade;
	var club = State.variables.club;
	var dairy = State.variables.dairy;
	var servantsQuarters = State.variables.servantsQuarters;
	var incubator = State.variables.incubator;
	var mercCosts = State.variables.mercenaries * 2000;
	var policyCost = State.variables.policyCost;
	var costs = (State.variables.brothel * facilityCost)
		+ (State.variables.arcade * facilityCost * 0.5)
		+ (State.variables.club * facilityCost)
		+ (State.variables.dairy * facilityCost)
		+ (State.variables.incubator * facilityCost * 10);
		
	//facility expenses
	costs += (0.1 * State.variables.brothelUpgradeDrugs * brothel * facilityCost)
	+ (0.2 * State.variables.arcadeUpgradeInjectors * arcade * facilityCost)
	+ (0.2 * State.variables.arcadeUpgradeCollectors * arcade * facilityCost)
	+ (0.2 * State.variables.clubUpgradePDAs * club * facilityCost)
	+ (0.2 * State.variables.dairyFeedersUpgrade * dairy * facilityCost)
	+ (0.1 * State.variables.dairyPregUpgrade * dairy * facilityCost)
	+ (0.2 * State.variables.dairyStimulatorsUpgrade * facilityCost)
	+ (0.2 * State.variables.servantsQuartersUpgradeMonitoring *  servantsQuarters * facilityCost)
	+ (0.2 * State.variables.incubatorUpgradeWeight * incubator * facilityCost)
	+ (0.2 * State.variables.incubatorUpgradeMuscles * incubator * facilityCost)
	+ (0.2 * State.variables.incubatorUpgradeReproduction * incubator * facilityCost)
	+ (0.2 * State.variables.incubatorUpgradeGrowthStims * incubator * facilityCost)
	+ (0.5 * State.variables.incubatorUpgradeSpeed * incubator * facilityCost);
	
	if(dairy > 0) {
		costs += ((State.variables.bioreactorsXY + State.variables.bioreactorsXX + State.variables.bioreactorsHerm + State.variables.bioreactorsBarren) * 100);
	}
	if(brothel > 0) {
		costs += State.variables.brothelAdsSpending;
	}
	if(club > 0) {
		costs += State.variables.clubAdsSpending;
	}
	if(incubator > 0) {
		costs += ((State.variables.incubatorWeightSetting + State.variables.incubatorMusclesSetting + State.variables.incubatorReproductionSetting + State.variables.incubatorGrowthStimsSetting) * 500);
	}
	if(State.variables.masterSuitePregnancySlaveLuxuries === 1) {
		costs += 500;
	}
	if(State.variables.masterSuitePregnancyFertilitySupplements === 1) {
		costs += 1000;
	}
	
	//security expansion
	if(State.variables.secExp == 1) {
		if(State.variables.edictsUpkeep > 0) {
			costs += State.variables.edictsUpkeep;
		}
		if(State.variables.SFSupportUpkeep > 0) {
			costs += State.variables.SFSupportUpkeep;
		}
		if(State.variables.propHub > 0) {
			costs += State.variables.propHubUpkeep;
		}
		if(State.variables.secHQ > 0) {
			costs += State.variables.secHQUpkeep + 20 * state.variables.secHelots;
		}
		if(State.variables.secBarracks > 0) {
			costs += State.variables.secBarracksUpkeep;
		}
		if (State.variables.militiaUnits != null) {
			for (var i = 0; i < State.variables.militiaUnits.length; i++) {
				if( !(State.variables.militiaUnits[i] === null) ){
					costs += State.variables.militiaUnits[i].troops * State.variables.soldierUpkeep;
				}
			}
		}
		if (State.variables.slaveUnits != null) {
			for (var i = 0; i < State.variables.slaveUnits.length; i++) {
				if( !( State.variables.slaveUnits[i] === null) ){
					costs +=  State.variables.slaveUnits[i].troops * State.variables.soldierUpkeep * 0.5;
				}
			}
		}
		if (State.variables.mercUnits != null) {
			for (var i = 0; i < State.variables.mercUnits.length; i++) {
				if( !(State.variables.mercUnits[i] === null) ){
					costs += State.variables.mercUnits[i].troops * State.variables.soldierUpkeep * 1.5;
				}
			}
		}
	}
	
	//general arcology costs
	costs += (State.variables.girls * (250 + (economy * 500)));
	
	if(State.variables.arcologies[0].FSRepopulationFocusLaw === 1 && State.variables.PC.pregKnown == 1) {
		costs -= 500;
	}
	
	costs += State.variables.citizenOrphanageTotal * 100;
	costs += State.variables.privateOrphanageTotal * 500;
	if(State.variables.breederOrphanageTotal > 0) {
		costs += 50;
	}
	
	if(State.variables.peacekeepers !== 0 && State.variables.peacekeepers.undermining !== 0) {
		costs += State.variables.peacekeepers.undermining;
	}
	
	if(State.variables.mercenaries > 0) {
		if(State.variables.barracks) {
			mercCosts *= 0.5;
		}
		if((State.variables.PC.warfare >= 100) || (State.variables.PC.career === 'arcology owner')) {
			mercCosts *= 0.5;
		}
		costs += mercCosts;
	}

	costs += State.variables.FSSpending;
	
	//slave expenses
	for (var slave of array) {
		costs += getSlaveCost(slave);
		if(slave.assignment === Job.SERVANT || slave.assignment === Job.SERVER) {
			if(slave.trust < -20) {
				costs -= rulesCost * 4;
			} else if(slave.devotion < -20) {
				costs -= rulesCost * 2;
			} else if(slave.devotion <= 20) {
				costs -= rulesCost * 3;
			} else if(slave.devotion <= 50) {
				costs -= rulesCost * 4;
			} else {
				costs -= rulesCost * 5;
			}
			if(slave.fetish === 'submissive') {
				costs -= rulesCost;
			} else if(slave.fetish === 'dom') {
				costs += rulesCost;
			}
			if(slave.relationship < -1) {
				costs -= rulesCost;
			}
			if(slave.energy < 20) {
				costs -= rulesCost;
			} else if(slave.energy < 40) {
				costs -= rulesCost / 2;
			}
			if(slave.lactation > 0) {
				costs -= 25;
			}
		}
	}
	
	// policy and other expenses
	if(State.variables.Recruiter !== 0) {
		costs += 250;
	}
	if(State.variables.TSS.schoolPresent === 1) {
		costs += 1000;
	}
	if(State.variables.GRI.schoolPresent === 1) {
		costs += 1000;
	}
	if(State.variables.SCP.schoolPresent === 1) {
		costs += 1000;
	}
	if(State.variables.LDE.schoolPresent === 1) {
		costs += 1000;
	}
	if(State.variables.TGA.schoolPresent === 1) {
		costs += 1000;
	}
	if(State.variables.TCR.schoolPresent === 1) {
		costs += 1000;
	}
	if((State.variables.TFS.schoolPresent === 1) && ((State.variables.PC.dick === 0) || (State.variables.PC.vagina === 0) || (State.variables.PC.boobs === 0))) {
		costs += 1000;
	}
	if(State.variables.TSS.subsidize !== 0) {
		costs += 1000;
	}
	if(State.variables.GRI.subsidize !== 0) {
		costs += 1000;
	}
	if(State.variables.SCP.subsidize !== 0) {
		costs += 1000;
	}
	if(State.variables.LDE.subsidize !== 0) {
		costs += 1000;
	}
	if(State.variables.TGA.subsidize !== 0) {
		costs += 1000;
	}
	if(State.variables.TCR.subsidize !== 0) {
		costs += 1000;
	}
	if(State.variables.TFS.subsidize !== 0) {
		costs += 1000;
	}

	if(State.variables.alwaysSubsidizeGrowth === 1) {
		costs += policyCost;
	}
	if(State.variables.alwaysSubsidizeRep === 1) {
		costs += policyCost;
	}
	if(State.variables.RegularParties === 1) {
		costs += policyCost;
	}

	if(State.variables.ProImmigrationCash === 1) {
		costs += policyCost;
	}
	if(State.variables.AntiEnslavementCash === 1) {
		costs += policyCost;
	}

	if(State.variables.CoursingAssociation === 1) {
		costs += 1000;
	}

	if(State.variables.personalAttention === PersonalAttention.TRADE) {
		costs += 10000;
	} else if(State.variables.personalAttention === PersonalAttention.WAR) {
		costs += 10000;
	} else if(State.variables.personalAttention === PersonalAttention.SLAVING) {
		costs += 10000;
	} else if(State.variables.personalAttention === PersonalAttention.ENGINEERING) {
		costs += 10000;
	} else if(State.variables.personalAttention === PersonalAttention.MEDICINE) {
		costs += 10000;
	}

	if(State.variables.cyberMod !== 0 && State.variables.researchLab.built === 'true') {
		costs += ((100 * State.variables.researchLab.maxSpace) + (300 * State.variables.researchLab.hired) + (100 * State.variables.researchLab.hired));
	}

	//player expenses

	if(State.variables.PC.preg === -1) {
		costs += 25;
	} else if(State.variables.PC.fertDrugs === 1) {
		costs += 50;
	} else if(State.variables.PC.preg >= 16) {
		costs += 100;
	}

	if(State.variables.PC.career === 'servant') {
		if(State.variables.personalAttention === PersonalAttention.MAID) {
			if(State.variables.PC.belly >= 5000) {
				costs *= 0.80;
			} else {
				costs *= 0.75;
			}
		} else {
			costs *= 0.9;
		}
	}

	
	// clean up
	if(costs < 0) {
		costs = 0;
	} else {
		costs = Math.trunc(costs);
	}
	
	return costs;
}
	
window.getSlaveCost = function(s) {
	if(!s) { return 0; }
	// Data duplicated from Cost Report
	var cost = 0;
	var rulesCost = State.variables.rulesCost;
	var foodCost = State.variables.foodCost;
	var drugsCost = State.variables.drugsCost;
	
	// Living expenses
	if((s.assignment !== Job.DAIRY || State.variables.dairyRestraintsSetting < 2) && (s.assignment !== Job.ARCADE)) {
		if(s.livingRules === LivingRule.LUXURIOUS) {
			cost += rulesCost * (s.relationship >= 4 ? 3 : 4);
		} else if(s.livingRules == LivingRule.NORMAL) {
			cost += rulesCost * 2;
		} else {
			cost += rulesCost;
		}
	} else {
		cost += rulesCost * .75;
	}
		
	
	// Food
	cost += foodCost * 4;
	switch(s.diet) {
		case 'fattening': case 'muscle building':
			cost += foodCost;
			break;
		case 'restricted': case 'slimming':
			cost -= foodCost;
			break;
	}
	if(s.weight > 130) {
		cost += foodCost * 2;
	} else if(s.weight > 50) {
		cost += foodCost;
	} else if(s.weight < -50) {
		cost -= foodCost;
	}
	if(s.drugs === 'appetite suppressors') {
		cost -= foodCost;
	}
	if(s.lactation > 0) {
		cost += foodCost * s.lactation * (1 + Math.trunc(s.boobs/10000));
	}
	if(s.preg > 5) {
		if(s.assignment === Job.DAIRY && State.variables.dairyFeedersSetting > 0) {
			// Extra feeding costs to support pregnancy are covered by dairy feeders.
			// TODO: Include them here anyway?
		} else if((s.assignment === Job.MASTER_SUITE || s.assignment === Job.CONCUBINE)
			&& State.variables.masterSuiteUpgradePregnancy === 1) {
			// Extra feeding costs to support pregnancy are covered by master suite luxuries.
			// TODO: Include them here anyway?
		} else {
			cost += foodCost * s.pregType * (s.pregControl === 'speed up' ? 3 : 1);
		}
	}
	if(s.diet === 'XX' || s.diet === 'XY') {
		cost += 25;
	} else if(s.diet === 'cleansing') {
		cost += 50;
	} else if(s.diet === 'XXY') {
		cost += 75;
	}
	
	// Accessibility costs
	if(State.variables.boobAccessibility !== 1 && s.boobs > 20000
		&& (s.assignment != Job.DAIRY || State.variables.dairyRestraintsSetting < 2) && (s.assignment != Job.ARCADE)) {
		cost += 50;
	}
	if(State.variables.pregAccessibility !== 1
		&& ((s.belly >= 60000) || (s.preg > 20 && s.pregType >= 10) || (s.preg > 10 && s.pregType >= 20) || s.bellyImplant >= 10000)
		&& s.assignment != Job.BABY_FACTORY && (s.assignment != Job.DAIRY || State.variables.dairyRestraintsSetting < 2) && (s.assignment != Job.ARCADE)) {
		cost += 100;
	}
	if(State.variables.dickAccessibility != 1 && s.dick > 45 && (s.assignment != Job.DAIRY || State.variables.dairyRestraintsSetting < 2) && (s.assignment != Job.ARCADE)) {
		cost += 50;
	}
	if(State.variables.ballsAccessibility != 1 && s.balls > 90 && (s.assignment != Job.DAIRY || State.variables.dairyRestraintsSetting < 2) && (s.assignment != Job.ARCADE)) {
		cost += 50;
	}
	if(State.variables.buttAccessibility != 1 && s.butt > 15 && (s.assignment != Job.DAIRY || State.variables.dairyRestraintsSetting < 2) && (s.assignment != Job.ARCADE)) {
		cost += 50;
	}
	if(!canSee(s) && (s.assignment != Job.DAIRY || State.variables.dairyRestraintsSetting < 2) && (s.assignment != Job.ARCADE)) {
		cost += 50;
	} else if(s.eyes <= -1 &&	s.eyewear !== 'corrective glasses' && s.eyewear !== 'corrective contacts') {
		cost += 25;
	} else if(s.eyewear === 'blurring glasses' || s.eyewear === 'blurring contacts') {
		cost += 25;
	}
	if((s.assignment !== Job.DAIRY || State.variables.dairyRestraintsSetting < 2) && (s.assignment !== Job.ARCADE)) {
		if(s.amp !== 0) {
			if(s.amp === 1) {
				cost += rulesCost;
			} else {
				cost += rulesCost / 2;
			}
		} else if(!canWalk(s)) {
			cost += rulesCost;
		}
	}
	
	// Maintenance
	if(s.boobs > 10000 && s.boobsImplantType === 1) {
		cost += 50;
	}
	if(s.butt > 10 && s.buttImplantType === 1) {
		cost += 50;
	}
	if((s.assignment !== Job.DAIRY || State.variables.dairyRestraintsSetting < 2) && (s.assignment !== Job.ARCADE)) {
		if(s.preg > 35 && State.variables.universalRulesBirthing === 1) {
			cost += 50;
		}
	}

	// Retirement account
	if(State.variables.CitizenRetirement === 1) {
		cost += 250;
	}
	
	// Enemas
	if(s.inflation === 3) {
		switch(s.inflationType) {
		case 'water':
			cost += 100;
			break;
		case 'food':
			cost += (foodCost * 4);
			break;
		case 'curative': case 'aphrodisiac': case 'tightener':
			cost += (100 + (drugsCost * 2));
			break;
		}
	} else if(s.inflation === 2) {
		switch(s.inflationType) {
		case 'water':
			cost += 50;
			break;
		case 'food':
			cost += (foodCost * 2);
			break;
		case 'curative': case 'aphrodisiac': case 'tightener':
			cost += (50 + (drugsCost * 2));
			break;
		}
	} else if(s.inflation === 1) {
		switch(s.inflationType) {
		case 'water':
			cost += 25;
			break;
		case 'food':
			cost += (foodCost);
			break;
		case 'curative': case 'aphrodisiac': case 'tightener':
			cost += (25 + (drugsCost * 2));
			break;
		}
	}

	// Drugs
	switch(s.drugs) {
	case 'anti-aging cream':
		cost += drugsCost * 10;
		break;
	case 'female hormone injections': case 'male hormone injections': case 'intensive breast injections':
	case 'intensive butt injections': case 'intensive penis enhancement': case 'intensive testicle enhancement':
	case 'intensive lip injections': case 'hyper breast injections': case 'hyper butt injections':
	case 'hyper penis enhancement': case 'hyper testicle enhancement': case 'hyper lip injections':
	case 'growth stimulants':
		cost += drugsCost * 5;
		break;
	case 'sag-B-gone':
		cost += drugsCost * .1;
		break;
	case 'no drugs': case 'none':
		break;
	default:
		cost += drugsCost * 2;
		break;
	}
	if(s.curatives > 0 && s.assignmentVisible === 1) {
		cost += drugsCost * s.curatives;
	}
	if(s.aphrodisiacs !== 0) {
		cost += drugsCost * Math.abs(s.aphrodisiacs);
	}
	if(s.hormones !== 0) {
		cost += (drugsCost * Math.abs(s.hormones) * 0.5);
	}
	if(s.preg === -1 && isFertile(s)) {
		cost += (drugsCost * 0.5);
	}
	
	// Promotion costs
	if(State.variables.studio === 1) {
		if(s.pornFameSpending > 0) {
			cost += s.pornFameSpending;
		}
	}
	
	if(isNaN(cost)) {
		throw new Error('Cost calculation for slave ' + s.slaveName + ' (' + s.ID + ') failed.');
	}
	return cost;
};

window.getSlaveStatisticData = function(s, facility) {
	if(!s || !facility) {
		// Base data, even without facility
		return {
			ID: s.ID, slaveName: s.slaveName, customLabel: s.customLabel,
			income: 0, adsIncome: 0, rep: 0, cost: getSlaveCost(s),
			customers: 0 /* brothel, club, ... */
		};
	}
	
	if(!facility.income) {
		facility.income = new Map();
	}
	
	if(facility.income.has(s.ID)) {
		return facility.income.get(s.ID);
	} else {
		var data = {
			ID: s.ID, slaveName: s.slaveName, customLabel: s.customLabel,
			income: 0, adsIncome: 0, rep: 0, cost: getSlaveCost(s),
			customers: 0 /* brothel, club, ... */
		};
		facility.income.set(s.ID, data);
		return data;
	}
};

window.initFacilityStatistics = function(facility) {
	facility = facility || {};
	facility.adsIncome = 0;
	facility.maintenance = 0;
	facility.totalIncome = 0;
	facility.totalExpenses = 0;
	facility.profit = 0;
	facility.income = new Map();
	return facility;
}

Number.prototype.toFixedHTML = function() {
	return Number.prototype.toFixed.apply(this, arguments).replace(/\.0+$/, '<span style="opacity: 0.3">$&</span>');
}