/* 
 * Copyright (c)2009-2025 DemiVision, LLC. All Rights Reserved. The information 
 * herein is the CONFIDENTIAL and PROPRIETARY information of DemiVision, LLC. 
 */

namespace iStatVball3;

/*
 * Provides ActionMenu configuration for all RallyFlow state machine states. Primarily used to separate configuration
 * code from the state machine. 
 */ 
public class RallyUI
{
	/* Constants */
	
	// Recording interface touch gestures
	public enum TouchType
	{
		Tap,
		Swipe,
		LongPress
	}

	/* Fields */
	private readonly RallyState sm;
	private readonly ActionOverlay overlay;

	/* Methods */
	public RallyUI( RallyState sm, ActionOverlay overlay )
	{
		this.sm = sm;
		this.overlay = overlay;
	}

	/* Action Menus */

	// Serve
	public void ShowServe( double x, double y, TouchType type, Action<RecordData> callback )
	{
		// Long press NA
		overlay.ShowServe( x, y, new ActionConfig
		{
			IsTeam1 = sm.Team1HasBall(),        // Same side start
			Action = Stats.ServeKey,
			Override = (type == TouchType.Swipe),
			Selected = callback
		});
	}

	// Receive
	public void ShowReceive( double x, double y, TouchType type, Action<RecordData> callback )
	{
		// TRE
		if ( type == TouchType.LongPress )
		{
			overlay.ShowError( x, y, new ActionConfig
			{
				Action = Stats.ReceiveKey,
				Error = "team",
				IsTeamError = true,
				Selected = callback
			});
		}
		// Normal contact
		else
		{
			overlay.ShowTeam( x, y, new ActionConfig
			{
				IsTeam1 = !sm.Team1HasBall(),       // From opposite side serve
				Action = Stats.ReceiveKey,
				Modifiers = "pass",
				Modifier = "bump",
				Override = (type == TouchType.Swipe),
				Selected = callback
			});
		}
	}

	// First Ball
	public void ShowFirst( double x, double y, TouchType type, Action<RecordData> callback, bool touch = false )
	{
		// Team error
		if ( type == TouchType.LongPress )
		{
			overlay.ShowError( x, y, new ActionConfig
			{
				Action = Stats.FirstKey,
				Error = "team",
				IsTeamError = true,
				Selected = callback
			});
		}
		// Normal contact
		else
		{
			bool team1HasBall = sm.Team1HasBall();

			overlay.ShowTeam( x, y, new ActionConfig
			{
				IsTeam1 = touch ? team1HasBall : !team1HasBall,     // Might be touch off overpass
				Action = Stats.FirstKey,
				Modifiers = "pass",
				Modifier = "bump",
				Override = (type == TouchType.Swipe),
				Selected = callback
			});
		}
	}

	// Second Ball
	public void ShowSecond( double x, double y, TouchType type, Action<RecordData> callback, Action<RecordData> prevCallback )
	{
		// Passer error
		if ( type == TouchType.LongPress )
		{
			overlay.ShowError( x, y, new ActionConfig
			{
				Action = Stats.SecondKey,
				Error = "pass",
				IsTeamError = true,
				Selected = prevCallback
			});
		}
		// Normal contact
		else
		{
			bool isTeam1 = sm.Team1HasBall();

			// Using 0-3 or 0-4 pass ratings?
			bool pass03 = Shell.Settings.IsPass03;

			// Automatic default pass rating based on location
			int rating = sm.GetDefaultRating( x, y );

			Stat prevStat = sm.PreviousStat();

			// Determine if previous contact was by setter
			Player prevPlayer = prevStat?.Player;
			Player setter = sm.GetSetter( isTeam1 )?.Player;

			bool prevSetter = (prevPlayer != null) && prevPlayer.Equals( setter );

			overlay.ShowTeam( x, y, new ActionConfig
			{
				IsTeam1 = isTeam1,				// From same side 1st
				Action = Stats.SecondKey,
				PrevAction = prevStat?.Action,
				Selectors = "second",
				Ratings = pass03 ? Settings.Pass03Key : Settings.Pass04Key,
				Modifiers = "set",
				Modifiers2 = "attack2",
				Selector = "set",
				Rating = rating.ToString(),
				Modifier = "two",
				Modifier2 = "dump",
				Override = (type == TouchType.Swipe),
				PrevSetter = prevSetter,
				Selected = callback
			});
		}
	}

	// Third Ball
	public void ShowThird( double x, double y, TouchType type, Action<RecordData> callback, Action<RecordData> prevCallback )
	{
		// Setter error
		if ( type == TouchType.LongPress )
		{
			overlay.ShowError( x, y, new ActionConfig
			{
				Action = Stats.ThirdKey,
				Error = "set",
				IsTeamError = true,
				Selected = prevCallback
			});
		}
		// Normal contact
		else
		{
			Stat prevStat = sm.PreviousStat();

			overlay.ShowTeam( x, y, new ActionConfig
			{
				IsTeam1 = sm.Team1HasBall(),        // From same side 2nd
				Action = Stats.ThirdKey,
				PrevAction = prevStat?.Action,
				Selectors = "third",
				Ratings = "set",
				Modifiers = "attack3",
				Modifiers2 = "free",
				Selector = "attack",
				Rating = "3",
				Modifier = "spike",
				Modifier2 = "bump",
				Override = (type == TouchType.Swipe),
				Selected = callback
			});
		}
	}

	// Defense
	public void ShowDefense( double x, double y, TouchType type, Action<RecordData> callback, bool touch = false )
	{
		// Team error
		if ( type == TouchType.LongPress )
		{
			overlay.ShowError( x, y, new ActionConfig
			{
				Action = Stats.DefenseKey,
				Error = "team",
				IsTeamError = true,
				Selected = callback
			});
		}
		// Normal contact
		else
		{
			bool team1HasBall = sm.Team1HasBall();

			overlay.ShowTeam( x, y, new ActionConfig
			{
				IsTeam1 = touch ? team1HasBall : !team1HasBall,     // Might be touch off block
				Action = Stats.DefenseKey,
				Modifiers = "defense",
				Modifier = "bump",
				Override = (type == TouchType.Swipe),
				Selected = callback
			});
		}
	}

	// Putback
	public void ShowPutback( double x, double y, TouchType type, Action<RecordData> callback )
	{
		// Team error
		if ( type == TouchType.LongPress )
		{
			overlay.ShowError( x, y, new ActionConfig
			{
				Action = Stats.PutbackKey,
				Error = "team",
				IsTeamError = true,
				Selected = callback
			});
		}
		// Normal contact
		else
		{
			overlay.ShowTeam( x, y, new ActionConfig
			{
				IsTeam1 = !sm.Team1HasBall(),		// From opposite block
				Action = Stats.PutbackKey,
				Modifiers = "pass",
				Modifier = "bump",
				Override = (type == TouchType.Swipe),
				Selected = callback
			});
		}
	}

	// Free Ball
	public void ShowFreeball( double x, double y, TouchType type, Action<RecordData> callback )
	{
		// Team error
		if ( type == TouchType.LongPress )
		{
			overlay.ShowError( x, y, new ActionConfig
			{
				Action = Stats.FreeballKey,
				Error = "team",
				IsTeamError = true,
				Selected = callback
			});
		}
		// Normal contact
		else
		{
			overlay.ShowTeam( x, y, new ActionConfig
			{
				IsTeam1 = !sm.Team1HasBall(),		// From opposite free
				Action = Stats.FreeballKey,
				Modifiers = "pass",
				Modifier = "bump",
				Override = (type == TouchType.Swipe),
				Selected = callback
			});
		}
	}

	// Overpass
	public void ShowOver( double x, double y, TouchType type, Action<RecordData> callback )
	{
		// Long press NA
		overlay.ShowBlock( x, y, new ActionConfig
		{
			IsTeam1 = !sm.Team1HasBall(),           // From opposite over
			Action = Stats.OverpassKey,
			Modifiers = "over",
			Modifier = "spike",
			Override = (type == TouchType.Swipe),
			Selected = callback
		}, false );
	}

	// Block
	public void ShowBlock( double x, double y, TouchType type, Action<RecordData> callback )
	{
		// Long press NA
		overlay.ShowBlock( x, y, new ActionConfig
		{
			IsTeam1 = !sm.Team1HasBall(),           // From opposite attack
			Action = Stats.BlockKey,
			Override = (type == TouchType.Swipe),
			Selected = callback
		}, true );
	}

	// Block (post-action player selection)
	public void ShowPostBlock( bool isTeam1, double x, double y, Action<RecordData> callback )
	{
		// Only for quick select
		overlay.ShowBlock( x, y, new ActionConfig
		{
			IsTeam1 = isTeam1,
			Action = Stats.BlockKey,
			Override = false,
			Selected = callback
		}, true, true );
	}

	// Net, Antennae, Out, 4 Hits
	public void ShowError( Court.Region region, double x, double y, TouchType type, Action<RecordData> callback )
	{
		string error = null;

		// Net
		if ( region == Court.Region.Net )
		{
			error = Stats.NetKey;
		}
		// Antennae
		else if ( region == Court.Region.Antennae )
		{
			error = Stats.AntKey;
		}
		// Same side out
		else if ( region == Court.Region.OutZone )
		{
			error = Stats.OutKey;
		}
		// Opposite side out
		else if ( Court.OppositeOut( sm.BallSide, region ) )
		{
			error = Stats.OutKey;
		}
		// Same side in
		else if ( Court.SameSide( sm.BallSide, region ) )
		{
			// Invalid serve, else 4 hits
			error = sm.State == "serve" ? Stats.OutKey : Stats.FourKey;
		}

		// Show error menu
		if ( error != null )
		{
			overlay.ShowError( x, y, new ActionConfig
			{
				Error = error,
				IsTeamError = false,
				Override = (type == TouchType.Swipe),
				Selected = callback
			});
		}
	}

	// Invalid marker
	public void ShowInvalid( double x, double y )
	{
		overlay.ShowInvalid( x, y );
	}
}

//
