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

namespace iStatVball3;

/*
 * Provides utility methods for working with the volleyball court common to both RallyFlow and Legacy interfaces. ONLY
 * utility code common to both engines is located here.
 */
public static class RecordCourt
{
	/* Constants */

	// Court Side (A = left/top, B = right/bottom)
	public enum Side
	{
		Unknown,
		SideA,
		SideB
	};
	
	// Court side keys
	public const string SideAKey = "sidea";
	public const string SideBKey = "sideb";

	// Court front/back row
	public enum Row
	{
		Unknown,
		Frontrow,
		Backrow
	};

	/* Methods */
	
	// Converts normalized X,Y position to court zone (1-6, 0 if out)
	public static int GetZone( double normX, double normY )
	{
		// Court A
		if ( normX is >= 0.0 and < 0.5 )
		{
			// Backrow (5-6-1)
			if ( normX < 0.33 )
			{
				if ( normY >= 0.0 )
				{
					if ( normY < 0.33 ) return 5;
					if ( normY < 0.67 ) return 6;
					if ( normY <= 1.0 ) return 1;
				}
			}
			// Frontrow (4-3-2)
			else
			{
				if ( normY >= 0.0 )
				{
					if ( normY < 0.33 ) return 4;
					if ( normY < 0.67 ) return 3;
					if ( normY <= 1.0 ) return 2;
				}
			}
		}
		// Court B
		else if ( normX is > 0.5 and <= 1.0 )
		{
			// Frontrow (2-3-4)
			if ( normX < 0.67 )
			{
				if ( normY >= 0.0 )
				{
					if ( normY < 0.33 ) return 2;
					if ( normY < 0.67 ) return 3;
					if ( normY <= 1.0 ) return 4;
				}
			}
			// Backrow (1-6-5)
			else
			{
				if ( normY >= 0.0 )
				{
					if ( normY < 0.33 ) return 1;
					if ( normY < 0.67 ) return 6;
					if ( normY <= 1.0 ) return 5;
				}
			}
		}

		// Out-of-bounds
		return 0;
	}

	/* Sides */

	// Converts court side LUT key to internal enum constant
	public static Side SideFromKey( string key )
	{
		return (key == SideAKey) ? Side.SideA : Side.SideB;
	}

	// Converts court side enum constant to LUT key
	public static string KeyFromSide( Side side )
	{
		return (side == Side.SideA) ? SideAKey : SideBKey;
	}

	// Returns opposite side of court from specified side
	public static Side SwitchSide( Side side )
	{
		return (side == Side.SideA) ? Side.SideB : Side.SideA;
	}
	
	/* Normalization */

	// Takes point already normalized for device/orientation and further normalizes it to specified side
	public static Point NormalizeSide( Point pt, Side side = Side.SideA )
	{
		return NormalizeSide( pt.X, pt.Y, side );
	}

	// Further normalizes x,y to be on specified side
	public static Point NormalizeSide( double x, double y, Side side = Side.SideA )
	{
		double normX = x;
		double normY = y;

		// Normalize to Side A
		if ( side == Side.SideA )
		{
			// Convert B to A
			if ( x > 0.5 )
			{
				normX = (0.5 - (x - 0.5));
				normY = (1.0 - y);
			}
			// Convert net
			else if ( Math.Abs( x - 0.5 ) < 0.01 )
			{
				normY = (1.0 - y);
			}
			// Already A
		}
		// Normalize to Side B
		else
		{
			// Convert A to B
			if ( x < 0.5 )
			{
				normX = (1.0 - x);
				normY = (1.0 - y);
			}
			// Convert net
			else if ( Math.Abs( x - 0.5 ) < 0.01 )
			{
				normY = (1.0 - y);
			}
			// Already B
		}

		return new Point( normX, normY );
	}
}

//
