using Specialisations;
using System;
using System.Collections.Generic;
using UnityEngine;

public class GameSpecialisations
{
    public static bool[] hasAuftragstaktik;

    public static bool[] hasProximityFuse;

    public static bool[] hasFieldMedics;

    public static bool[] hasBanzaiCharge;

    public static bool[] hasBushidoCode;

    public static bool[] hasForcedLabour;

    public static bool[] hasTokyoExpress;

    public static bool[] hasRadarI;

    public static bool[] hasRadarII;

    public static bool[] hasDamageControl;

    public static bool[] hasDropTank;

    public static bool[] hasUnrestrictedSubWar;

    public static bool[] hasWolfPack;

    public static bool[] hasLibertyShips;

    public static bool[] hasTorpImprovements;

    public static bool[] hasMetalDetector;

    public static bool[] hasBomberStream;

    public static bool[] hasHobartsFunnies;

    public static bool[] hasGoliath;

    public static bool[] hasPakFront;

    public static bool[] hasPanzerKeil;

    public static bool[] hasWireBomb;

    public static bool[] hasESeries;

    public static bool[] hasPanzerLehr;

    public static bool[] hasInfrared;

    public static bool[] hasMolotovRibbentropPact;

    public static bool[] hasGreatPatrioticWar;

    public static bool[] hasSiberianReserves;

    public static bool[] hasArcticConvoy;

    public static bool[] hasLendLeaseUssr;

    public static bool[] hasOrderNo227;

    public static bool[] hasShockArmy;

    public static bool[] hasGuardsArmy;

    public static bool[] hasATClusterBomb;

    public static bool[] hasSovFighterTactics;

    public static bool[] hasAirOffensive;

    public static bool[] hasDeepOperations;

    public static bool[] hasRedTails;

    public static UnitType infraredLight;

    public GameSpecialisations()
    {
    }

    public static void AddLegacySpecialisation(int oldSpecId, Alliance alliance)
    {
        SpecialisationType specialisationTypeByName = null;
        if (oldSpecId == 0)
        {
            specialisationTypeByName = GameSpecialisations.GetSpecialisationTypeByName("banzai_charge");
        }
        else if (oldSpecId == 1)
        {
            specialisationTypeByName = GameSpecialisations.GetSpecialisationTypeByName("bushido_code");
        }
        else if (oldSpecId == 2)
        {
            specialisationTypeByName = GameSpecialisations.GetSpecialisationTypeByName("forced_labour");
        }
        else if (oldSpecId == 3)
        {
            specialisationTypeByName = GameSpecialisations.GetSpecialisationTypeByName("tokyo_express");
        }
        else if (oldSpecId == 4)
        {
            specialisationTypeByName = GameSpecialisations.GetSpecialisationTypeByName("super_sensha");
            if (App.mode != App.modes.editor)
            {
            Label0:
                foreach (Faction faction in alliance.factions)
                {
                    foreach (Unit unit in faction.state.units)
                    {
                        if (!(unit.state.unitType.name == "type100_o-i") || !unit.IsAlive())
                        {
                            continue;
                        }
                        faction.AddResources(unit.state.unitType.stats.costs[0], App.game.actualGameState);
                        goto Label0;
                    }
                }
            }
        }
        else if (oldSpecId == 5)
        {
            specialisationTypeByName = GameSpecialisations.GetSpecialisationTypeByName("advanced_aeronautics");
        }
        else if (oldSpecId == 6)
        {
            specialisationTypeByName = GameSpecialisations.GetSpecialisationTypeByName("kamikaze");
        }
        else if (oldSpecId == 7)
        {
            specialisationTypeByName = GameSpecialisations.GetSpecialisationTypeByName("gruppe_monsun");
        }
        else if (oldSpecId == 8)
        {
            specialisationTypeByName = GameSpecialisations.GetSpecialisationTypeByName("yanagi_missions");
        }
        else if (oldSpecId == 9)
        {
            specialisationTypeByName = GameSpecialisations.GetSpecialisationTypeByName("build_bunkers");
        }
        else if (oldSpecId == 10)
        {
            specialisationTypeByName = GameSpecialisations.GetSpecialisationTypeByName("field_medics");
        }
        else if (oldSpecId == 11)
        {
            specialisationTypeByName = GameSpecialisations.GetSpecialisationTypeByName("landing_craft_infantry");
        }
        else if (oldSpecId == 12)
        {
            specialisationTypeByName = GameSpecialisations.GetSpecialisationTypeByName("war_economy");
        }
        else if (oldSpecId == 13)
        {
            specialisationTypeByName = GameSpecialisations.GetSpecialisationTypeByName("flight_school");
        }
        else if (oldSpecId == 14)
        {
            specialisationTypeByName = GameSpecialisations.GetSpecialisationTypeByName("radar_i");
        }
        else if (oldSpecId == 15)
        {
            specialisationTypeByName = GameSpecialisations.GetSpecialisationTypeByName("radar_i");
        }
        else if (oldSpecId == 16)
        {
            specialisationTypeByName = GameSpecialisations.GetSpecialisationTypeByName("landing_craft_tank");
        }
        else if (oldSpecId == 17)
        {
            specialisationTypeByName = GameSpecialisations.GetSpecialisationTypeByName("advanced_aeronautics");
        }
        else if (oldSpecId != 18 && oldSpecId == 19)
        {
            specialisationTypeByName = GameSpecialisations.GetSpecialisationTypeByName("nuclear_bomb");
        }
        if (specialisationTypeByName != null)
        {
            foreach (Faction faction1 in alliance.factions)
            {
                if (!specialisationTypeByName.factionTypes.Contains(faction1.factionType))
                {
                    continue;
                }
                Specialisation specialisation = new Specialisation()
                {
                    id = alliance.id * 1000000 + faction1.id * 100 + oldSpecId,
                    type = specialisationTypeByName,
                    faction = faction1
                };
                specialisation.faction.specialisations.Add(specialisation);
            }
        }
    }

    public static void ApplyCampaignEffect(Specialisation specialisation, bool fromCoreImport)
    {
        if (specialisation.type.seffect != null)
        {
            for (int i = 0; i < (int)specialisation.type.seffect.Length; i++)
            {
                if ((!fromCoreImport || !(specialisation.type.seffect[i].GetType() == typeof(EffectCreateUnit))) && (!fromCoreImport || !(specialisation.type.seffect[i].GetType() == typeof(EffectUnlockCommander))))
                {
                    specialisation.type.seffect[i].Apply(specialisation);
                }
            }
            return;
        }
        if (specialisation.type.effect == GameSpecialisations.effects.field_medics)
        {
            UnitType unitTypeByName = App.GetUnitTypeByName("willys_redcross");
            App.game.CreateUnit(specialisation.faction, unitTypeByName, null, 1, 0, new ActualGameState(), true).history.AddHistory(new List<string>()
            {
                "enlisted",
                "",
                "",
                App.game.campaign.currentDate.ToString()
            });
            return;
        }
        if (specialisation.type.effect == GameSpecialisations.effects.gruppe_monsun)
        {
            Faction factionByName = App.game.campaign.GetFactionByName("germany");
            UnitType unitType = App.GetUnitTypeByName("sub_typeix_submerged");
            for (int j = 0; j < 2; j++)
            {
                App.game.CreateUnit(factionByName, unitType, null, 1, 0, new ActualGameState(), true).history.AddHistory(new List<string>()
                {
                    "enlisted",
                    "",
                    "",
                    App.game.campaign.currentDate.ToString()
                });
            }
            App.game.campaign.cores[0].factions.Add(factionByName);
            return;
        }
        if (specialisation.type.effect == GameSpecialisations.effects.british_pacific_fleet)
        {
            Faction faction = App.game.campaign.GetFactionByName("britain");
            UnitType unitTypeByName1 = App.GetUnitTypeByName("bb_kinggeorgev");
            App.game.CreateUnit(faction, unitTypeByName1, null, 1, 0, new ActualGameState(), true).history.AddHistory(new List<string>()
            {
                "enlisted",
                "",
                "",
                App.game.campaign.currentDate.ToString()
            });
            UnitType unitType1 = App.GetUnitTypeByName("cv_implacable");
            App.game.CreateUnit(faction, unitType1, null, 1, 0, new ActualGameState(), true).history.AddHistory(new List<string>()
            {
                "enlisted",
                "",
                "",
                App.game.campaign.currentDate.ToString()
            });
            UnitType unitTypeByName2 = App.GetUnitTypeByName("dd_battle");
            App.game.CreateUnit(faction, unitTypeByName2, null, 1, 0, new ActualGameState(), true).history.AddHistory(new List<string>()
            {
                "enlisted",
                "",
                "",
                App.game.campaign.currentDate.ToString()
            });
            App.game.CreateUnit(faction, unitTypeByName2, null, 1, 0, new ActualGameState(), true).history.AddHistory(new List<string>()
            {
                "enlisted",
                "",
                "",
                App.game.campaign.currentDate.ToString()
            });
            UnitType unitType2 = App.GetUnitTypeByName("supermarine_seafire");
            App.game.CreateUnit(faction, unitType2, null, 1, 0, new ActualGameState(), true).history.AddHistory(new List<string>()
            {
                "enlisted",
                "",
                "",
                App.game.campaign.currentDate.ToString()
            });
            UnitType unitTypeByName3 = App.GetUnitTypeByName("tbm-3e_avenger_britain_b");
            App.game.CreateUnit(faction, unitTypeByName3, null, 1, 0, new ActualGameState(), true).history.AddHistory(new List<string>()
            {
                "enlisted",
                "",
                "",
                App.game.campaign.currentDate.ToString()
            });
            App.game.campaign.cores[0].factions.Add(faction);
            return;
        }
        if (specialisation.type.effect == GameSpecialisations.effects.yanagi_missions)
        {
            if (Random.Range(0, 2) == 0)
            {
                UnitType unitType3 = App.GetUnitTypeByName("pzkw_vi_tiger_japan");
                App.game.CreateUnit(App.game.campaign.GetFactionByName("japan"), unitType3, null, 1, 0, new ActualGameState(), true).history.AddHistory(new List<string>()
                {
                    "enlisted",
                    "",
                    "",
                    App.game.campaign.currentDate.ToString()
                });
                return;
            }
            UnitType unitTypeByName4 = App.GetUnitTypeByName("nebelwerfer_japan");
            App.game.CreateUnit(App.game.campaign.GetFactionByName("japan"), unitTypeByName4, null, 1, 0, new ActualGameState(), true).history.AddHistory(new List<string>()
            {
                "enlisted",
                "",
                "",
                App.game.campaign.currentDate.ToString()
            });
            return;
        }
        if (specialisation.type.effect == GameSpecialisations.effects.waffen_ss)
        {
            GameSpecialisations.FindOrAddCoreFaction(App.GetFactionTypeByName("waffenss"), specialisation.faction.alliance).AddResources(100, App.game.actualGameState);
            App.campaignController.CheckSpecialUnlocks("wiking");
            return;
        }
        if (specialisation.type.effect == GameSpecialisations.effects.waffen_ss_ii)
        {
            GameSpecialisations.FindOrAddCoreFaction(App.GetFactionTypeByName("waffenss"), specialisation.faction.alliance).AddResources(150, App.game.actualGameState);
            return;
        }
        if (specialisation.type.effect == GameSpecialisations.effects.waffen_ss_iii)
        {
            GameSpecialisations.FindOrAddCoreFaction(App.GetFactionTypeByName("waffenss"), specialisation.faction.alliance).AddResources(200, App.game.actualGameState);
            return;
        }
        if (specialisation.type.effect == GameSpecialisations.effects.elite_air_groups)
        {
            int num = 0;
            foreach (Unit unit in specialisation.faction.state.units)
            {
                if (unit.core != -1 && unit.IsAlive() && (unit.state.unitType.uClass.id == 6 || unit.state.unitType.uClass.id == 7 || unit.state.unitType.uClass.id == 8))
                {
                    GameExperience.AddExperienceStars(unit, 6, App.game.actualGameState);
                    num++;
                }
                if (num != 2)
                {
                    continue;
                }
                return;
            }
        }
        else if (specialisation.type.effect == GameSpecialisations.effects.arbeitnehmer)
        {
            UnitType unitType4 = App.GetUnitTypeByName("german_bautruppe");
            UnitType unitTypeByName5 = App.GetUnitTypeByName("german_truck");
            bool flag = false;
            foreach (Unit unit1 in specialisation.faction.state.units)
            {
                if (unit1.state.originalType != unitType4)
                {
                    continue;
                }
                flag = true;
                goto Label4;
            }
        Label4:
            if (!flag && unitType4 != null && unitTypeByName5 != null)
            {
                App.game.CreateUnit(-1, specialisation.faction, unitType4, unitTypeByName5, null, 1, 0, App.game.actualGameState, true).history.AddHistory(new List<string>()
                {
                    "enlisted",
                    "",
                    "",
                    App.game.campaign.currentDate.ToString()
                });
                return;
            }
        }
        else if (specialisation.type.effect != GameSpecialisations.effects.super_sensha)
        {
            if (specialisation.type.effect == GameSpecialisations.effects.plan_z)
            {
                specialisation.faction.AddResources(100, App.game.actualGameState);
                return;
            }
            if (specialisation.type.effect == GameSpecialisations.effects.elite_air_groups)
            {
                int num1 = 0;
                for (int k = 0; k < specialisation.faction.state.units.Count; k++)
                {
                    Unit item = specialisation.faction.state.units[k];
                    if (item.core != -1 && item.IsAlive() && (item.state.unitType.uClass.id == 6 || item.state.unitType.uClass.id == 7 || item.state.unitType.uClass.id == 8))
                    {
                        num1++;
                        GameExperience.AddExperienceStars(item, 6, App.game.actualGameState);
                        if (num1 == 2)
                        {
                            return;
                        }
                    }
                }
                return;
            }
            else if (specialisation.type.effect == GameSpecialisations.effects.panzer_lehr)
            {
                UnitType unitType5 = App.GetUnitTypeByName("pzkw_v_panther_g");
                if (unitType5 != null)
                {
                    Unit unit2 = App.game.CreateUnit(-1, specialisation.faction, unitType5, null, null, 1, 0, App.game.actualGameState, true);
                    GameExperience.AddExperienceStars(unit2, 8, App.game.actualGameState);
                    unit2.history.AddHistory(new List<string>()
                    {
                        "enlisted",
                        "",
                        "",
                        App.game.campaign.currentDate.ToString()
                    });
                    unit2.history.customName = "Panzer-Lehr-Division";
                    return;
                }
            }
            else if (specialisation.type.effect == GameSpecialisations.effects.nuke)
            {
                UnitType unitType6 = null;
                foreach (UnitType unitType7 in App.unitTypes)
                {
                    if (unitType7.specialisation == null || unitType7.specialisation.effect != GameSpecialisations.effects.nuke || !unitType7.factionTypes.Contains(specialisation.faction.factionType))
                    {
                        continue;
                    }
                    unitType6 = unitType7;
                    goto Label1;
                }
            Label1:
                bool flag1 = false;
                foreach (Unit unit3 in specialisation.faction.state.units)
                {
                    if (unit3.state.originalType != unitType6)
                    {
                        continue;
                    }
                    flag1 = true;
                    goto Label2;
                }
            Label2:
                if (!flag1 && unitType6 != null)
                {
                    App.game.CreateUnit(-1, specialisation.faction, unitType6, null, null, 1, 0, App.game.actualGameState, true).history.AddHistory(new List<string>()
                    {
                        "enlisted",
                        "",
                        "",
                        App.game.campaign.currentDate.ToString()
                    });
                    return;
                }
            }
            else if (specialisation.type.effect == GameSpecialisations.effects.infrared)
            {
                UnitType unitTypeByName6 = App.GetUnitTypeByName("sdkfz_251_uhu");
                bool flag2 = false;
                foreach (Unit unit4 in specialisation.faction.state.units)
                {
                    if (unit4.state.originalType != unitTypeByName6)
                    {
                        continue;
                    }
                    flag2 = true;
                    goto Label0;
                }
            Label0:
                if (!flag2 && unitTypeByName6 != null)
                {
                    App.game.CreateUnit(-1, specialisation.faction, unitTypeByName6, null, null, 1, 0, App.game.actualGameState, true).history.AddHistory(new List<string>()
                    {
                        "enlisted",
                        "",
                        "",
                        App.game.campaign.currentDate.ToString()
                    });
                }
            }
        }
        else if (App.game.campaign.currentDate.year >= 1945)
        {
            UnitType unitTypeByName7 = App.GetUnitTypeByName("type100_o-i");
            if (unitTypeByName7.factionTypes.Contains(specialisation.faction.factionType))
            {
                foreach (Unit unit5 in specialisation.faction.state.units)
                {
                    if (unit5.state.unitType != unitTypeByName7)
                    {
                        continue;
                    }
                    return;
                }
                App.game.CreateUnit(specialisation.faction, unitTypeByName7, null, 1, 0, App.game.actualGameState, true).history.AddHistory(new List<string>()
                {
                    "enlisted",
                    "",
                    "",
                    App.game.campaign.currentDate.ToString()
                });
                return;
            }
        }
    }

    public static void ApplyScenarioEffect(Specialisation specialisation)
    {
        IList<int> item;
        GameState gameState = App.game.actualGameState;
        if (specialisation.type.seffect != null)
        {
            for (int i = 0; i < (int)specialisation.type.seffect.Length; i++)
            {
                specialisation.type.seffect[i].Apply(specialisation);
            }
            return;
        }
        if (specialisation.type.effect == GameSpecialisations.effects.landing_craft_infantry)
        {
            foreach (Unit unit in specialisation.faction.state.units)
            {
                if (!unit.IsDeployed() || !unit.state.unitType.transportNaval || unit.state.originalType.uClass.id != 0)
                {
                    continue;
                }
                unit.SwitchTo(App.GetUnitTypeByName("lcvp"), gameState);
            }
        }
        else if (specialisation.type.effect == GameSpecialisations.effects.war_economy)
        {
            if (specialisation.faction.state.command[0] > 0)
            {
                item = specialisation.faction.state.command;
                item[0] = item[0] + 2;
            }
            if (specialisation.faction.state.command[1] > 0)
            {
                item = specialisation.faction.state.command;
                item[1] = item[1] + 2;
            }
            if (specialisation.faction.state.command[2] > 0)
            {
                item = specialisation.faction.state.command;
                item[2] = item[2] + 1;
                return;
            }
        }
        else if (specialisation.type.effect == GameSpecialisations.effects.female_laborers)
        {
            if (specialisation.faction.state.command[0] > 0)
            {
                item = specialisation.faction.state.command;
                item[0] = item[0] + 2;
            }
            if (specialisation.faction.state.command[1] > 0)
            {
                item = specialisation.faction.state.command;
                item[1] = item[1] + 2;
            }
            if (specialisation.faction.state.command[2] > 0)
            {
                item = specialisation.faction.state.command;
                item[2] = item[2] + 1;
                return;
            }
        }
        else if (specialisation.type.effect == GameSpecialisations.effects.rationing)
        {
            if (specialisation.faction.state.command[0] > 0)
            {
                item = specialisation.faction.state.command;
                item[0] = item[0] + 2;
            }
            if (specialisation.faction.state.command[1] > 0)
            {
                item = specialisation.faction.state.command;
                item[1] = item[1] + 2;
            }
            if (specialisation.faction.state.command[2] > 0)
            {
                item = specialisation.faction.state.command;
                item[2] = item[2] + 1;
                return;
            }
        }
        else if (specialisation.type.effect == GameSpecialisations.effects.air_cp_bonus)
        {
            if (specialisation.faction.state.command[2] > 0)
            {
                item = specialisation.faction.state.command;
                item[2] = item[2] + 2;
                return;
            }
        }
        else if (specialisation.type.effect != GameSpecialisations.effects.landing_craft_tank)
        {
            if (specialisation.type.effect == GameSpecialisations.effects.gruppe_monsun)
            {
                Faction faction = GameSpecialisations.FindOrAddCoreFaction(App.GetFactionTypeByName("germany"), specialisation.faction.alliance);
                faction.SetState(gameState).command[1] = faction.state.command[1] + App.GetUnitTypeByName("sub_typeix_submerged").stats.supply[1] * 2;
                App.game.scenario.GetFactionByName("germany").state.resources = 50;
                return;
            }
            if (specialisation.type.effect == GameSpecialisations.effects.british_pacific_fleet)
            {
                Faction faction1 = GameSpecialisations.FindOrAddCoreFaction(App.GetFactionTypeByName("britain"), specialisation.faction.alliance);
                faction1.SetState(gameState).command[1] = faction1.state.command[1] + 20;
                faction1.SetState(gameState).command[2] = faction1.state.command[2] + 10;
                App.game.scenario.GetFactionByName("britain").state.resources = 50;
                return;
            }
            if (specialisation.type.effect == GameSpecialisations.effects.waffen_ss || specialisation.type.effect == GameSpecialisations.effects.waffen_ss_ii || specialisation.type.effect == GameSpecialisations.effects.waffen_ss_iii)
            {
                if (specialisation.type.effect == GameSpecialisations.effects.waffen_ss && (GameSpecialisations.HasFactionSpecialisationEffect(specialisation.faction, GameSpecialisations.effects.waffen_ss_ii) || GameSpecialisations.HasFactionSpecialisationEffect(specialisation.faction, GameSpecialisations.effects.waffen_ss_iii)))
                {
                    return;
                }
                if (specialisation.type.effect == GameSpecialisations.effects.waffen_ss_ii && GameSpecialisations.HasFactionSpecialisationEffect(specialisation.faction, GameSpecialisations.effects.waffen_ss_iii))
                {
                    return;
                }
                Faction faction2 = GameSpecialisations.FindOrAddCoreFaction(App.GetFactionTypeByName("waffenss"), specialisation.faction.alliance);
                Faction factionByType = App.game.scenario.GetFactionByType(App.GetFactionTypeByName("germany"));
                int num = 0;
                if (specialisation.type.effect == GameSpecialisations.effects.waffen_ss_iii)
                {
                    faction2.SetState(gameState).command[0] = faction2.State(gameState).command[0] + 6;
                    num = 10;
                }
                else if (specialisation.type.effect != GameSpecialisations.effects.waffen_ss_ii)
                {
                    faction2.SetState(gameState).command[0] = faction2.State(gameState).command[0] + 6;
                    num = 2;
                }
                else
                {
                    faction2.SetState(gameState).command[0] = faction2.State(gameState).command[0] + 6;
                    num = 5;
                }
                num = Mathf.Min(num, factionByType.State(gameState).income / 5);
                factionByType.AddIncome(-num, gameState);
                faction2.AddIncome(num, gameState);
                return;
            }
            if (specialisation.type.effect == GameSpecialisations.effects.plan_z && specialisation.faction.state.command[1] > 0)
            {
                item = specialisation.faction.state.command;
                item[1] = item[1] + 4;
            }
        }
        else
        {
            foreach (Unit unit1 in specialisation.faction.state.units)
            {
                if (!unit1.IsDeployed() || !unit1.state.unitType.transportNaval || unit1.state.originalType.uClass.id != 2)
                {
                    continue;
                }
                unit1.SwitchTo(App.GetUnitTypeByName("lct"), gameState);
            }
        }
    }

    private static Faction FindOrAddCoreFaction(FactionType factionType, Alliance targetAlliance)
    {
        Faction factionByType = null;
        if (App.game.campaign != null)
        {
            bool flag = false;
            foreach (Faction faction in App.game.campaign.GetPlayerCore().factions)
            {
                if (faction.factionType != factionType)
                {
                    continue;
                }
                flag = true;
                factionByType = faction;
                goto Label0;
            }
        Label0:
            if (!flag)
            {
                factionByType = App.game.campaign.GetFactionByType(factionType);
                if (factionByType == null)
                {
                    factionByType = App.game.campaign.AddFaction(factionType, targetAlliance);
                    factionByType.index = App.game.campaign.factions.Count - 1;
                }
                App.game.campaign.GetPlayerCore().factions.Add(factionByType);
            }
        }
        if (App.game.scenario != null)
        {
            factionByType = App.game.scenario.GetFactionByType(factionType);
            if (factionByType == null)
            {
                factionByType = new Faction(App.game.scenario.AssignNextFactionId(), factionType)
                {
                    stats = new FactionStats(factionByType)
                };
                App.game.scenario.factions.Add(factionByType);
                App.map.CreateUnitPlateEmblem(factionByType);
                factionByType.index = App.game.scenario.factions.Count - 1;
            }
            if (factionByType.alliance != targetAlliance)
            {
                factionByType.SetAlliance(targetAlliance);
            }
        }
        return factionByType;
    }

    public static SpecialisationType GetSpecialisationTypeById(int id)
    {
        for (int i = 0; i < App.specialisationTypes.Count; i++)
        {
            if (App.specialisationTypes[i].id == id)
            {
                return App.specialisationTypes[i];
            }
        }
        return null;
    }

    public static SpecialisationType GetSpecialisationTypeByName(string name)
    {
        for (int i = 0; i < App.specialisationTypes.Count; i++)
        {
            if (App.specialisationTypes[i].name == name)
            {
                return App.specialisationTypes[i];
            }
        }
        return null;
    }

    public static bool HasFactionSpecialisationEffect(Faction faction, GameSpecialisations.effects effect)
    {
        for (int i = 0; i < faction.specialisations.Count; i++)
        {
            if (faction.specialisations[i].type.effect == effect)
            {
                return true;
            }
        }
        return false;
    }

    public static bool HasFactionSpecialisationType(Faction faction, string name)
    {
        return GameSpecialisations.HasFactionSpecialisationType(faction, GameSpecialisations.GetSpecialisationTypeByName(name));
    }

    public static bool HasFactionSpecialisationType(Faction faction, SpecialisationType specType)
    {
        for (int i = 0; i < faction.specialisations.Count; i++)
        {
            if (faction.specialisations[i].type.id == specType.id)
            {
                return true;
            }
        }
        return false;
    }

    public static void Init()
    {
        Debug.Log("init specs");
        int count = App.factionTypes.Count;
        GameSpecialisations.hasAuftragstaktik = new bool[count];
        GameSpecialisations.hasProximityFuse = new bool[count];
        GameSpecialisations.hasFieldMedics = new bool[count];
        GameSpecialisations.hasBanzaiCharge = new bool[count];
        GameSpecialisations.hasBushidoCode = new bool[count];
        GameSpecialisations.hasForcedLabour = new bool[count];
        GameSpecialisations.hasTokyoExpress = new bool[count];
        GameSpecialisations.hasRadarI = new bool[count];
        GameSpecialisations.hasRadarII = new bool[count];
        GameSpecialisations.hasDamageControl = new bool[count];
        GameSpecialisations.hasDropTank = new bool[count];
        GameSpecialisations.hasUnrestrictedSubWar = new bool[count];
        GameSpecialisations.hasWolfPack = new bool[count];
        GameSpecialisations.hasLibertyShips = new bool[count];
        GameSpecialisations.hasTorpImprovements = new bool[count];
        GameSpecialisations.hasMetalDetector = new bool[count];
        GameSpecialisations.hasBomberStream = new bool[count];
        GameSpecialisations.hasHobartsFunnies = new bool[count];
        GameSpecialisations.hasGoliath = new bool[count];
        GameSpecialisations.hasPakFront = new bool[count];
        GameSpecialisations.hasPanzerKeil = new bool[count];
        GameSpecialisations.hasWireBomb = new bool[count];
        GameSpecialisations.hasESeries = new bool[count];
        GameSpecialisations.hasPanzerLehr = new bool[count];
        GameSpecialisations.hasInfrared = new bool[count];
        GameSpecialisations.hasMolotovRibbentropPact = new bool[count];
        GameSpecialisations.hasGreatPatrioticWar = new bool[count];
        GameSpecialisations.hasSiberianReserves = new bool[count];
        GameSpecialisations.hasArcticConvoy = new bool[count];
        GameSpecialisations.hasLendLeaseUssr = new bool[count];
        GameSpecialisations.hasOrderNo227 = new bool[count];
        GameSpecialisations.hasShockArmy = new bool[count];
        GameSpecialisations.hasGuardsArmy = new bool[count];
        GameSpecialisations.hasATClusterBomb = new bool[count];
        GameSpecialisations.hasSovFighterTactics = new bool[count];
        GameSpecialisations.hasAirOffensive = new bool[count];
        GameSpecialisations.hasRedTails = new bool[count];
        foreach (Faction faction in App.game.scenario.factions)
        {
            GameSpecialisations.hasAuftragstaktik[faction.index] = GameSpecialisations.HasFactionSpecialisationEffect(faction, GameSpecialisations.effects.auftragstaktik);
            GameSpecialisations.hasProximityFuse[faction.index] = GameSpecialisations.HasFactionSpecialisationEffect(faction, GameSpecialisations.effects.proximity_fuse);
            GameSpecialisations.hasFieldMedics[faction.index] = GameSpecialisations.HasFactionSpecialisationEffect(faction, GameSpecialisations.effects.field_medics);
            GameSpecialisations.hasBanzaiCharge[faction.index] = GameSpecialisations.HasFactionSpecialisationEffect(faction, GameSpecialisations.effects.banzai_charge);
            GameSpecialisations.hasBushidoCode[faction.index] = GameSpecialisations.HasFactionSpecialisationEffect(faction, GameSpecialisations.effects.bushido_code);
            GameSpecialisations.hasForcedLabour[faction.index] = GameSpecialisations.HasFactionSpecialisationEffect(faction, GameSpecialisations.effects.forced_labour);
            GameSpecialisations.hasTokyoExpress[faction.index] = GameSpecialisations.HasFactionSpecialisationEffect(faction, GameSpecialisations.effects.destroyer_supply_bonus);
            GameSpecialisations.hasRadarI[faction.index] = GameSpecialisations.HasFactionSpecialisationEffect(faction, GameSpecialisations.effects.radar_i);
            GameSpecialisations.hasRadarII[faction.index] = GameSpecialisations.HasFactionSpecialisationEffect(faction, GameSpecialisations.effects.radar_ii);
            GameSpecialisations.hasDamageControl[faction.index] = GameSpecialisations.HasFactionSpecialisationEffect(faction, GameSpecialisations.effects.damage_control);
            GameSpecialisations.hasDropTank[faction.index] = GameSpecialisations.HasFactionSpecialisationEffect(faction, GameSpecialisations.effects.drop_tank);
            GameSpecialisations.hasUnrestrictedSubWar[faction.index] = GameSpecialisations.HasFactionSpecialisationEffect(faction, GameSpecialisations.effects.unrestricted_submarine_warface);
            GameSpecialisations.hasWolfPack[faction.index] = GameSpecialisations.HasFactionSpecialisationEffect(faction, GameSpecialisations.effects.wolfpack);
            GameSpecialisations.hasLibertyShips[faction.index] = GameSpecialisations.HasFactionSpecialisationEffect(faction, GameSpecialisations.effects.liberty_ships);
            GameSpecialisations.hasTorpImprovements[faction.index] = GameSpecialisations.HasFactionSpecialisationEffect(faction, GameSpecialisations.effects.torpedo_improvements);
            GameSpecialisations.hasMetalDetector[faction.index] = GameSpecialisations.HasFactionSpecialisationEffect(faction, GameSpecialisations.effects.metal_detector);
            GameSpecialisations.hasBomberStream[faction.index] = GameSpecialisations.HasFactionSpecialisationEffect(faction, GameSpecialisations.effects.bomber_stream);
            GameSpecialisations.hasHobartsFunnies[faction.index] = GameSpecialisations.HasFactionSpecialisationEffect(faction, GameSpecialisations.effects.hobarts_funnies);
            GameSpecialisations.hasGoliath[faction.index] = GameSpecialisations.HasFactionSpecialisationEffect(faction, GameSpecialisations.effects.goliath);
            GameSpecialisations.hasPakFront[faction.index] = GameSpecialisations.HasFactionSpecialisationEffect(faction, GameSpecialisations.effects.pak_front);
            GameSpecialisations.hasPanzerKeil[faction.index] = GameSpecialisations.HasFactionSpecialisationEffect(faction, GameSpecialisations.effects.panzer_keil);
            GameSpecialisations.hasWireBomb[faction.index] = GameSpecialisations.HasFactionSpecialisationEffect(faction, GameSpecialisations.effects.wire_guided_bomb);
            GameSpecialisations.hasESeries[faction.index] = GameSpecialisations.HasFactionSpecialisationEffect(faction, GameSpecialisations.effects.e_series);
            GameSpecialisations.hasPanzerLehr[faction.index] = GameSpecialisations.HasFactionSpecialisationEffect(faction, GameSpecialisations.effects.panzer_lehr);
            GameSpecialisations.hasInfrared[faction.index] = GameSpecialisations.HasFactionSpecialisationEffect(faction, GameSpecialisations.effects.infrared);
            GameSpecialisations.hasMolotovRibbentropPact[faction.index] = GameSpecialisations.HasFactionSpecialisationEffect(faction, GameSpecialisations.effects.molotov_ribbentrop_pact);
            GameSpecialisations.hasGreatPatrioticWar[faction.index] = GameSpecialisations.HasFactionSpecialisationEffect(faction, GameSpecialisations.effects.great_patriotic_war);
            GameSpecialisations.hasSiberianReserves[faction.index] = GameSpecialisations.HasFactionSpecialisationEffect(faction, GameSpecialisations.effects.siberian_reserves);
            GameSpecialisations.hasArcticConvoy[faction.index] = GameSpecialisations.HasFactionSpecialisationEffect(faction, GameSpecialisations.effects.arctic_convoy);
            GameSpecialisations.hasLendLeaseUssr[faction.index] = GameSpecialisations.HasFactionSpecialisationEffect(faction, GameSpecialisations.effects.lend_lease_ussr);
            GameSpecialisations.hasOrderNo227[faction.index] = GameSpecialisations.HasFactionSpecialisationEffect(faction, GameSpecialisations.effects.order_no227);
            GameSpecialisations.hasShockArmy[faction.index] = GameSpecialisations.HasFactionSpecialisationEffect(faction, GameSpecialisations.effects.shock_army);
            GameSpecialisations.hasGuardsArmy[faction.index] = GameSpecialisations.HasFactionSpecialisationEffect(faction, GameSpecialisations.effects.guards_army);
            GameSpecialisations.hasATClusterBomb[faction.index] = GameSpecialisations.HasFactionSpecialisationEffect(faction, GameSpecialisations.effects.at_cluster_bomb);
            GameSpecialisations.hasSovFighterTactics[faction.index] = GameSpecialisations.HasFactionSpecialisationEffect(faction, GameSpecialisations.effects.sov_fighter_tactics);
            GameSpecialisations.hasAirOffensive[faction.index] = GameSpecialisations.HasFactionSpecialisationEffect(faction, GameSpecialisations.effects.air_offensive);
            GameSpecialisations.hasRedTails[faction.index] = GameSpecialisations.HasFactionSpecialisationEffect(faction, GameSpecialisations.effects.red_tails);
        }
        foreach (UnitType unitType in App.unitTypes)
        {
            if (unitType.specialisation == null || unitType.specialisation.effect != GameSpecialisations.effects.infrared)
            {
                continue;
            }
            GameSpecialisations.infraredLight = unitType;
        }
    }

    public static void Unlock(Faction faction, SpecialisationType specialisationType)
    {
        GameSpecialisations.Unlock(faction, specialisationType, false, false);
    }

    public static void Unlock(Faction faction, SpecialisationType specialisationType, bool free, bool fromCoreImport = false)
    {
        if (GameSpecialisations.HasFactionSpecialisationType(faction, specialisationType))
        {
            return;
        }
        if (!free)
        {
            if (faction.specialisationPoints < specialisationType.cost)
            {
                return;
            }
            faction.specialisationPoints -= specialisationType.cost;
        }
        Specialisation specialisation = new Specialisation(faction, specialisationType);
        specialisation.AssignId(App.game.campaign.factions);
        if (App.mode == App.modes.campaign)
        {
            GameSpecialisations.ApplyCampaignEffect(specialisation, fromCoreImport);
        }
    }

    public static void UnlockFree(Faction faction, SpecialisationType specialisationType)
    {
        GameSpecialisations.Unlock(faction, specialisationType, true, false);
    }

    public enum effects
    {
        radar_i,
        landing_craft_infantry,
        land_cp_bonus,
        landing_craft_tank,
        wolfpack,
        british_pacific_fleet,
        hidden_nests,
        field_medics,
        aircraft_experience,
        proximity_fuse,
        forced_labour,
        destroyer_supply_bonus,
        kamikaze,
        super_sensha,
        plan_z,
        advanced_aeronautics,
        banzai_charge,
        auftragstaktik,
        beutepanzer,
        tank_experience,
        panzer_lehr,
        pak_front,
        panzer_keil,
        waffen_ss,
        nuke,
        naval_experience,
        damage_control,
        beaching,
        armed_merchants,
        pilot_rotation,
        drop_tank,
        winter_gear,
        infantry_experience,
        bushido_code,
        rationing,
        elite_air_groups,
        radar_ii,
        scrambling,
        build_bunkers,
        yanagi_missions,
        war_economy,
        female_laborers,
        gruppe_monsun,
        unrestricted_submarine_warface,
        block_construction,
        liberty_ships,
        flugzeugtrager,
        schlachtschiffe,
        torpedo_improvements,
        lend_lease,
        home_guard,
        metal_detector,
        hobarts_funnies,
        free_french,
        resistance_fighters,
        special_services,
        bomber_stream,
        waffen_ss_ii,
        waffen_ss_iii,
        arbeitnehmer,
        goliath,
        air_cp_bonus,
        baukommando_becker,
        panzer_fibel,
        e_series,
        wire_guided_bomb,
        infrared,
        molotov_ribbentrop_pact,
        great_patriotic_war,
        siberian_reserves,
        arctic_convoy,
        lend_lease_ussr,
        ll_ussr_air,
        ll_ussr_logistics,
        order_no227,
        guard_infantry,
        shock_army,
        guards_army,
        kuban_shelves,
        at_cluster_bomb,
        sov_fighter_tactics,
        air_offensive,
        red_tails
    }
}