using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using UnityEngine;
using Verse;
using Verse.AI;

namespace RimWorld
{
abstract class IncidentWorker_ShipPartCrash : IncidentWorker
{
    //Constants
    private const float ShipPointsFactor = 0.9f;
    private const int IncidentMinimumPoints = 300; //One centipede

    //Properties
    protected virtual int CountToSpawn { get { return 1; } }

    protected override bool StorytellerCanUseNowSub()
    {
        if (Find.ListerThings.ThingsOfDef(def.shipPart).Count > 0)
            return false;

        return true;
    }

    public override bool TryExecute(IncidentParms parms)
    {
        int spawnedCount = 0;
        int countToSpawn = CountToSpawn;
        IntVec3 lastSpawnedLoc = IntVec3.Invalid;

        for (int i = 0; i < countToSpawn; ++i)
        {
            Predicate<IntVec3> validator = c =>
            {
                if (c.Fogged())
                    return false;

                foreach (IntVec3 subCell in GenAdj.CellsOccupiedBy(c, Rot4.North, def.shipPart.size))
                {
                    if (!subCell.Standable())
                        return false;

                    if (Find.RoofGrid.Roofed(subCell))
                        return false;
                }

                if (!c.CanReachColony())
                    return false;

                return true;
            };


            IntVec3 center;
            if (!CellFinderLoose.TryFindRandomNotEdgeCellWith(14, validator, out center))
                break;

            // Make the crash explosion
            GenExplosion.DoExplosion(center, 3f, DamageDefOf.Flame, null);

            // Spawn the ship part
            Building_CrashedShipPart shipPart = (Building_CrashedShipPart)GenSpawn.Spawn(def.shipPart, center);
            shipPart.SetFaction(Faction.OfMechanoids);
            shipPart.pointsLeft = parms.points * ShipPointsFactor;
            if (shipPart.pointsLeft < IncidentMinimumPoints)
                shipPart.pointsLeft = IncidentMinimumPoints;

            ++spawnedCount;
            lastSpawnedLoc = center;
        }

        if (spawnedCount > 0)
        {
            Find.CameraMap.shaker.DoShake(1.0f);

            //Make letter
            Find.LetterStack.ReceiveLetter(def.letterLabel, def.letterText, def.letterType, lastSpawnedLoc);
        }

        return spawnedCount > 0;
    }
}
}
