package data.missions.swp_duelofthecentury;

import com.fs.starfarer.api.Global;
import com.fs.starfarer.api.characters.FullName;
import com.fs.starfarer.api.characters.PersonAPI;
import com.fs.starfarer.api.combat.BaseEveryFrameCombatPlugin;
import com.fs.starfarer.api.combat.CombatEngineAPI;
import com.fs.starfarer.api.combat.ShipAPI;
import com.fs.starfarer.api.fleet.FleetGoal;
import com.fs.starfarer.api.fleet.FleetMemberAPI;
import com.fs.starfarer.api.fleet.FleetMemberType;
import com.fs.starfarer.api.impl.campaign.events.OfficerManagerEvent;
import com.fs.starfarer.api.impl.campaign.events.OfficerManagerEvent.SkillPickPreference;
import com.fs.starfarer.api.impl.campaign.ids.Factions;
import com.fs.starfarer.api.input.InputEventAPI;
import com.fs.starfarer.api.mission.FleetSide;
import com.fs.starfarer.api.mission.MissionDefinitionAPI;
import com.fs.starfarer.api.mission.MissionDefinitionPlugin;
import java.awt.Color;
import java.util.ArrayList;
import java.util.List;
import org.dark.shaders.light.LightShader;
import org.dark.shaders.light.StandardLight;
import org.dark.shaders.post.PostProcessShader;
import org.lwjgl.util.vector.Vector3f;

public class MissionDefinition implements MissionDefinitionPlugin {
    
    public static final List<String[]> ENEMIES = new ArrayList<>();
    public static final String PLAYER_VARIANT = "swp_excelsior_eli";
    
    protected boolean campaignMode;    // set to true if mission is being created from an arcade machine in campaign
    
    static {
        // name, required mod's ID, variant, fallback variant
        ENEMIES.add(new String[] {"Mozart", null, "hyperion_Strike", null});
        ENEMIES.add(new String[] {"Beethoven", "underworld", "uw_venomx_eli", "hyperion_Strike"});
        ENEMIES.add(new String[] {"Vivaldi", "blackrock_driveyards", "brdy_imaginos_shock", "hyperion_Attack"});
        //ENEMIES.add(new String[] {"Tartini", "exigency", "exigency_indra_Standard", "hyperion_Strike"});    // wait till Exigency's return?
        ENEMIES.add(new String[] {"Mendelssohn", "shadow_ships", "ms_shamash_EMP", "hyperion_Attack"});
        ENEMIES.add(new String[] {"Paganini", "Templars", "tem_jesuit_est", "hyperion_Strike"});
        ENEMIES.add(new String[] {"Dvorak", "Imperium", "ii_maximus_str", "hyperion_Attack"});
        ENEMIES.add(new String[] {"Saint-Saens", "SCY", "SCY_stymphalianbird_combat", "hyperion_Strike"});
        ENEMIES.add(new String[] {"Haydn", "diableavionics", "diableavionics_versant_standard", "hyperion_Attack"});
        ENEMIES.add(new String[] {"Bizet", "ORA", "ora_ascension_control", "hyperion_Strike"});
        ENEMIES.add(new String[] {"Chopin", "Imperium", "swp_boss_excelsior_cus", "hyperion_Attack"});
    }
    
    // TODO: maybe limit to 10 or so enemies and rotate which ones are selected based on available mods
    public void addEnemyShips(MissionDefinitionAPI api) {
        for (String[] entry : ENEMIES) {
            String name = entry[0];
            String modId = entry[1];
            String variantId = entry[2];
            String fallback = entry[3];
            
            if (modId != null && !Global.getSettings().getModManager().isModEnabled(modId)) {
                variantId = fallback;
            }
            api.addToFleet(FleetSide.ENEMY, variantId, FleetMemberType.SHIP, "ISS " + name, false);
        }
    }
    
    @Override
    public void defineMission(MissionDefinitionAPI api) {
        api.initFleet(FleetSide.PLAYER, "TTS", FleetGoal.ATTACK, false);
        api.initFleet(FleetSide.ENEMY, "ISS", FleetGoal.ATTACK, true);

        api.setFleetTagline(FleetSide.PLAYER, "Captain Clawfoot's stolen Tri-Tachyon prototype");
        api.setFleetTagline(FleetSide.ENEMY, "\"The Protectors\" elite mercenary company");

        api.setHyperspaceMode(true);

        api.addBriefingItem("Defeat \"The Protectors\".");
        api.addBriefingItem(
                "Captain Clawfoot's skills are impeccable; the Excelsior is particularly effective in battle.");
        api.addBriefingItem("Flux will increase slowly over time due to flux synchonicity from the nearby star.");
        
        if (!campaignMode) {
            FleetMemberAPI member = api.addToFleet(FleetSide.PLAYER, PLAYER_VARIANT, 
                    FleetMemberType.SHIP, "TTS Excelsior", true);

            PersonAPI officer = OfficerManagerEvent.createOfficer(Global.getSector().getFaction(Factions.INDEPENDENT), 
                    20, true, SkillPickPreference.NON_CARRIER);
            officer.getName().setFirst("Captain");
            officer.getName().setLast("Clawfoot");
            officer.getName().setGender(FullName.Gender.MALE);
            officer.setPortraitSprite("graphics/portraits/portrait20.png");
            officer.setFaction(Factions.INDEPENDENT);
            member.setCaptain(officer);
            float maxCR = member.getRepairTracker().getMaxCR();
            member.getRepairTracker().setCR(maxCR);
            
            addEnemyShips(api);
        }

        float width = 10000f;
        float height = 10000f;
        api.initMap(-width / 2f, width / 2f, -height / 2f, height / 2f);

        api.addAsteroidField(0f, 0f, (float) Math.random() * 360f, width, 30f, 200f, 500);
        api.addPlugin(new Plugin());
    }
    
    public void setCampaignMode(boolean mode) {
        campaignMode = mode;
    }

    public final static class Plugin extends BaseEveryFrameCombatPlugin {

        private boolean reallyStarted = false;
        private boolean started = false;

        @Override
        public void advance(float amount, List<InputEventAPI> events) {
            if (!started) {
                started = true;
                return;
            }
            if (!reallyStarted) {
                reallyStarted = true;

                StandardLight sun = new StandardLight();
                sun.setType(3);
                sun.setDirection((Vector3f) (new Vector3f(-1f, -1f, -0.2f)).normalise());
                sun.setIntensity(0f);
                sun.setSpecularIntensity(2f);
                sun.setColor(new Color(212, 91, 22));
                sun.makePermanent();
                LightShader.addLight(sun);

                sun = new StandardLight();
                sun.setType(3);
                sun.setDirection((Vector3f) (new Vector3f(0f, 0f, -1f)).normalise());
                sun.setIntensity(0.75f);
                sun.setSpecularIntensity(0f);
                sun.setColor(new Color(212, 91, 22));
                sun.makePermanent();
                LightShader.addLight(sun);

                PostProcessShader.setSaturation(false, 1.1f);
                PostProcessShader.setLightness(false, 1.1f);
                PostProcessShader.setContrast(false, 1.1f);
                PostProcessShader.setNoise(false, 0.1f);
            }

            if (Global.getCombatEngine().isPaused()) {
                return;
            }

            for (ShipAPI ship : Global.getCombatEngine().getShips()) {
                if (ship.getHullSpec().getHullId().contentEquals("swp_excelsior")) {
                    ship.getFluxTracker().increaseFlux(30f * amount, true);
                }
            }
        }

        @Override
        public void init(CombatEngineAPI engine) {
        }
    };
}
