package com.bernard.greposimu.model;

import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.Set;

import com.bernard.greposimu.model.game.units.Hero;
import com.bernard.greposimu.model.game.units.Unit;

public class OffContext {
	
	Map<Unit, Integer> units;
	
	Hero hero;
	int heroLevel;
	
	int luck;
	int moral;
	
	// RESEARCHES
	boolean divineSelection= false, phalanx = false, ram=false, combatExperience=false;
	
	// COUNSELLORS
	boolean commander= false;
	boolean priest = false;
	boolean captain = false;
	
	// EFFECTS
	// PC x2
	boolean acumen = false;
	// PC x4
	boolean divineSenses= false;
	// Attq +10%, Def -10%
	boolean myrmidionAttack= false;
	// Attq +10%
	boolean attackBoost= false;
	// Attq -10%
	boolean attackPenalty= false;
	// Attq +10%
	boolean longtermAttackBoost = false;
	//XXX implement this :/
	boolean luxuriousResidence = false;
	// BF attq +10%
	boolean attack_ship_attack_boost_small = false;
	// BF attq +20%
	boolean attack_ship_attack_boost_medium = false;
	// BF attq +30%
	boolean attack_ship_attack_boost_large = false;
	// PC +50%
	boolean assassinsAcumen= false;
	// Attq +10%
	boolean rareAttackBoost= false;
	// Attq +20%
	boolean epicAttackBoost= false;
	// Attq +5%*level
	int olympicSwordGrepolympiaSummerLevel = 0;
	// PC+10%*level
	int olympicSensesGrepolympiaSummerLevel = 0;
	// +50% PC
	boolean missionsPower4= false;
	// PC+50% (sauf BC, transport)
	boolean divineBattleStrategyRare= false;
	// PC+100% (sauf BC, transport)
	boolean divineBattleStrategyEpic= false;
	// PC+50% against naval (sauf BC,transports)
	boolean navalBattleStrategyRare= false;
	// PC+100% against naval (sauf BC, transport)
	boolean navalBattleStrategyEpic= false;
	// PC+50% against terrestres
	boolean landBattleStrategyRare= false;
	// PC+100% against terrestre
	boolean landBattleStrategyEpic= false;
	// Attq +1%*level
	int aresRageLevel = 0;
		
	// SPELLS
	// Add one sparte for every 25 fury used
	int aresArmyFurySpent = 0;
	// Attq +5% +(1% for each 200 fury spent)
	// PC + 1% for each 100 fury spent
	int bloodlustFurySpent = 0;
	// Attq naval +10%
	boolean fairWind = false;
	// Attq -10%
	boolean desire = false;
	// Terr + aer +10% attq
	boolean strengthOfHeroes = false;
	// Attq distance +15%
	boolean effortOfTheHuntress = false;
	
	boolean strategyBreach = false;
	boolean allianceModifier = false;
	
	
	public OffContext(Map<Unit, Integer> units, Hero hero, int heroLevel, int luck, int moral,
			Set<String> powers, int olympicSwordGrepolympiaSummerLevel, int olympicSensesGrepolympiaSummerLevel,
			int aresRageLevel, int aresArmyFurySpent, int bloodlustFurySpent, Set<String> researches, Set<String> counsellors,
			boolean strategyBreach, boolean allianceModifier) {
		this.units = units;
		this.hero = hero;
		this.heroLevel = heroLevel;
		this.luck = luck;
		this.moral = moral;
		
		if(powers.contains("acumen"))this.acumen = true;
		if(powers.contains("divine_senses"))this.divineSenses = true;
		if(powers.contains("myrmidion_attack"))this.myrmidionAttack = true;
		if(powers.contains("attack_boost"))this.attackBoost = true;
		if(powers.contains("attack_penalty"))this.attackPenalty = true;
		if(powers.contains("longterm_attack_boost"))this.longtermAttackBoost = true;
		if(powers.contains("attack_ship_attack_boost_small"))this.attack_ship_attack_boost_small = true;
		if(powers.contains("attack_ship_attack_boost_medium"))this.attack_ship_attack_boost_medium = true;
		if(powers.contains("attack_ship_attack_boost_large"))this.attack_ship_attack_boost_large = true;
		if(powers.contains("assassins_acumen"))this.assassinsAcumen = true;
		if(powers.contains("rare_attack_boost"))this.rareAttackBoost = true;
		if(powers.contains("epic_attack_boost"))this.epicAttackBoost = true;
		if(powers.contains("olympic_sword"))this.olympicSwordGrepolympiaSummerLevel = olympicSwordGrepolympiaSummerLevel;
		if(powers.contains("olympic_senses"))this.olympicSensesGrepolympiaSummerLevel = olympicSensesGrepolympiaSummerLevel;
		if(powers.contains("missions_power_4"))this.missionsPower4 = true;
		if(powers.contains("divine_battle_strategy_rare"))this.divineBattleStrategyRare = true;
		if(powers.contains("divine_battle_strategy_epic"))this.divineBattleStrategyEpic = true;
		if(powers.contains("naval_battle_strategy_rare"))this.navalBattleStrategyRare = true;
		if(powers.contains("naval_battle_strategy_epic"))this.navalBattleStrategyEpic = true;
		if(powers.contains("land_battle_strategy_rare"))this.landBattleStrategyRare = true;
		if(powers.contains("land_battle_strategy_epic"))this.landBattleStrategyEpic = true;
		if(powers.contains("ares_rage"))this.aresRageLevel = aresRageLevel;
		if(powers.contains("ares_army"))this.aresArmyFurySpent = aresArmyFurySpent;
		if(powers.contains("bloodlust"))this.bloodlustFurySpent = bloodlustFurySpent;
		if(powers.contains("fair_wind"))this.fairWind = true;
		if(powers.contains("desire"))this.desire = true;
		if(powers.contains("effort_of_the_huntress"))this.effortOfTheHuntress = true;
		if(powers.contains("strength_of_heroes"))this.strengthOfHeroes = true;
		if(researches.contains("divine_selection"))this.divineSelection = true;
		if(researches.contains("phalanx"))this.phalanx = true;
		if(researches.contains("ram"))this.ram = true;
		if(researches.contains("combat_experience"))this.combatExperience = true;
		if(counsellors.contains("commander"))this.commander = true;
		if(counsellors.contains("priest"))this.priest = true;
		if(counsellors.contains("captain"))this.captain = true;
		this.strategyBreach = strategyBreach;
		this.allianceModifier = allianceModifier;
	}
	
	public int unitCount(Unit u) {
		return Optional.ofNullable(units.getOrDefault(u,0)).orElse(0);
	}
	public Map<Unit, Integer> getUnits() {
		return units;
	}
	public Hero getHero() {
		return hero;
	}
	public int getHeroLevel() {
		return heroLevel;
	}
	public int getLuck() {
		return luck;
	}
	public int getMorale() {
		return moral;
	}
	public boolean hasDivineSelection() {
		return divineSelection;
	}
	public boolean hasPhalanx() {
		return phalanx;
	}
	public boolean hasRam() {
		return ram;
	}
	public boolean hasCombatExperience() {
		return combatExperience;
	}
	public boolean hasCommander() {
		return commander;
	}
	public boolean hasPriest() {
		return priest;
	}
	public boolean hasCaptain() {
		return captain;
	}
	public boolean hasAcumen() {
		return acumen;
	}
	public boolean hasDivineSenses() {
		return divineSenses;
	}
	public boolean hasMyrmidionAttack() {
		return myrmidionAttack;
	}
	public boolean hasAttackBoost() {
		return attackBoost;
	}
	public boolean hasAttackPenalty() {
		return attackPenalty;
	}
	public boolean hasLongtermAttackBoost() {
		return longtermAttackBoost;
	}
	public boolean hasLuxurious_residence() {
		return luxuriousResidence;
	}
	public boolean hasAttack_ship_attack_boost_small() {
		return attack_ship_attack_boost_small;
	}
	public boolean hasAttack_ship_attack_boost_medium() {
		return attack_ship_attack_boost_medium;
	}
	public boolean hasAttack_ship_attack_boost_large() {
		return attack_ship_attack_boost_large;
	}
	public boolean hasAssassinsAcumen() {
		return assassinsAcumen;
	}
	public boolean hasRareAttackBoost() {
		return rareAttackBoost;
	}
	public boolean hasEpicAttackBoost() {
		return epicAttackBoost;
	}
	public int getOlympicSwordGrepolympiaSummerLevel() {
		return olympicSwordGrepolympiaSummerLevel;
	}
	public int getOlympicSensesGrepolympiaSummerLevel() {
		return olympicSensesGrepolympiaSummerLevel;
	}
	public boolean hasMhassionsPower4() {
		return missionsPower4;
	}
	public boolean hasDivineBattleStrategyRare() {
		return divineBattleStrategyRare;
	}
	public boolean hasDivineBattleStrategyEpic() {
		return divineBattleStrategyEpic;
	}
	public boolean hasNavalBattleStrategyRare() {
		return navalBattleStrategyRare;
	}
	public boolean hasNavalBattleStrategyEpic() {
		return navalBattleStrategyEpic;
	}
	public boolean hasLandBattleStrategyRare() {
		return landBattleStrategyRare;
	}
	public boolean hasLandBattleStrategyEpic() {
		return landBattleStrategyEpic;
	}
	public int getAresRageLevel() {
		return aresRageLevel;
	}
	public int getAresArmyFurySpent() {
		return aresArmyFurySpent;
	}
	public int getBloodlust() {
		return bloodlustFurySpent;
	}
	public boolean hasFairWind() {
		return fairWind;
	}
	public boolean hasDesire() {
		return desire;
	}
	public boolean hasStrengthOfHeroes() {
		return strengthOfHeroes;
	}
	public boolean hasEffortOfTheHuntress() {
		return effortOfTheHuntress;
	}
	public boolean hasStrategyBreach() {
		return strategyBreach;
	}
	public boolean hasAllianceModifier() {
		return allianceModifier;
	}
	
	public static final List<String> POWERS = List.of("acumen", "divine_senses", "myrmidion_attack", "attack_boost",
			"attack_penalty", "longterm_attack_boost", "attack_ship_attack_boost_small",
			"attack_ship_attack_boost_medium", "attack_ship_attack_boost_large", "assassins_acumen",
			"rare_attack_boost", "epic_attack_boost", "olympic_sword", "olympic_senses", "missions_power_4",
			"divine_battle_strategy_rare", "divine_battle_strategy_epic", "naval_battle_strategy_rare",
			"naval_battle_strategy_epic", "land_battle_strategy_rare", "land_battle_strategy_epic", "ares_rage",
			"ares_army", "bloodlust", "fair_wind", "desire", "effort_of_the_huntress", "strength_of_heroes");
	public static final List<String> RESEARCHES = List.of("divine_selection","phalanx","ram","combat_experience");
	public static final List<String> COUNSELLORS = List.of("priest","commander","captain");
	
}
