using UnityEngine;
using System.Collections;
using Verse;
using Verse.Sound;


namespace RimWorld{
public class CompExplosive : ThingComp
{
	//Working vars
	public bool 			wickStarted = false;
	protected int			wickTicksLeft = 0;
	private Thing			instigator;
	
	//Components
	protected Sustainer		wickSoundSustainer = null;
	
	//Properties
	public CompProperties_Explosive Props { get { return (CompProperties_Explosive)props; } }
	protected int StartWickThreshold
	{
		get
		{
			return Mathf.RoundToInt(Props.startWickHitPointsPercent * parent.MaxHitPoints);
		}
	}
	private bool CanEverExplodeFromDamage
	{
		get
		{
			if( Props.chanceNeverExplodeFromDamage < 0.00001f )
				return true;
			else
			{
				Rand.PushSeed();
				Rand.Seed = parent.thingIDNumber.GetHashCode();
				bool result = Rand.Value < Props.chanceNeverExplodeFromDamage;
				Rand.PopSeed();
				return result;
			}
		}
	}


	public override void PostExposeData()
	{
		base.PostExposeData();

		Scribe_References.LookReference(ref instigator, "instigator");
		Scribe_Values.LookValue( ref wickStarted, "wickStarted", false );
		Scribe_Values.LookValue( ref wickTicksLeft, "wickTicksLeft", 0 );
	}

	public override void CompTick()
	{
		if( wickStarted )
		{
			if( wickSoundSustainer == null )
				StartWickSustainer(); //or sustainer is missing on load
			else
				wickSoundSustainer.Maintain();
			
			wickTicksLeft--;
			if( wickTicksLeft <= 0 )
				Detonate();
		}
	}
	
	private void StartWickSustainer()
	{
		SoundDefOf.MetalHitImportant.PlayOneShot(parent.Position);
		SoundInfo info = SoundInfo.InWorld(parent, MaintenanceType.PerTick);
		wickSoundSustainer = SoundDefOf.HissSmall.TrySpawnSustainer( info );
	}

	public override void PostDraw()
	{
		if( wickStarted )
		{
			OverlayDrawer.DrawOverlay(parent, OverlayTypes.BurningWick);
		}
	}

	public override void PostPreApplyDamage(DamageInfo dinfo, out bool absorbed)
	{
		if( Props.startWickOnDamageTaken != null
			&& dinfo.Def == Props.startWickOnDamageTaken
			&& CanEverExplodeFromDamage )
		{
			StartWick(dinfo.Instigator);
			absorbed = true;
		}
		else
			absorbed = false;
	}
	
	public override void PostPostApplyDamage(DamageInfo dinfo, float totalDamageDealt)
	{
		if( !CanEverExplodeFromDamage )
			return;

		if( parent.HitPoints <= 0 && StartWickThreshold >= 0 )
		{
			if( dinfo.Def.externalViolence )
			{
				instigator = dinfo.Instigator;
				Detonate();
			}
		}
		else
		{
			
			if( wickStarted && dinfo.Def == DamageDefOf.Stun )
				StopWick();		
			else if( !wickStarted && parent.HitPoints <= StartWickThreshold )
			{
				if( dinfo.Def.externalViolence )
					StartWick(dinfo.Instigator);
			}
		}
	}
	
	public void StartWick(Thing instigator = null)
	{
		if( wickStarted )
			return;

		this.instigator = instigator;

		wickStarted = true;
		wickTicksLeft = Props.wickTicks.RandomInRange;
		StartWickSustainer();

		GenExplosion.NotifyNearbyPawnsOfDangerousExplosive(parent, Props.explosiveDamageType);
	}
	
	public void StopWick()
	{
		wickStarted = false;
		instigator = null;
	}
	
	private bool detonated = false;
	protected void Detonate()
	{	
		if( detonated )
			return;

		detonated = true;

		if( !parent.Destroyed )
			parent.Destroy(	DestroyMode.Kill );

		var props = Props;

		//Expand radius for stackcount
		float radius = props.explosiveRadius;
		if( parent.stackCount > 1 && props.explosiveExpandPerStackcount > 0 )
			radius += Mathf.Sqrt((parent.stackCount-1) * props.explosiveExpandPerStackcount);

		if( props.explosionEffect != null )
		{
			var effect = props.explosionEffect.Spawn();
			effect.Trigger(parent.Position, parent.Position);
			effect.Cleanup();
		}

		GenExplosion.DoExplosion(parent.Position,
			radius,
			props.explosiveDamageType,
			instigator ?? parent,
			postExplosionSpawnThingDef: props.postExplosionSpawnThingDef,
			postExplosionSpawnChance: props.postExplosionSpawnChance,
			postExplosionSpawnThingCount: props.postExplosionSpawnThingCount,
			applyDamageToExplosionCellsNeighbors: props.applyDamageToExplosionCellsNeighbors,
			preExplosionSpawnThingDef: props.preExplosionSpawnThingDef,
			preExplosionSpawnChance: props.preExplosionSpawnChance,
			preExplosionSpawnThingCount: props.preExplosionSpawnThingCount);
	}	
}}