/*
 * Created by SharpDevelop.
 * User: Etienne
 * Date: 22/11/2017
 * Time: 16:41
 * 
 * To change this template use Tools | Options | Coding | Edit Standard Headers.
 */

using RimWorld;
using System;
using System.Collections.Generic;
using Verse;

namespace LTF_Crystal
{
	public class HeDiffComp_LTF_Crystal : HediffComp
	{
		int skillCooldown = 30000;
				
		int hungerReset=0;
		int healthReset=0;
        int graceTicks = 0;

        Pawn pawn = null;

        Random rand = new Random();

        public HeDiffCompProperties_LTF_Crystal Props
		{
			get
			{
				return (HeDiffCompProperties_LTF_Crystal)this.props;
			}
		}


        public override void CompExposeData()
        {
            Scribe_Values.Look(ref skillCooldown, "LTF_skillCooldown");
            Scribe_Values.Look(ref hungerReset, "LTF_hungerReset");
            Scribe_Values.Look(ref healthReset, "LTF_healthReset");

        }

        public override void CompPostTick(ref float severityAdjustment)
        {

            pawn = parent.pawn;
            if (pawn == null) return;
            if (pawn.Map == null) return;


            if (IsHungry())
            {
                hungerReset++;
                graceTicks = (int)(RandomTime2wait() * 5000);
                return;
            }

            if (IsInjured())
            {
                healthReset++;
                graceTicks = (int)(RandomTime2wait() * 2000);
                return;
            }

            if (skillCooldown > 0)
            {
                skillCooldown--;
            }

            if (skillCooldown < 0) skillCooldown = 0;

        }

        public bool TryDoSpawn()
        {
            pawn = this.parent.pawn;
            if (pawn == null)
            {
                return false;
            }
            return false;

            //         GenSpawn.Spawn(insect, CellFinder.RandomClosewalkCellNear(pawn.Position, pawn.Map, 4, null), pawn.Map);
            /*                        
            if (this.Props.spawnMaxAdjacent >= 0)
            {
                int num = 0;
                for (int i = 0; i < 9; i++)
                {
                    List<Thing> thingList = (pawn.Position + GenAdj.AdjacentCellsAndInside[i]).GetThingList(pawn.Map);
                    for (int j = 0; j < thingList.Count; j++)
                    {
                        if (thingList[j].def == this.Props.thingToSpawn)
                        {
                            num += thingList[j].stackCount;
                            if (num >= this.Props.spawnMaxAdjacent)
                            {
                                return false;
                            }
                        }
                    }
                }
            }
            */
            /*
            IntVec3 center;
            if (this.TryFindSpawnCell(out center))
            {
                Thing thing = ThingMaker.MakeThing(this.Props.thingToSpawn, null);
                thing.stackCount = this.Props.spawnCount;
                Thing t;
                GenPlace.TryPlaceThing(thing, center, pawn.Map, ThingPlaceMode.Direct, out t, null);
                if (this.Props.spawnForbidden)
                {
                    t.SetForbidden(true, true);
                }
                return true;
            }
            return false;
            */
        }

		private bool TryFindSpawnCell(out IntVec3 result)
		{
			pawn = this.parent.pawn;
			if (pawn != null)
			{
				foreach (IntVec3 current in GenAdj.CellsAdjacent8Way(pawn).InRandomOrder(null))
				{
					if (current.Walkable(pawn.Map))
					{
						Building edifice = current.GetEdifice(pawn.Map);
						if (edifice == null || !this.Props.thingToSpawn.IsEdifice())
						{
							Building_Door building_Door = edifice as Building_Door;
							if (building_Door == null || building_Door.FreePassage)
							{
								if (GenSight.LineOfSight(pawn.Position, current,pawn.Map, false, null, 0, 0))
								{
									bool flag = false;
									List<Thing> thingList = current.GetThingList(pawn.Map);
									for (int i = 0; i < thingList.Count; i++)
									{
										Thing thing = thingList[i];
										if (thing.def.category == ThingCategory.Item && (thing.def != this.Props.thingToSpawn || thing.stackCount > this.Props.thingToSpawn.stackLimit - this.Props.spawnCount))
										{
											flag = true;
											break;
										}
									}
									if (!flag)
									{
										result = current;
										return true;
									}
								}
							}
						}
					}
				}
				result = IntVec3.Invalid;
				return false;
			}else{
				Log.Warning( "TryFindSpawnCell Null");
				result = IntVec3.Invalid;
				return false;
			}
		}

		private void ResetCooldown()
		{
            skillCooldown = RandomTime2wait();
        }

        private int RandomTime2wait()
        {
            return ((int)(Props.timeUnit*Rand.Range(Props.minTimeB4Next, Props.maxTimeB4Next)));
            //return ((this.Props.minTimeB4Next + (this.Props.maxTimeB4Next - this.Props.minTimeB4Next) * (float)rand.NextDouble()) );
        }
        private float randomGraceTime()
        {
            return ((int)(Props.timeUnit * Rand.Range(Props.graceTime/3, Props.graceTime)));
        }

        private bool IsWounded()
		{
			pawn = this.parent.pawn;
            if (pawn == null) return false;
			
			float num = 0;
			List<Hediff> hediffs = pawn.health.hediffSet.hediffs;
			for (int i = 0; i < hediffs.Count; i++)
			{
				if (hediffs[i] is Hediff_Injury && !hediffs[i].IsOld())
				{
					num += hediffs[i].Severity;
				}
			}

			return (num>0);
		}
		
		private bool IsHungry()
		{

			pawn = parent.pawn;

            if (pawn == null) return false;
            
			if (Props.hungerRelative == true){
				if (pawn.needs.food != null && pawn.needs.food.CurCategory == HungerCategory.Starving)
				{
					return true;
				}else{
					return false;
				}
			}
			else{
				return false;
			}
		}

        private bool IsInjured()
        {
            pawn = parent.pawn;
            if (pawn == null) return false;

            if (Props.healthRelative == true) {
                if (IsWounded())
                {
                    return true;
                }
                else {

                }
                return false;
            }
            else
            {
                return false;
            }
        }
		

		public override string CompTipStringExtra
		{
			get
			{
				string result = string.Empty;
                int ticksLeft = skillCooldown;

                if (this.graceTicks > 0)
                {

                    result = " No " + Props.thingToSpawn.label + " for " + (graceTicks).ToStringTicksToPeriod(true, false, true);

                    if (hungerReset > 0)
                    {
                        result += "(hunger)";
                    }
                    else if (healthReset > 0)
                    {
                        result += "(injury)";
                    }
                    else
                    {
                        result += "(why not)";
                    }
                }
                else{

                    result = ticksLeft.ToStringTicksToPeriod(true, false, true) + " before ";
                    result += Props.thingToSpawn.label;
                }
				return result;
			}
		}
	}
}
