using NpgsqlTypes;
using System;
using System.Collections;

public static partial class PostgreSQLTypesExtensions
{
    /// <summary>
    /// 测量两个经纬度的距离，返回单位：米
    /// </summary>
    /// <param name="that">经纬坐标1</param>
    /// <param name="point">经纬坐标2</param>
    /// <returns>返回距离（单位：米）</returns>
    public static double Distance(this NpgsqlPoint that, NpgsqlPoint point)
    {
        double radLat1 = (double)(that.Y) * Math.PI / 180d;
        double radLng1 = (double)(that.X) * Math.PI / 180d;
        double radLat2 = (double)(point.Y) * Math.PI / 180d;
        double radLng2 = (double)(point.X) * Math.PI / 180d;
        return 2 * Math.Asin(Math.Sqrt(Math.Pow(Math.Sin((radLat1 - radLat2) / 2), 2) + Math.Cos(radLat1) * Math.Cos(radLat2) * Math.Pow(Math.Sin((radLng1 - radLng2) / 2), 2))) * 6378137;
    }

#if net40
#else
    /// <summary>
    /// 测量两个经纬度的距离，返回单位：米
    /// </summary>
    /// <param name="that">经纬坐标1</param>
    /// <param name="point">经纬坐标2</param>
    /// <returns>返回距离（单位：米）</returns>
    public static double Distance(this Npgsql.LegacyPostgis.PostgisPoint that, Npgsql.LegacyPostgis.PostgisPoint point)
    {
        double radLat1 = (double)(that.Y) * Math.PI / 180d;
        double radLng1 = (double)(that.X) * Math.PI / 180d;
        double radLat2 = (double)(point.Y) * Math.PI / 180d;
        double radLng2 = (double)(point.X) * Math.PI / 180d;
        return 2 * Math.Asin(Math.Sqrt(Math.Pow(Math.Sin((radLat1 - radLat2) / 2), 2) + Math.Cos(radLat1) * Math.Cos(radLat2) * Math.Pow(Math.Sin((radLng1 - radLng2) / 2), 2))) * 6378137;
    }
    
    public static NpgsqlRange<T> ToNpgsqlRange<T>(this string that)
    {
        var s = that;
        if (string.IsNullOrEmpty(s) || s == "empty") return NpgsqlRange<T>.Empty;
        string s1 = s.Trim('(', ')', '[', ']');
        string[] ss = s1.Split(new char[] { ',' }, 2);
        if (ss.Length != 2) return NpgsqlRange<T>.Empty;
        T t1 = default(T);
        T t2 = default(T);
        if (!string.IsNullOrEmpty(ss[0])) t1 = (T)Convert.ChangeType(ss[0], typeof(T));
        if (!string.IsNullOrEmpty(ss[1])) t2 = (T)Convert.ChangeType(ss[1], typeof(T));
        return new NpgsqlRange<T>(t1, s[0] == '[', s[0] == '(', t2, s[s.Length - 1] == ']', s[s.Length - 1] == ')');
    }
#endif

    public static string To1010(this BitArray ba)
    {
        char[] ret = new char[ba.Length];
        for (int a = 0; a < ba.Length; a++) ret[a] = ba[a] ? '1' : '0';
        return new string(ret);
    }

    /// <summary>
    /// 将 1010101010 这样的二进制字符串转换成 BitArray
    /// </summary>
    /// <param name="_1010Str">1010101010</param>
    /// <returns></returns>
    public static BitArray ToBitArray(this string _1010Str)
    {
        if (_1010Str == null) return null;
        BitArray ret = new BitArray(_1010Str.Length);
        for (int a = 0; a < _1010Str.Length; a++) ret[a] = _1010Str[a] == '1';
        return ret;
    }
}