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


namespace Verse.AI{
public class JobDriver_HaulToContainer : JobDriver
{
	//Constants
	private const TargetIndex CarryThingIndex = TargetIndex.A;
	private const TargetIndex DestIndex = TargetIndex.B;
	private const TargetIndex PrimaryDestIndex = TargetIndex.C;

	private Thing Container { get { return (Thing)job.GetTarget(DestIndex); } }

    public override string GetReport()
	{
		Thing hauledThing = null;
		if( pawn.CurJob == job && pawn.carryTracker.CarriedThing != null )
			hauledThing = pawn.carryTracker.CarriedThing;
		else
			hauledThing = TargetThingA;

		if( hauledThing == null || !job.targetB.HasThing )
			return "ReportHaulingUnknown".Translate();
		else
			return "ReportHaulingTo".Translate( hauledThing.LabelCap, job.targetB.Thing.LabelShort );
	}

	public override bool TryMakePreToilReservations()
	{
		pawn.ReserveAsManyAsPossible(job.GetTargetQueue(CarryThingIndex), job);
		pawn.ReserveAsManyAsPossible(job.GetTargetQueue(DestIndex), job);

		return pawn.Reserve(job.GetTarget(CarryThingIndex), job)
			&& pawn.Reserve(job.GetTarget(DestIndex), job);
	}

	protected override IEnumerable<Toil> MakeNewToils()
	{
		this.FailOnDestroyedOrNull( CarryThingIndex );
		this.FailOnDestroyedNullOrForbidden( DestIndex );
		this.FailOn(() => TransporterUtility.WasLoadingCanceled(Container));

		Toil getToHaulTarget = Toils_Goto.GotoThing( CarryThingIndex, PathEndMode.ClosestTouch )
			.FailOnSomeonePhysicallyInteracting(CarryThingIndex);
		yield return getToHaulTarget;

		yield return Toils_Construct.UninstallIfMinifiable(CarryThingIndex)
			.FailOnSomeonePhysicallyInteracting(CarryThingIndex);

		yield return Toils_Haul.StartCarryThing(CarryThingIndex, subtractNumTakenFromJobCount: true);

		yield return Toils_Haul.JumpIfAlsoCollectingNextTargetInQueue( getToHaulTarget, CarryThingIndex );

		Toil carryToContainer = Toils_Haul.CarryHauledThingToContainer();
		yield return carryToContainer;

		yield return Toils_Goto.MoveOffTargetBlueprint(DestIndex);

		yield return Toils_Construct.MakeSolidThingFromBlueprintIfNecessary(DestIndex, PrimaryDestIndex);

		yield return Toils_Haul.DepositHauledThingInContainer(DestIndex, PrimaryDestIndex);

		yield return Toils_Haul.JumpToCarryToNextContainerIfPossible(carryToContainer, PrimaryDestIndex);
	}
}}

