namespace Plane.Geography
{
    public static class LocationExtensions
    {
        /// <summary>
        /// 计算在二维平面上从 <paramref name="l1"/> 到 <paramref name="l2"/> 的方向，单位为弧度。
        /// </summary>
        /// <param name="l1">出发点。</param>
        /// <param name="l2">目标点。</param>
        /// <returns>点 1 到点 2 的方向。</returns>
        public static double CalcDirection2D(this ILocation2D l1, ILocation2D l2)
            => GeographyUtils.CalcDirection2D(l1.Latitude, l1.Longitude, l2.Latitude, l2.Longitude);

        /// <summary>
        /// 计算在二维平面上从 <paramref name="l1"/> 到 (<paramref name="lat2"/>, <paramref name="lng2"/>) 的方向，单位为弧度。
        /// </summary>
        /// <param name="l1">出发点。</param>
        /// <param name="lat2">目标点的纬度。</param>
        /// <param name="lng2">目标点的经度。</param>
        /// <returns>点 1 到点 2 的方向。</returns>
        public static double CalcDirection2D(this ILocation2D l1, double lat2, double lng2)
            => GeographyUtils.CalcDirection2D(l1.Latitude, l1.Longitude, lat2, lng2);

        /// <summary>
        /// 计算空间中两点间的距离，单位为米。
        /// </summary>
        /// <param name="l1">点 1。</param>
        /// <param name="l2">点 2。</param>
        /// <returns>空间中两点间的距离。</returns>
        public static double CalcDistance(this ILocation l1, ILocation l2)
            => GeographyUtils.CalcDistance(l1, l2);

        /// <summary>
        /// 计算空间中两点间的距离，单位为米。
        /// </summary>
        /// <param name="l1">点 1。</param>
        /// <param name="lat2">点 2 的纬度。</param>
        /// <param name="lng2">点 2 的经度。</param>
        /// <param name="alt2">点 2 的高度。</param>
        /// <returns>空间中两点间的距离。</returns>
        public static double CalcDistance(this ILocation l1, double lat2, double lng2, double alt2)
            => GeographyUtils.CalcDistance(l1.Latitude, l1.Longitude, l1.Altitude, lat2, lng2, alt2);

        /// <summary>
        /// 计算二维平面上两个位置之间的距离，单位为米。
        /// </summary>
        /// <param name="l1">位置 1。</param>
        /// <param name="l2">位置 2。</param>
        /// <returns>平面上两点间的距离。</returns>
        public static double CalcDistance2D(this ILocation2D l1, ILocation2D l2)
            => GeographyUtils.CalcDistance2D(l1, l2);


        /// <summary>
        /// 计算二维平面上两个位置之间的距离，单位为米。
        /// </summary>
        /// <param name="lat2">点 2 的纬度。</param>
        /// <param name="lng2">点 2 的经度。</param>
        /// <returns>平面上两点间的距离。</returns>
        public static double CalcDistance2D(this ILocation2D l1, double lat2, double lng2)
            => GeographyUtils.CalcDistance2D(l1.Latitude, l1.Longitude, lat2, lng2);
        /// <summary>
        /// 计算在水平面上从指定点往指定方向移动指定距离后所在的点。
        /// </summary>
        /// <param name="loc1">出发点。</param>
        /// <param name="directionDegrees">移动方向，单位为角度。</param>
        /// <param name="distance">移动距离。</param>
        /// <returns>从指定点往指定方向移动指定距离后所在的点。</returns>
        public static ILocation2D CalcLatLngSomeMetersAway2D(this ILocation2D loc1, float directionDegrees, float distance)
            => GeographyUtils.CalcLatLngSomeMetersAway2D(loc1, directionDegrees, distance);

        /// <summary>
        /// 判断一个 <see cref="ILocation"/> 实例是否被认为是空值。
        /// </summary>
        /// <param name="loc"><see cref="ILocation"/> 实例。</param>
        /// <returns>若给定的位置被认为是空值，返回 true；否则返回 false。</returns>
        public static bool IsNullOrEmpty(this ILocation loc)
            => loc == null || (loc.Latitude == 0 && loc.Longitude == 0 && loc.Altitude == 0);
    }
}
