using System;

namespace Decal.Adapter.Wrappers;

public class CoordsObject
{
	private double myNorthSouth;

	private double myEastWest;

	/// <summary>
	/// The north or south component of these coordinates. North is 
	/// positive and south is negative.
	/// </summary>
	public double NorthSouth => myNorthSouth;

	/// <summary>
	/// The east or west component of these coordinates. East is positive 
	/// and west is negative.
	/// </summary>
	public double EastWest => myEastWest;

	public CoordsObject(double northSouth, double eastWest)
	{
		myNorthSouth = northSouth;
		myEastWest = eastWest;
	}

	/// <summary>
	/// Calculates the straight-line distance between these coordinates 
	/// and the given coordinates.
	/// </summary>
	/// <param name="destination">The coordinates to calculate the 
	/// 	distance to.</param>
	/// <returns>The distance between these coordinates and the given 
	/// 	coordinates.</returns>
	public double DistanceToCoords(CoordsObject destination)
	{
		if (destination == null)
		{
			throw new ArgumentNullException("destination");
		}
		double num = myNorthSouth - destination.myNorthSouth;
		double num2 = myEastWest - destination.myEastWest;
		return Math.Sqrt(num * num + num2 * num2);
	}

	/// <summary>
	/// Calculates the angle from these coordinates to the given 
	/// coordinates, in degrees.  North is 0, east is 90, south is 180, 
	/// and west is 270.
	/// </summary>
	/// <param name="destination">The coordinates to calculate the 
	/// 	angle to.</param>
	/// <returns>The angle between these coordinates and the given 
	/// 	coordinates.</returns>
	public double AngleToCoords(CoordsObject destination)
	{
		return 180.0 / Math.PI * AngleToCoordsRadians(destination);
	}

	/// <summary>
	/// Calculates the angle from these coordinates to the given 
	/// coordinates, in radians.  North is 0, east is pi/2, south is pi, 
	/// and west is 3*pi/2.
	/// </summary>
	/// <param name="destination"></param>
	/// <returns></returns>
	public double AngleToCoordsRadians(CoordsObject destination)
	{
		if (destination == null)
		{
			throw new ArgumentNullException("destination");
		}
		double num = Math.Atan2(destination.myEastWest - myEastWest, destination.myNorthSouth - myNorthSouth);
		if (num < 0.0)
		{
			num += Math.PI * 2.0;
		}
		return num;
	}

	/// <summary>Formats the coordinates like "0.0N, 0.0E"</summary>
	/// <returns>The formatted coordinate string.</returns>
	public override string ToString()
	{
		return ToString("0.0");
	}

	/// <summary>
	/// Formats the coordinates using the number style you choose to 
	/// format the NorthSouth and EastWest numbers.
	/// </summary>
	/// <param name="numberFormat">The format for the NorthSouth and 
	/// 	EastWest numbers. This can be any format string used by
	/// 	double.ToString(). E.g., use "0.00" for 2-digit precision on 
	/// 	the coordinates.</param>
	/// <returns>The formatted coordinate string.</returns>
	public string ToString(string numberFormat)
	{
		return Math.Abs(myNorthSouth).ToString(numberFormat) + ((myNorthSouth >= 0.0) ? "N" : "S") + ", " + Math.Abs(myEastWest).ToString(numberFormat) + ((myEastWest >= 0.0) ? "E" : "W");
	}

	public override bool Equals(object obj)
	{
		if (obj is CoordsObject)
		{
			CoordsObject coordsObject = (CoordsObject)obj;
			if (coordsObject.myNorthSouth == myNorthSouth)
			{
				return coordsObject.myEastWest == myEastWest;
			}
			return false;
		}
		return false;
	}

	public bool Equals(CoordsObject obj)
	{
		if (obj == null)
		{
			return false;
		}
		if (obj.myNorthSouth == myNorthSouth)
		{
			return obj.myEastWest == myEastWest;
		}
		return false;
	}

	public override int GetHashCode()
	{
		return myNorthSouth.GetHashCode() ^ myEastWest.GetHashCode();
	}

	public static bool operator ==(CoordsObject a, CoordsObject b)
	{
		if (object.Equals(a, null))
		{
			return object.Equals(b, null);
		}
		return a.Equals(b);
	}

	public static bool operator !=(CoordsObject a, CoordsObject b)
	{
		return !(a == b);
	}
}
