using System;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using System.Security.Cryptography;
using System.Text;
using TMPro;
using Unity.Collections.LowLevel.Unsafe;
using Unity.VisualScripting;
using Unity.VisualScripting.FullSerializer;
using UnityEngine;
using UnityEngine.Networking;
using UnityEngine.UI;

class DeviceAdaptationInfo
{
    public float x = 0;
    public float y = 0;
    public float width = 0;
    public float height = 0;
    public void init(RectTransform rectTransform)
    {
        x = rectTransform.localPosition.x;
        y = rectTransform.localPosition.y;
        width = rectTransform.rect.width;
        height = rectTransform.rect.height;
    }
}
public class utilsTools
{
    private static int isPhone = 0;
    private static Vector2 displaySize = new Vector2(0,0);
    private static Vector2 shejiSize = new Vector2(750, 1624);
    private static Vector2 nowSceneSize = new Vector2(0, 0);
    public static Vector2 NowSceneSize
    {
        get
        {
            return nowSceneSize;
        }
    }
    private static System.Random random = new System.Random();
    private static Dictionary<string,System.Object> globalDatas = new Dictionary<string,System.Object>();
    static utilsTools()
    {
        int width = Screen.width;
        int height = Screen.height;
        if(width < height)
        {
            nowSceneSize = new Vector2(width, height);
        }
        else
        {
            nowSceneSize = new Vector2(height, width);
        }
    }
    public static T getGDataByKey<T>(string key,T defvalue)
    {
        if (globalDatas.ContainsKey(key))
        {
            return (T)globalDatas[key];
        }
        return defvalue;
    }
    public static void setGDataByKey(string key,System.Object obj)
    {
        if(globalDatas.ContainsKey(key))
        {
            globalDatas[key] = obj;
        }
        else
        {
            globalDatas.Add(key, obj);
        }
    }
    public static string getGameSceneName()
    {
        if (Boolean.Parse(getGDataByKey<string>("showBackPlayer", "false")) == false)
        {
            return "Scenes/gameScene";
        }
        else
            return "Scenes/replayeScene";


    }
    public static bool removeGDataByKey(string key)
    {
        if( globalDatas.ContainsKey(key))
        {
            globalDatas.Remove(key);
            return true;
        }
        return false;
    }
    public static bool ContainsKeyGDataByKey(string key)
    {
        return globalDatas.ContainsKey(key);
    }
    public static bool IsPhone
    {
        get { 
            if(isPhone == 0)
            {
                switch (Application.platform)
                {
                    case RuntimePlatform.WindowsEditor:
                    case RuntimePlatform.WindowsPlayer:
                    case RuntimePlatform.WebGLPlayer:
                    case RuntimePlatform.OSXEditor:
                    case RuntimePlatform.OSXPlayer:
                        isPhone = 2;
                        break;
                    case RuntimePlatform.Android:
                    case RuntimePlatform.IPhonePlayer:
                        isPhone = 1;
                        break;
                    default:
                        isPhone = 1;
                        break;
                }
            }
            return isPhone == 1;
        }
    }
    public static bool IsWin
    {
        get
        {
            switch (Application.platform)
            {
                case RuntimePlatform.WindowsEditor:
                case RuntimePlatform.WindowsPlayer:
                    return true;
                default: return false;
            }
        }
    }
    public static Vector2 DisplaySize
    {
        get
        {
            return displaySize;
        }
        set
        {
            displaySize = nowSceneSize;
        }
    }
    
    public static Dictionary<String, GameObject> dynamicMount = new Dictionary<string, GameObject>();
    public static bool addTimer_Sec(GameObject gameObject, string name, timeEventBack back, double intervalLen, uint loopRepetitionLen = 1)
    {
        Itimer itimer = gameObject.GetComponent<Itimer>();
        if(itimer == null)
        {
            gameObject.AddComponent<Itimer>();
            itimer = gameObject.GetComponent<Itimer>();
        }
        loopRepetitionLen--;
        return itimer.addTimer_Sec(name, back, intervalLen, loopRepetitionLen);
    }
    public static bool addTimer_Update(GameObject gameObject,string name, timeEventBack back, int intervalLen = 0, int loopRepetitionLen = 1)
    {
        Itimer itimer = gameObject.GetComponent<Itimer>();
        if (itimer == null)
        {
            gameObject.AddComponent<Itimer>();
            itimer = gameObject.GetComponent<Itimer>();
        }
        loopRepetitionLen--;
        return itimer.addTimer_Update(name, back, intervalLen, loopRepetitionLen);
    }
    public static void delTimeHandler(GameObject gameObject,string name)
    {
        Itimer itimer = gameObject.GetComponent<Itimer>();
        if(itimer != null)
        {
            itimer.delTimer(name);
        }
    }
    public static bool ContainsKey(GameObject gameObject,string key)
    {
        IRunUserData runUserData = gameObject.GetComponent<IRunUserData>();
        if (runUserData == null)
            return false;
        return runUserData.ContainsKey(key);
    }
    public static bool setUserData(GameObject gameObject, string key, System.Object value)
    {
        IRunUserData runUserData = gameObject.GetComponent<IRunUserData>();
        if(runUserData == null)
        {
            runUserData = gameObject.AddComponent<IRunUserData>();
        }
        runUserData.setData(key, value);
        return false;
    }
    public static bool getUserData<T>(GameObject gameObject,string key,out System.Object value, System.Object defvalue)
    {
        IRunUserData runUserData = gameObject.GetComponent<IRunUserData>();
        if (runUserData == null)
        {
            runUserData = gameObject.AddComponent<IRunUserData>();
            value = defvalue;
            return false;
        }
        return runUserData.getUserData<T>(key,out value, defvalue);
    }
    public static bool getUserData<T>(GameObject gameObject, string key, out T value, T defvalue)
    {
        System.Object newvalue = defvalue;
        System.Object newdef = defvalue;
        if(getUserData<T>(gameObject,key,out newvalue,defvalue) == false)
        {
            value = defvalue;
            return false;
        }
        else
        {
            value = (T)newvalue;
            return true;
        }        
    }
    public static void delUserDataByKey(GameObject gameObject,string key)
    {
        IRunUserData runUserData = gameObject.GetComponent<IRunUserData>();
        if (runUserData == null) return;
        runUserData.delDataByKey(key);
    }
    public static bool ContainsName(MonoBehaviour monoBehaviour,string name)
    {
        return IRunEventManages.ContainsName(monoBehaviour, name);
    }
    public static bool onEvent(MonoBehaviour monoBehaviour,string name)
    {
        return IRunEventManages.on(monoBehaviour, name);
    }
    public static bool unOnEvent(MonoBehaviour monoBehaviour,string name)
    {
        return IRunEventManages.unOn(monoBehaviour, name);
    }
    public static bool sendEvent(string name)
    {
        return IRunEventManages.send(name, null,null);
    }
    public static bool sendEventUObjects(string name,List<UnityEngine.Object> objects,List<System.Object> list = null){
        return IRunEventManages.send(name, objects, list);
    }
    public delegate bool YuanHuanBackHandler(int x, int y, int idx);
    public static int Ring(int startX, int startY, int RMin, int RMax, int width, int height, YuanHuanBackHandler ringBack)
    {

        if (RMin > RMax)
        {
            return Ring(startX, startY, RMax, RMin, width, height, ringBack);
        }
        int RMaxFang = RMax * RMax;
        int RMinFang = RMin * RMin;
        int diff = RMax - RMin;
        int cout = 0;
        int prveEndY = 0;
        int prveStartY = 0 - RMax;
        for (int x = -RMax + 1; x < RMax; x++)
        {
            int XFang = x * x;
            int x1 = startX + x;
            if (x1 < 0)
            {
                cout++;
                continue;
            }
            if(x1 >= width)
            {
                cout++;
                break;
            };

            int startY1 = (int)Math.Sqrt((double)(RMaxFang - XFang));
            prveStartY = startY1 * -1;
            if (RMax - Math.Abs(x) < diff)
                prveEndY = 0;
            else
            {
                prveEndY = (int)Math.Sqrt((double)(RMinFang - XFang)) * -1;
            }
            for (int y = prveStartY; y <= prveEndY; y++)
            {
                cout++;
                int y1 = startY + y;
                if (y1 >= 0)
                {
                    ringBack(x1, y1,y1 * width + x1);

                }
                int y2 = startY - y;
                if (y2 < height)
                {
                    ringBack(x1, y2,y2 * width + x1);
                }
            }
        }
        return cout;
    }
    public static void TextureJpg2Png(Texture2D jpgTexture, out Texture2D pngTexture2d,int width = -1,int height = -1)
    {
        if (width < 0) width = jpgTexture.width;
        if(height < 0) height = jpgTexture.height;
        pngTexture2d = new Texture2D(width,height, TextureFormat.RGBA32, false);
        Color[] allColorJpg = jpgTexture.GetPixels();
        Color[] allColorPng = new Color[width * height];
        for (int i = 0; i < width; i++)
        {
            int x1 = (int)(((float)i / (float)width) * jpgTexture.width);
            for (int j = 0; j < height; j++)
            {
                int idx = j * width + i;
                int y1 = (int)(((float)j / (float)height) * jpgTexture.height);

                Color color = allColorJpg[y1 * jpgTexture.width + x1];
                color.a = 1f;
                allColorPng[idx] = color;
            }
        }
        pngTexture2d.SetPixels(allColorPng);
        return;
    }
    public static List<int> getResetYuanJiaoOutList(int width, int height, int minR, int offsetX = 0, int offsetY = 0)
    { 
        List<int> list = new List<int>();
        int rFang = minR * minR;
        int count = 0;
        int x = 0;
        int y = 0;
        int idx = 0;
        for (int i = 0; i < offsetX; i++)
        {
            for (int j = 0; j < height; j++)
            {
                list.Add(j * width + i);
                list.Add(j * width + width - i - 1);
            }
        }
        for (int i = 0; i < width; i++)
        {
            for (int j = 0; j < offsetY; j++)
            {
                list.Add(j * width + i);
                list.Add((height - j - 1) * width + i);
            }
        }
        for (int i = 0; i < minR; i++)
        {
            int iFang = (minR - i) * (minR - i);
            for (int j = 0; j < minR; j++)
            {
                if (iFang + (minR - j) * (minR - j) > rFang)//超出⚪范围
                {
                    x = i + offsetX;
                    y = j + offsetY;
                    idx = y * width + x;
                    list.Add(idx);
                    x = width - i - 1 - offsetX;
                    y = height - j - 1 - offsetY;
                    idx = y * width + x;
                    list.Add(idx);

                    x = i + offsetX;
                    y = height - j - 1 - offsetY;
                    idx = y * width + x;
                    list.Add(idx);

                    x = width - i - 1 - offsetX;
                    y = j + offsetY;
                    idx = y * width + x;
                    list.Add(idx);
                }
            }
        }
        return list;
    }
    public static int checkResetYuanJiao(Color[] colors, int width, int height,int minR,int offsetX = 0,int offsetY = 0) {
        //检查四个角落是否透明
        List<int> temp = getResetYuanJiaoOutList(width,height,minR,offsetX,offsetY);
        foreach (var item in temp)
        {
            colors[item].a = 0f;
        }
        return temp.Count;
    }
    public static bool sendEventObjectParams(string name, System.Object param1 = null,System.Object param2 = null, System.Object param3 = null, List<System.Object> listex = null)
    {
        List<System.Object> list = null;
        if (param1 != null)
        {
            list = new List<System.Object>();
            list.Add(param1);
            if (param2 != null) list.Add(param2);
            if (param3 != null) list.Add(param3);
            if(listex != null)
            {
                for (int i = 0; i < listex.Count; i++)
                {
                    list.Add(listex[i]);
                }
            }
        }
        return sendEventObjects(name, list);
    }
    public static bool sendEventObjects(string name,List<System.Object> list){
        return IRunEventManages.send(name, null, list);
    }
    public static void httpPOST(MonoBehaviour monoBehaviour,string url,String jsonParam,bool isText, onUrlBackHandler back)
    {
        nodeNetProxy netProxy = monoBehaviour.GetComponent<nodeNetProxy>();
        if (netProxy == null)
        {
            netProxy = monoBehaviour.gameObject.AddComponent<nodeNetProxy>();
        }
        netProxy.POST(url, jsonParam, isText, back);
    }
    public static void httpGET(MonoBehaviour monoBehaviour, string url, Dictionary<String, object> param, bool isText, onUrlBackHandler back)
    {
        nodeNetProxy netProxy = monoBehaviour.GetComponent<nodeNetProxy>();
        if (netProxy == null)
        {
            netProxy = monoBehaviour.gameObject.AddComponent<nodeNetProxy>();
        }
        netProxy.GET(url,param,isText,back);
    }
    public static void httpGET(MonoBehaviour monoBehaviour, string url, bool isText, onUrlBackHandler back)
    {
        nodeNetProxy netProxy = monoBehaviour.GetComponent<nodeNetProxy>();
        if (netProxy == null)
        {
            netProxy = monoBehaviour.gameObject.AddComponent<nodeNetProxy>();
        }
        netProxy.GET(url, null, isText, back);
    }
    public static void httpGET(MonoBehaviour monoBehaviour, string urlFormat, bool isText, onUrlBackHandler back,params System.Object[] objects)
    {
        nodeNetProxy netProxy = monoBehaviour.GetComponent<nodeNetProxy>();
        if (netProxy == null)
        {
            netProxy = monoBehaviour.gameObject.AddComponent<nodeNetProxy>();
        }
        netProxy.GET(urlFormat, isText, back, objects);
    }
    public static void loadLocalImage(MonoBehaviour monoBehaviour,string locapath, onUrlBackHandler back = null)
    {
        nodeNetProxy netProxy = monoBehaviour.GetComponent<nodeNetProxy>();
        if (netProxy == null)
        {
            netProxy = monoBehaviour.gameObject.AddComponent<nodeNetProxy>();
        }
        netProxy.DOWNIMG("", locapath, back);
    }
    public static void loadLocalImage(MonoBehaviour monoBehaviour,Image image,string locapath, LoadImageInfo back = null)
    {
        loadLocalImage(monoBehaviour,locapath, (string id, string url, bool isSuccess, System.Object data) => {
            if(isSuccess == false)
            {
                if(back != null)
                {
                    back(false);
                }
                return 0;
            }
            Texture2D texture2d = data as Texture2D;
            Sprite sprite = Sprite.Create(texture2d, new Rect(0, 0, texture2d.width, texture2d.height), new Vector2(0.5f, 0.5f));
            var oldSprite = image.sprite;
            image.sprite = sprite;
            image.sprite.texture.Apply();
            if (back != null) { 
                back(true); 
            }
            return 0;
        });
    }
    
    public static void httpDownText(MonoBehaviour monoBehaviour,string url,string localpath, onUrlBackHandler back)
    {
        nodeNetProxy netProxy = monoBehaviour.GetComponent<nodeNetProxy>();
        if (netProxy == null)
        {
            netProxy = monoBehaviour.gameObject.AddComponent<nodeNetProxy>();
        }
        netProxy.DOWNTEXT(url, localpath, back);
    }
    public static void httpDOWNIMG(MonoBehaviour monoBehaviour, string url, string localpath, onUrlBackHandler back)
    {
        nodeNetProxy netProxy = monoBehaviour.GetComponent<nodeNetProxy>();
        if (netProxy == null)
        {
            netProxy = monoBehaviour.gameObject.AddComponent<nodeNetProxy>();
        }
        netProxy.DOWNIMG(url, localpath, back);
    }
    public static bool getJsonDictionaryValue<T>(Dictionary<string,System.Object> data,string path,out T value,T defvalue)
    {
        value = defvalue;
        String[] keys = path.Split("/");
        String lastName = keys[keys.Length - 1];
        Dictionary<string, System.Object> tempData = data;
        for(int i = 0;i < (keys.Length - 1); i++)
        {
            if(tempData.ContainsKey(keys[i]) == false)
            {
                return false;
            }
            tempData = tempData[keys[i]] as Dictionary<String, System.Object>;
            if(tempData == null)
            {
                return false;
            }
        }
        if (tempData.ContainsKey(lastName) == false)
        {
            return false;
        }
        System.Object lastData = tempData[lastName];
        if(value is System.Object)
        {
            value = (T)lastData;
            return true;
        }
        else
        {
            value = (T)lastData;
            return true;
        }
    }
    public static DateTime GetDateTimeMilliseconds(long timestamp)
    {
        long begtime = timestamp;// * 10000;
        DateTime dt_1970 = new DateTime(1970, 1, 1, 8, 0, 0);
        long tricks_1970 = dt_1970.Ticks;//1970年1月1日刻度
        long time_tricks = tricks_1970 + begtime;//日志日期刻度
        DateTime dt = new DateTime(time_tricks);//转化为DateTime
        return dt;
    }
    public static long GetTimeMillisecondsByDateTime(DateTime dt)
    {
        TimeSpan ts = DateTime.Now.ToUniversalTime() - new DateTime(1970, 1, 1);
        return (long)ts.TotalMilliseconds;
    }
    public static bool showWebView(string url)
    {
        Debug.Log("引擎不支持或者三方插件不支持非Android|IOS调用webView");
        return false;
    }
    public static totalView showTotal(string context,float timeLen = 5)
    {
        if(dynamicMount.ContainsKey("commons") == false)
        {
            return null;
        }
        var totalTransform = dynamicMount["commons"].transform.Find("Total");
        totalView ret = null;
        if (totalTransform != null)
        {
            ret = totalTransform.GetComponent<totalView>();
        }
        else
        {
            GameObject obj = GameObject.Instantiate((Resources.Load<GameObject>("perfabs/totalView")));
            obj.name = "Total";
            Vector3 vector3 = new Vector3();
            Quaternion quaternion = new Quaternion();
            obj.transform.GetLocalPositionAndRotation(out vector3, out quaternion);
            vector3.x = 320;
            obj.transform.SetLocalPositionAndRotation(vector3, quaternion);
            obj.transform.SetParent(dynamicMount["commons"].transform);
            ret = obj.GetComponent<totalView>();
        }
        ret.showTime = timeLen;
        return ret;
    }
    public static void HideView(GameObject gameObject)
    {
        var rectTransform = gameObject.GetComponent<RectTransform>();
        Vector3 vector3 = new Vector3();
        Quaternion quaternion = new Quaternion();
        rectTransform.GetLocalPositionAndRotation(out vector3, out quaternion);
        vector3.x = -10000;
        rectTransform.SetLocalPositionAndRotation(vector3, quaternion);
    }
    public static void ShowView(GameObject gameObject)
    {
        var rectTransform = gameObject.GetComponent<RectTransform>();
        Vector3 vector3 = new Vector3();
        Quaternion quaternion = new Quaternion();
        rectTransform.GetLocalPositionAndRotation(out vector3, out quaternion);
        vector3.x = 0;
        rectTransform.SetLocalPositionAndRotation(vector3, quaternion);
    }
    public static string EncryptString(string str)
    {

        //将字符串以UTF-8格式转为byte数组

        byte[] resultBytes = Encoding.UTF8.GetBytes(str);
        //创建一个MD5的对象
        MD5 md5 = new MD5CryptoServiceProvider();
        //调用MD5的ComputeHash方法将字节数组加密

        byte[] outPut = md5.ComputeHash(resultBytes);

        StringBuilder hashString = new StringBuilder();

        //最后把加密后的字节数组转为字符串
        for (int i = 0; i < outPut.Length; i++)
        {
            hashString.Append(Convert.ToString(outPut[i], 16).PadLeft(2, '0'));
        }
        return hashString.ToString();
    }
    public static bool saveByteToPath(byte[] bytes,string path)
    {
        string firstpath = Application.persistentDataPath + "/";
        if(path.StartsWith(firstpath) == false)
        {
            if(path.StartsWith("/") == true)
            {
                path = path.Substring(1, path.Length - 1);
            }
            path = firstpath + path;
        }
        File.WriteAllBytes(path, bytes);
        return true;
    }
    public static bool saveImageMetaInfoToPath(byte[] bytes,string imgpath)
    {
        var path = utilsTools.getWritableByPath(imgpath);
        if(path.EndsWith(".meta") == false)
        {
            path = path + ".meta";
        }
        if(File.Exists(path) == false)
           File.WriteAllBytes(path, bytes);
        return true;
    }
    public static bool saveImageDefaultMetaInfoToPath(string imgpath)
    {
        Byte[] bytes1 = Encoding.UTF8.GetBytes("fileFormatVersion: 2\r\nguid: 54ac8b67ea1f6f14892bd14ea1caab62\r\nTextureImporter:\r\n  internalIDToNameTable: []\r\n  externalObjects: {}\r\n  serializedVersion: 12\r\n  mipmaps:\r\n    mipMapMode: 0\r\n    enableMipMap: 0\r\n    sRGBTexture: 1\r\n    linearTexture: 0\r\n    fadeOut: 0\r\n    borderMipMap: 0\r\n    mipMapsPreserveCoverage: 0\r\n    alphaTestReferenceValue: 0.5\r\n    mipMapFadeDistanceStart: 1\r\n    mipMapFadeDistanceEnd: 3\r\n  bumpmap:\r\n    convertToNormalMap: 0\r\n    externalNormalMap: 0\r\n    heightScale: 0.25\r\n    normalMapFilter: 0\r\n    flipGreenChannel: 0\r\n  isReadable: 0\r\n  streamingMipmaps: 0\r\n  streamingMipmapsPriority: 0\r\n  vTOnly: 0\r\n  ignoreMipmapLimit: 0\r\n  grayScaleToAlpha: 0\r\n  generateCubemap: 6\r\n  cubemapConvolution: 0\r\n  seamlessCubemap: 0\r\n  textureFormat: 1\r\n  maxTextureSize: 2048\r\n  textureSettings:\r\n    serializedVersion: 2\r\n    filterMode: 1\r\n    aniso: 1\r\n    mipBias: 0\r\n    wrapU: 1\r\n    wrapV: 1\r\n    wrapW: 1\r\n  nPOTScale: 0\r\n  lightmap: 0\r\n  compressionQuality: 50\r\n  spriteMode: 1\r\n  spriteExtrude: 1\r\n  spriteMeshType: 1\r\n  alignment: 0\r\n  spritePivot: {x: 0.5, y: 0.5}\r\n  spritePixelsToUnits: 1\r\n  spriteBorder: {x: 0, y: 0, z: 0, w: 0}\r\n  spriteGenerateFallbackPhysicsShape: 1\r\n  alphaUsage: 1\r\n  alphaIsTransparency: 1\r\n  spriteTessellationDetail: -1\r\n  textureType: 8\r\n  textureShape: 1\r\n  singleChannelComponent: 0\r\n  flipbookRows: 1\r\n  flipbookColumns: 1\r\n  maxTextureSizeSet: 0\r\n  compressionQualitySet: 0\r\n  textureFormatSet: 0\r\n  ignorePngGamma: 0\r\n  applyGammaDecoding: 0\r\n  swizzle: 50462976\r\n  cookieLightType: 0\r\n  platformSettings:\r\n  - serializedVersion: 3\r\n    buildTarget: DefaultTexturePlatform\r\n    maxTextureSize: 2048\r\n    resizeAlgorithm: 0\r\n    textureFormat: -1\r\n    textureCompression: 1\r\n    compressionQuality: 50\r\n    crunchedCompression: 0\r\n    allowsAlphaSplitting: 0\r\n    overridden: 0\r\n    ignorePlatformSupport: 0\r\n    androidETC2FallbackOverride: 0\r\n    forceMaximumCompressionQuality_BC6H_BC7: 0\r\n  - serializedVersion: 3\r\n    buildTarget: Standalone\r\n    maxTextureSize: 2048\r\n    resizeAlgorithm: 0\r\n    textureFormat: -1\r\n    textureCompression: 1\r\n    compressionQuality: 50\r\n    crunchedCompression: 0\r\n    allowsAlphaSplitting: 0\r\n    overridden: 0\r\n    ignorePlatformSupport: 0\r\n    androidETC2FallbackOverride: 0\r\n    forceMaximumCompressionQuality_BC6H_BC7: 0\r\n  - serializedVersion: 3\r\n    buildTarget: Server\r\n    maxTextureSize: 2048\r\n    resizeAlgorithm: 0\r\n    textureFormat: -1\r\n    textureCompression: 1\r\n    compressionQuality: 50\r\n    crunchedCompression: 0\r\n    allowsAlphaSplitting: 0\r\n    overridden: 0\r\n    ignorePlatformSupport: 0\r\n    androidETC2FallbackOverride: 0\r\n    forceMaximumCompressionQuality_BC6H_BC7: 0\r\n  - serializedVersion: 3\r\n    buildTarget: Android\r\n    maxTextureSize: 2048\r\n    resizeAlgorithm: 0\r\n    textureFormat: -1\r\n    textureCompression: 1\r\n    compressionQuality: 50\r\n    crunchedCompression: 0\r\n    allowsAlphaSplitting: 0\r\n    overridden: 0\r\n    ignorePlatformSupport: 0\r\n    androidETC2FallbackOverride: 0\r\n    forceMaximumCompressionQuality_BC6H_BC7: 0\r\n  spriteSheet:\r\n    serializedVersion: 2\r\n    sprites: []\r\n    outline: []\r\n    physicsShape: []\r\n    bones: []\r\n    spriteID: 5e97eb03825dee720800000000000000\r\n    internalID: 0\r\n    vertices: []\r\n    indices: \r\n    edges: []\r\n    weights: []\r\n    secondaryTextures: []\r\n    nameFileIdTable: {}\r\n  mipmapLimitGroupName: \r\n  pSDRemoveMatte: 0\r\n  userData: \r\n  assetBundleName: \r\n  assetBundleVariant: \r\n");
        return saveImageMetaInfoToPath(bytes1, imgpath);
    }
    public static Texture2D ScaleTexture(Texture2D source, int targetWidth, int targetHeight, TextureFormat format)
    {
        Texture2D result = new Texture2D(targetWidth, targetHeight, format, false);

        for (int i = 0; i < result.height; ++i)
        {
            for (int j = 0; j < result.width; ++j)
            {
                Color newColor = source.GetPixelBilinear((float)j / (float)result.width, (float)i / (float)result.height);
                if(format != source.format)
                {
                    newColor.a = 1f;
                }
                result.SetPixel(j, i, newColor);
            }
        }
        return result;
    }
    public static void showAd(string param,string gameName,string funName)
    {
        
    }
    public static void share(string param,string gameName,string funName)
    {

    }
    public static Texture2D ScaleTexture(Texture2D source, int targetWidth, int targetHeight)
    {
        Texture2D result = new Texture2D(targetWidth, targetHeight, source.format, false);
        Color[] colors = result.GetPixels(0,0,targetWidth,targetHeight);
        for (int i = 0; i < result.height; ++i)
        {
            for (int j = 0; j < result.width; ++j)
            {
                Color newColor = source.GetPixelBilinear((float)j / (float)result.width, (float)i / (float)result.height);
                //result.SetPixel(j, i, newColor);
                colors[i * targetWidth + j] = newColor;
            }
        }
        result.SetPixels(0, 0, targetWidth, targetHeight, colors);
        return result;
    }
    public static bool isEqualByValue(float value1,float value2,float mismatch)
    {
        if (mismatch == 0) return value1.Equals(value2);
        if (value1.Equals(value2)) return true;
        mismatch = Math.Abs(mismatch);
        if (value1 > value2) 
            return (value1 - mismatch) < value2;
        else
            return (value2 - mismatch) < value1;
    }
    public static bool isEqualByValue(double value1,double value2,float mismatch)
    {
        if (mismatch == 0) return value1.Equals(value2);
        if (value1.Equals(value2)) return true;
        mismatch = Math.Abs(mismatch);
        if (value1 > value2)
            return (value1 - mismatch) < value2;
        else
            return (value2 - mismatch) < value1;
    }
    //外面列表的并且有本地进度时候的调用
    //loadImageThumbnailById("6573",(Sprite sprite,string id,Image image)=>{if(image == null) image = gameObject.GetComponent<Image>();image.sprite = sprite;...},image1)
    public static void loadImageThumbnailById(string id, LoadImageBack loadImageBack, Image image = null)
    {

    }
    //初始化播放游戏过程
    //OnAreaHandler 回调的时候才能调用replayGameProcessById
    public static void initPlayGameById(string id,GameObject gameObject, OnAreaHandler onAreaHandler)
    {
    }
    //开始播放游戏过程
    public static void replayGameProcessById(string id,GameObject gameObject,List<Tuple<short,float,float>> playOrders)
    {
    }
    public static bool setGameScenUserInfo(string id,string lineUrl,string colorUrl,string jsonUrl,string zipUrl)
    {
        string gameSaveKey = "gameUserData_" + id.ToString();
        string oldData = utilsDB.getDBStringDataByKey(gameSaveKey, "");
        if (oldData.Equals("") == false)
        {
            var data = JsonUtility.FromJson<GameScenUserInfo>(oldData);
            return data.id.Equals(id);
        }
        GameScenUserInfo gameScenUserDataInfo = new GameScenUserInfo();
        gameScenUserDataInfo.img = lineUrl;
        gameScenUserDataInfo.finishImg = colorUrl;
        gameScenUserDataInfo.json = jsonUrl;
        gameScenUserDataInfo.id = id;
        gameScenUserDataInfo.file = zipUrl;
        utilsDB.setDBJsonDataByKey(gameSaveKey, JsonUtility.ToJson(gameScenUserDataInfo));
        return true;
    }
    public static GameScenUserInfo getGameScenUserInfo(string id)
    {
        string gameSaveKey = "gameUserData_" + id.ToString();
        string oldData = utilsDB.getDBStringDataByKey(gameSaveKey, "");
        if (oldData.Equals("") == false)
        {
            var data = JsonUtility.FromJson<GameScenUserInfo>(oldData);
            return data;
        }
        return null;
    }
    public static bool saveGameScenUserInfo(GameScenUserInfo gameScenUserInfo)
    {
        string gameSaveKey = "gameUserData_" + gameScenUserInfo.id;
        string oldData = utilsDB.getDBStringDataByKey(gameSaveKey, "");
        var data = JsonUtility.FromJson<GameScenUserInfo>(oldData);
        if (data.id.Equals(gameScenUserInfo.id) == false) return false;
        utilsDB.setDBJsonDataByKey(gameSaveKey, JsonUtility.ToJson(gameScenUserInfo));
        return true;
    }
    public static Vector2 ScreenToUILocalPos(RectTransform transform, Vector2 mousePos, Camera canvasCam = null)
    {
        Vector2 uiLocalPos;
        RectTransformUtility.ScreenPointToLocalPointInRectangle(transform, mousePos, canvasCam, out uiLocalPos);
        return uiLocalPos;
    }
    
    public static string getWritableByPath(string path)
    {
        var persistentDataPath = Application.persistentDataPath;
        if (path.StartsWith(persistentDataPath))
        {
            return path;
        }
        if (IsPhone)
        {
            if (path.StartsWith("jar:file://"+ persistentDataPath))
            {
                return path;
            }
        }
        else
        {
            if (path.StartsWith("file://" + persistentDataPath))
            {
                return path;
            }
        }
        if(IsWin == true && path.IndexOf("\\") > 0)
        {
            return getWritableByPath(path.Replace("\\", "/"));
        }
        return persistentDataPath + "/" + path;
    }
    public static bool IsExistIO(string path,bool isFile = true)
    {
        string path1 = getWritableByPath(path);
        if (IsWin == true)
        {
            path1 = path1.Replace("/", "\\");
        }
        else
        {
            path1 = path1.Replace("\\", "/");
        }
        if (isFile) return File.Exists(path1);
        return Directory.Exists(path1);
    }
    public static void CreateDirectory(string path)
    {
        string path1 = getWritableByPath(path);
        if (IsWin)
        {
            path1 = path1.Replace("/", "\\");
        }
        else
        {
            path1 = path1.Replace("\\", "/");
        }
        if(Directory.Exists(path1) == false)
        {
            Directory.CreateDirectory(path1);
        }
    }
    public static float randValueByFloat(float min,float max)
    {
        return (float)random.NextDouble() * (max - min) + min;
    }
    public static int getTotalMillisecond()
    {
        DateTime dt = DateTime.Now;
        return dt.Minute * 60000 + dt.Second * 1000 + dt.Millisecond%1000;
    }
    public static string copyFile(string path)
    {
        String readPath = "";// Application.persistentDataPath + "/" + path;//永久文件地址
        String path1 = Application.persistentDataPath;
        if(path1.EndsWith("/") || path1.EndsWith("\\"))
        {
            readPath = path1 + path;
        }
        else
        {
            readPath = path1 + "/" + path;
        }
        string sql_DirPath = Path.Combine(Application.streamingAssetsPath, path);//找到streamingAssets下的数据库文件位置//以下代码最好使用协程
        if(IsExistIO(readPath) == true)
        {
            return readPath;
        }
        Uri ri = new Uri(sql_DirPath);
        UnityWebRequest wr = UnityWebRequest.Get(ri);
        //发送文件请求 
        wr.SendWebRequest();
        while (!wr.isDone)
        {
            if (wr.isDone)
            {
                Debug.Log("写入");
                File.Create(readPath).Dispose();
                File.WriteAllBytes(readPath, wr.downloadHandler.data);
                return readPath;
            }
        }
        return readPath;
    }
    public static void RGBtoYUV(Color[] rgbData, byte[] yuvData, int width, int height)
    {
        int size = width * height;

        for (int i = 0; i < size; i++)
        {
            Color32 rgb = rgbData[i];
            byte y = (byte)(0.299 * rgb.r * 255 + 0.587 * rgb.g * 255 + 0.114 * rgb.b * 255);
            byte u = (byte)(128 - 0.168736 * rgb.r * 255 - 0.331264 * rgb.g * 255 + 0.5 * rgb.b * 255);
            byte v = (byte)(128 + 0.5 * rgb.r * 255 - 0.418688 * rgb.g * 255 - 0.081312 * rgb.b * 255);

            yuvData[i] = y;
            yuvData[size + i / 4] = u;
            yuvData[size + size / 4 + i / 4] = v;
        }
    }
    public static void DeviceAdaptationTool(GameObject gameObject,bool changSize=true,int type = 0)
    {
        DeviceAdaptationInfo info = null;
        var trans = gameObject.GetComponent<RectTransform>();
        getUserData<DeviceAdaptationInfo>(gameObject, "sys_sheji_sys", out info, null);
        if(info == null)
        {
            info = new DeviceAdaptationInfo();
            info.init(trans);
            setUserData(gameObject, "sys_sheji_sys", info);
        }
        //计算新的大小和位置
        float x = (info.x * nowSceneSize.x) / shejiSize.x;
        float y =  (info.y * nowSceneSize.y) / shejiSize.y;
        float width = (info.width * nowSceneSize.x) / shejiSize.x;
        float height = (info.height * nowSceneSize.y) / shejiSize.y;
        trans.localPosition = new Vector3(x, y);
        if (type.Equals(2))
        {
            width = height;
        }else if (type.Equals(1))
        {
            height = width;
        }
        if (changSize)
        {
            trans.sizeDelta = new Vector2(width, height);
        }
        else
        {
            trans.localScale = new Vector2(width/info.width, height/info.height);
        }
    }
    public static void DeviceAdaptationSize(Vector2 shejiGameSize, out Vector2 vector2)
    {
        float x = shejiSize.x;
        if(x.Equals(0.0f) == false)
            x = (shejiGameSize.x * nowSceneSize.x) / shejiSize.x;
        float y = shejiSize.y;
        if(y.Equals(0.0f) == false)
            y = (shejiGameSize.y * nowSceneSize.y) / shejiSize.y;
        vector2 = new Vector2(x, y);
    }
    public static void DeviceAdaptationSize(ref Vector2 shejiGameSize)
    {
        float x = shejiSize.x;
        if (x.Equals(0.0f) == false)
            x = (shejiGameSize.x * nowSceneSize.x) / shejiSize.x;
        float y = shejiSize.y;
        if (y.Equals(0.0f) == false)
            y = (shejiGameSize.y * nowSceneSize.y) / shejiSize.y;
        shejiGameSize = new Vector2(x, y);
    }
    public static void checkUpdateNowSceneSize()
    {
        int width = Screen.width;
        int height = Screen.height;
        if (width < height)
        {
            nowSceneSize = new Vector2(width, height);
        }
        else
        {
            nowSceneSize = new Vector2(height, width);
        }
    }
    public static void resetGameObjectTreeSize(GameObject gobject, GetOperType back, String path = "")
    {
        path = path + gobject.name + "/";
        for (int i = 0; i < gobject.transform.childCount; i++)
        {
            var tran = gobject.transform.GetChild(i);
            ScrollRect scrollRect = tran.GetComponent<ScrollRect>();
            if (scrollRect == null)
            {
                Slider slider = tran.GetComponent<Slider>();
                if(slider == null)
                    resetGameObjectTreeSize(tran.gameObject, back, path);
                else
                {
                    utilsTools.DeviceAdaptationTool(tran.gameObject);
                }
            }
            else
            {

                utilsTools.DeviceAdaptationTool(tran.gameObject);
                var trans = tran.gameObject.GetComponent<RectTransform>();
            }
        }
        int type = back(path.Substring(0,path.Length-1));
        bool changSize = true;
        if(gobject.GetComponent<Text>() != null || gobject.GetComponent<TextMeshProUGUI>() != null)
        {
            changSize = false;
        }
        if(type.Equals(1))
            utilsTools.DeviceAdaptationTool(gobject, changSize, 1);
        else if(type.Equals(2))
            utilsTools.DeviceAdaptationTool(gobject, changSize, 2);
        else
            utilsTools.DeviceAdaptationTool(gobject, changSize, 0);
    }
    public static void setAnchor(Transform transform, Vector2 anchor)
    {
        setAnchor(transform, anchor, new Vector2(0, 0));
    }
    public static void setAnchor(Transform transform,Vector2 anchor,Vector2 anchoredPosition)
    {
        RectTransform rectTransform = (RectTransform)transform;
        if(rectTransform == null)
            rectTransform = transform.GetComponent<RectTransform>();
        rectTransform.anchorMax = anchor;
        rectTransform.anchorMin = anchor;
        rectTransform.pivot = anchor;
        rectTransform.anchoredPosition = anchoredPosition;
        //rectTransform.sizeDelta = size;
        //RectTransform rectTrans_Fatter = rectTransform.parent as RectTransform;
        //Vector2 delatAnchor = anchor - oldAnchorCenter;
        //Vector2 deltaMove = new Vector2(delatAnchor.x * rectTrans_Fatter.rect.width, delatAnchor.y * rectTrans_Fatter.rect.height);
        //rectTransform.anchoredPosition = oldAnchredPos - deltaMove;
    }

    public static Vector2 getAnchor(Transform transform)
    {
        RectTransform rectTransform = (RectTransform)transform;
        if (rectTransform == null)
            rectTransform = transform.GetComponent<RectTransform>();
        return rectTransform.anchorMax;
    }
}