this.GoalType = "RIDE";
this.Version = 1;
this.DefaultPriority = 0.79;
this.RolePriorityBonus = 0.1;
this.MaxUsers_InUse(1);
this.MaxUsers_InProgress(2);

//////////////////////////////////////////////////////////////////////////
this.Schema = Schema();
this.Schema.BoardPositions = Validate.TableOf("vector3").Default({});
this.Schema.Seats = Validate.TableOf("vector3").Default({});
this.Schema.Stance = Validate.Enum("stand","crouch","prone").Default("stand");
this.Schema.SeatRadius = Validate.NumRange(30,200).Default(60);
// cs: can't check Vehicle because it relies on interface goals that are deferred.

//////////////////////////////////////////////////////////////////////////

this.InitNewGoal = function()
{
	this.MinRadius = 0;
	this.Schema.Check(this);
};

//////////////////////////////////////////////////////////////////////////

this.UpgradeVersion = function(Props)
{
	if(Props.Version == 1)
	{
		this.Vehicle = Props.Vehicle;
		this.BoardPositions = Props.BoardPositions;
		this.Seats = Props.Seats;
		this.Stance = Props.Stance;
		this.SeatRadius = Props.SeatRadius;

		if(!this.Schema.Check(this)
			|| !tableCount(this.BoardPositions)
			|| !tableCount(this.Seats) )
		{
			this.DisableGoal(true);
		}
	}
};

//////////////////////////////////////////////////////////////////////////

this.Render = function(editMode)
{
	offset2 = Vec3(0,0,64);

	if ( this.Vehicle )
	{
		vehGoal = GetGoal(this.Vehicle);
		if ( vehGoal )
		{
			vehEnt = vehGoal.GetEntity();
		}
	}

	while(this.RenderGoal)
	{
		goalName = this.GetName();
		goalBasePos = this.GetPosition();
		goalPos = goalBasePos + offset2;

		if(!this.ExtraDebugText)
		{
			this.ExtraDebugText = format("Stance: %s\n",this.Stance);

			if (this.Vehicle) {
				this.ExtraDebugText += format("Vehicle: %s\n",this.Vehicle);
			}
		}

		if ( this.Vehicle )
		{
			goal = GetGoal(this.Vehicle);
			if ( goal )
			{
				vehEnt = goal.GetEntity();
				if (!EntityIsValid(vehEnt))
				{
					sleep(2);
					return;
				}
			}
		}

		this.RenderDefault();

		if(this.IsDisabled())
		{
			DrawLine(goalPos,goalBasePos,COLOR.RED,2);
		}
		else
		{
			DrawLine(goalPos,goalBasePos,COLOR.GREEN,2);
		}

		if ( this.Vehicle )
		{
			if ( !vehGoal || !vehEnt )
			{
				vehGoal = GetGoal(this.Vehicle);
				if ( vehGoal )
				{
					vehEnt = vehGoal.GetEntity();
				}
			}

			if ( EntityIsValid(vehEnt) )
			{
				foreach ( id and board in this.BoardPositions )
				{
					// if it's excluded, draw it red
					if ( this.ExcludeIndexes && typeId(Util.GetTableKey(this.ExcludeIndexes, id)) != 0 ) {
						clr = COLOR.RED;
					}
					else if ( this.StartIndex == id && typeId(this.StartIndex) != 0 ) {
						clr = COLOR.GREEN;
					}
					else {
						clr = COLOR.BLUE;
					}

					boardPos = GetEntityWorldSpace( vehEnt, board );
					//boardPos = GroundPoint(boardPos);
					DrawLine(boardPos,boardPos+offset2,COLOR.BLUE,2);
					DrawText3d(boardPos+offset2,goalName + " board " + ToString(id),COLOR.WHITE,2,textDrawRadius);
				}

				foreach ( id and seat in this.Seats )
				{
					seatPos = GetEntityWorldSpace( vehEnt, seat );
					//seatPos = GroundPoint(seatPos);
					DrawLine(seatPos,seatPos+offset2,COLOR.BLUE,2);
					DrawText3d(seatPos+offset2,goalName + " seat " + ToString(id),COLOR.WHITE,2,textDrawRadius);
				}
			}
		}

		sleep(2);
	}
};

//////////////////////////////////////////////////////////////////////////

this.SaveToTable = function(SaveTable)
{
	// save the goal specific properties
	SaveTable.Vehicle = this.Vehicle;
	SaveTable.BoardPositions = this.BoardPositions;
	SaveTable.Seats = this.Seats;
	SaveTable.Stance = this.Stance;
	SaveTable.SeatRadius = this.SeatRadius;
};

//////////////////////////////////////////////////////////////////////////

this.Help = function()
{
	print(this.GoalType,"goal");
	print("Requires:");
	print("		vehicle - The goal name of the vehicle to ride");
	print("		board - Position(s) the bot should board from");
	print("		seat - Position(s) the bot should ride in");
	print("Optional:");
	print("		stance - stand, crouch, prone");
	print("		seatradius - default 60");
};

//////////////////////////////////////////////////////////////////////////

this.SetProperty = function(property, value)
{
	switch(property)
	{
		case "vehicle":
		{
			if ( value.Find("MOVER") != -1 && GetGoal(value) )
			{
				this.Vehicle = value;
			}
			else
			{
				print(this.GoalType, ": wrong type or goal not found, expecting mover" );
			}
		}
		case "board":
		{
			if ( value == "clearall" || value == "clear" )
			{
				tableClear(this.BoardPositions);
			}
			else
			{
				bGood = false;
				i = ToInt(value);
				if (typeId(i) == 1)
				{
					if(this.Vehicle)
					{
						g = GetGoal(this.Vehicle);
						if (g)
						{
							bGood = true;
							pPos = GetEntPosition(GetLocalEntity());
							offset = GetEntityLocalSpace(g.GetEntity(), pPos);

							// make em add sequentially
							n = tableCount(this.BoardPositions);
							if ( i < 0 || i > n )
							{
								i = n;
							}

							this.BoardPositions[ i ] = offset;
							print("Board Position",i,"set to",offset);
						}
					}
				}
				else
				{
					print(this.GoalType, ": Invalid offset index, expecting int");
				}

				if (!bGood)
				{
					print(this.GoalType, ": Vehicle must be set first");
				}
			}
		}
		case "seat":
		{
			if ( value == "clearall" || value == "clear" )
			{
				tableClear(this.Seats);
			}
			else
			{
				bGood = false;
				i = ToInt(value);
				if (typeId(i) == 1)
				{
					if(this.Vehicle)
					{
						g = GetGoal(this.Vehicle);
						if (g)
						{
							bGood = true;
							pPos = GetEntPosition(GetLocalEntity());
							offset = GetEntityLocalSpace(g.GetEntity(), pPos);

							// make em add sequentially
							n = tableCount(this.Seats);
							if ( i < 0 || i > n )
							{
								i = n;
							}

							this.Seats[ i ] = offset;
							print("Seat Position",i,"set to",offset);
						}
					}
				}
				else
				{
					print(this.GoalType, ": Invalid offset index, expecting int");
				}

				if (!bGood)
				{
					print(this.GoalType, ": Vehicle must be set first");
				}
			}
		}
		case "seatradius":
		{
			radius = ToInt(value);
			if(this.Schema.SeatRadius.CheckPrintErrors(this,radius))
			{
				this.SeatRadius = radius;
				print("SeatRadius set to " + radius);
			}
		}
		case "stance": // crouch, prone, default stand
		{
			if(this.Schema.Stance.CheckPrintErrors(this,value))
			{
				this.Stance = value;
			}
		}
		default:
		{
			print(this.GoalType, ": Invalid property:", property);
		}
	}

	// null the debug text so it will be rebuilt
	this.ExtraDebugText = null;
};

//////////////////////////////////////////////////////////////////////////

this.HudDisplay = function(window)
{
	this.CreateGuiFromSchema(this.Schema);
};
