using System;
using UnityEngine;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using System.Collections.Generic;


public static class SerializeUtil
{
    private static Type StringType = typeof(string);

    static SerializeUtil()
    {
        JsonConvert.DefaultSettings = new Func<JsonSerializerSettings>(() => { return DefaultUseJsonSettings; });
    }

    private static JsonSerializerSettings DefaultUseJsonSettings = new JsonSerializerSettings
    {
        Formatting = Formatting.None,


        DateFormatHandling = DateFormatHandling.MicrosoftDateFormat,

        DateFormatString = "yyyy/MM/dd hh:mm:ss",
    };

    private static JsonSerializerSettings JsonIndentedSettings = new JsonSerializerSettings
    {
        Formatting = Formatting.Indented,


        DateFormatHandling = DateFormatHandling.MicrosoftDateFormat,

        DateFormatString = "yyyy/MM/dd hh:mm:ss",
    };

    private static JsonSerializer JObjectJsonSerializer = new JsonSerializer
    {
        Formatting = Formatting.None,


        DateFormatHandling = DateFormatHandling.MicrosoftDateFormat,

        DateFormatString = "yyyy/MM/dd hh:mm:ss",
    };

    public static string ToRawJson(object obj)
    {
        return JsonConvert.SerializeObject(obj, StringType, DefaultUseJsonSettings);
    }

    public static string ToJson(object obj)
    {
        return JsonConvert.SerializeObject(obj, DefaultUseJsonSettings);
    }

    public static string ToJsonIndented(object obj)
    {
        return JsonConvert.SerializeObject(obj, JsonIndentedSettings);
    }

    public static string ToJson(object obj, Type type)
    {
        return JsonConvert.SerializeObject(obj, type, DefaultUseJsonSettings);
    }

    public static string ToJsonIndented(object obj, Type type)
    {
        return JsonConvert.SerializeObject(obj, type, JsonIndentedSettings);
    }

    public static string ToJson<T>(object obj)
    {
        return ToJson(obj, typeof(T));
    }

    public static string ToJsonIndented<T>(object obj)
    {
        return JsonConvert.SerializeObject(obj, typeof(T), JsonIndentedSettings);
    }

    public static Dictionary<string, object> ToDicLocal(string json)
    {
        JObject o_jobject = GetJObjectByJson(json);
        if (o_jobject == null || o_jobject["value"] == null)
        {
            return null;
        }

        string dicJson = o_jobject["value"].ToString();
        return JsonConvert.DeserializeObject<Dictionary<string, object>>(dicJson);
    }

    public static Dictionary<string, object> ToDicClient(string json)
    {
        JObject o_jobject = GetJObjectByJson(json);
        if (o_jobject == null || o_jobject["version"] == null)
        {
            return null;
        }

        string dicJson = o_jobject.ToString();
        return JsonConvert.DeserializeObject<Dictionary<string, object>>(dicJson);
    }

    public static T ToObject<T>(string json)
    {
        return JsonConvert.DeserializeObject<T>(json);
    }

    public static T ReplaceJobject<T>(T obj, JObject serverJson)
    {
        JObject o_jobject = GetJObjectByObject(obj);
        string newJson = ReplaceJObject(o_jobject, serverJson);
        return ToObject<T>(newJson);
    }

    private static string ReplaceJObject(JObject o_jobject, JObject serverJson)
    {
        foreach (JProperty newItem in o_jobject.Children())
        {
            string newKey = newItem.Name;
            JToken newValue = newItem.Value;
            if (serverJson[newKey] != null)
            {
                newValue = serverJson[newKey];
                newItem.Value = newValue;
            }
        }

        return o_jobject.ToString();
    }

    public static object ToObject(string json, Type type)
    {
        return JsonConvert.DeserializeObject(json, type);
    }

    public static JObject GetJObjectByJson(string json)
    {
        return JObject.Parse(json);
    }

    public static JObject GetJObjectByObject(object obj)
    {
        return JObject.FromObject(obj, JObjectJsonSerializer);
    }

    public static string UnityToJson(object obj)
    {
        return JsonUtility.ToJson(obj);
    }

    public static object UnityToObject(string json)
    {
        return JsonUtility.FromJson<object>(json);
    }
}

#region 自定义Json格式转换器

public class JsonConverter_Vector2 : JsonConverter
{
    private static Type CurrType = typeof(Vector2);

    public override bool CanConvert(Type objectType)
    {
        return objectType == CurrType;
    }

    public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
    {
        Vector2 v = (Vector2)value;
        serializer.Serialize(writer, "(" + v.x + "," + v.y + ")");
    }

    public override object ReadJson(JsonReader reader, Type objectType, object existingValue,
        JsonSerializer serializer)
    {
        string[] vStr = reader.Value.ToString().Split(',');
        vStr[0] = vStr[0].Replace("(", string.Empty);
        vStr[1] = vStr[1].Replace(")", string.Empty);
        return new Vector2(float.Parse(vStr[0]), float.Parse(vStr[1]));
    }
}

public class JsonConverter_Vector3 : JsonConverter
{
    private static Type CurrType = typeof(Vector3);

    public override bool CanConvert(Type objectType)
    {
        return objectType == CurrType;
    }

    public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
    {
        Vector3 v = (Vector3)value;
        serializer.Serialize(writer, "(" + v.x + "," + v.y + "," + v.z + ")");
    }

    public override object ReadJson(JsonReader reader, Type objectType, object existingValue,
        JsonSerializer serializer)
    {
        string[] vStr = reader.Value.ToString().Split(',');
        vStr[0] = vStr[0].Replace("(", string.Empty);
        vStr[1] = vStr[1];
        vStr[2] = vStr[2].Replace(")", string.Empty);
        return new Vector3(float.Parse(vStr[0]), float.Parse(vStr[1]), float.Parse(vStr[2]));
    }
}

public class JsonConverter_Vector4 : JsonConverter
{
    private static Type CurrType = typeof(Vector4);

    public override bool CanConvert(Type objectType)
    {
        return objectType == CurrType;
    }

    public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
    {
        Vector4 v = (Vector4)value;
        serializer.Serialize(writer, "(" + v.x + "," + v.y + "," + v.z + "," + v.w + ")");
    }

    public override object ReadJson(JsonReader reader, Type objectType, object existingValue,
        JsonSerializer serializer)
    {
        string[] vStr = reader.Value.ToString().Split(',');
        vStr[0] = vStr[0].Replace("(", string.Empty);
        vStr[1] = vStr[1];
        vStr[2] = vStr[2];
        vStr[3] = vStr[3].Replace(")", string.Empty);
        return new Vector4(float.Parse(vStr[0]), float.Parse(vStr[1]), float.Parse(vStr[2]), float.Parse(vStr[3]));
    }
}

#endregion