using System;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using UnityEngine;

/// <summary>
/// 可编辑脸部部位
/// </summary>
public enum EditableFacePart
{
    eyebrow,
    eye,
    mousewidth
}

/// <summary>
/// 可编辑身体部位
/// </summary>
public enum EditableBodyPart
{
    UpperArm = 0,
    LowerArm = 1,
    Hand = 2,
    UpperLeg = 3,
    LowerLeg = 4,
    Foot = 5,
    All = 6,
    Neck = 7,
    Clavicle = 8,
    Shoulder = 9,
    Chest = 10,//胸
    Pleural = 11,//胸腔下部
    Belly = 12,//肚子
    UpperArmUp = 13,
    UpperArmDown = 14,
    UpperLegUp = 15,
    UpperLegDown = 16,
    LowerLegUp = 17,
    LowerLegDown = 18,
    Head = 19,
    Acromion = 20,//肩峰
    Waist = 21,//腰
    Wrist = 22,//手腕
    Crotch = 23,//胯部
    Hips = 24,//臀部
    Knee = 25,//膝盖
    Ankle = 26,//脚腕
    None = 27,
}
/// <summary>
/// 编辑类型
/// </summary>
public enum ModifyType
{
    Length = 0,//长
    Width = 1,//宽
    Thick = 2,//厚度
    LengthWidthThick = 3,//长宽厚
    Angle = 4,//角度
    UpDown = 5,//上下
    LeftRight = 6,//左右
    ForwardBehind = 7,//前后
}

public static class CustomRoleUtility
{
    public static void UpdateBoneScale(Animator ani,EditableBodyPart part, Vector3 scale,bool keepChildWorldScale, float value)
    {
        Transform[] transList = GetRelativeTransform(ani,part);
        Vector3 beforeScale = Vector3.one;

        if(transList == null)
        {
            return;
        }
        for (int i = 0; i < transList.Length; i++)
        {
            var trans = transList[i];
            if(trans == null)
            {
                continue;
            }
            beforeScale = trans.localScale;
            var world_l = trans.lossyScale;
            if (scale.x == 1) trans.SetLocalScaleX(trans.localScale.x * value / world_l.x);
            if (scale.y == 1) trans.SetLocalScaleY(trans.localScale.y * value / world_l.y);
            if (scale.z == 1) trans.SetLocalScaleZ(trans.localScale.z * value / world_l.z);

            //修改子物体的缩放
            if (!keepChildWorldScale)
            {
                continue;
            }
            var lcount = trans.childCount;
            for (int j = 0; j < lcount; j++)
            {
                var childTrans = trans.GetChild(j);
                var oldScale = childTrans.localScale;
                if (scale.x == 1) childTrans.SetLocalScaleX(oldScale.x * beforeScale.x / value);
                if (scale.y == 1) childTrans.SetLocalScaleY(oldScale.y * beforeScale.y / value);
                if (scale.z == 1) childTrans.SetLocalScaleZ(oldScale.z * beforeScale.z / value);
            }
        }
    }

    public static Transform[] GetRelativeTransform(Animator ani,EditableBodyPart part)
    {
        Transform[] result = null;
        switch (part)
        {
            case EditableBodyPart.UpperArm:
                result = new Transform[2];
                result[0] = ani.GetBoneTransform(HumanBodyBones.LeftUpperArm);
                result[1] = ani.GetBoneTransform(HumanBodyBones.RightUpperArm);
                break;
            case EditableBodyPart.LowerArm:
                result = new Transform[2];
                result[0] = ani.GetBoneTransform(HumanBodyBones.LeftLowerArm);
                result[1] = ani.GetBoneTransform(HumanBodyBones.RightLowerArm);
                break;
            case EditableBodyPart.Hand:
                result = new Transform[2];
                result[0] = ani.GetBoneTransform(HumanBodyBones.LeftHand);
                result[1] = ani.GetBoneTransform(HumanBodyBones.RightHand);
                break;
            case EditableBodyPart.UpperLeg:
                result = new Transform[2];
                result[0] = ani.GetBoneTransform(HumanBodyBones.LeftUpperLeg);
                result[1] = ani.GetBoneTransform(HumanBodyBones.RightUpperLeg);
                break;
            case EditableBodyPart.LowerLeg:
                result = new Transform[2];
                result[0] = ani.GetBoneTransform(HumanBodyBones.LeftLowerLeg);
                result[1] = ani.GetBoneTransform(HumanBodyBones.RightLowerLeg);
                break;
            case EditableBodyPart.Foot:
                result = new Transform[2];
                result[0] = ani.GetBoneTransform(HumanBodyBones.LeftFoot);
                result[1] = ani.GetBoneTransform(HumanBodyBones.RightFoot);
                break;
            case EditableBodyPart.All:
                result = new Transform[1];
                result[0] = ani.GetBoneTransform(HumanBodyBones.Spine);
                break;
            case EditableBodyPart.Neck:
                result = new Transform[1];
                result[0] = ani.GetBoneTransform(HumanBodyBones.Neck);
                break;
            case EditableBodyPart.Clavicle:
                result = new Transform[1];
                //result[0] = ani.GetBoneTransform(HumanBodyBones.cl);
                break;
            case EditableBodyPart.Shoulder:
                result = new Transform[2];
                result[0] = ani.GetBoneTransform(HumanBodyBones.LeftShoulder);
                result[1] = ani.GetBoneTransform(HumanBodyBones.RightShoulder);
                break;
            case EditableBodyPart.Chest:
                result = new Transform[2];
                var p = ani.GetBoneTransform(HumanBodyBones.Chest);
                result[0] = GetChild(p, "Chest_L");
                result[1] = GetChild(p, "Chest_R");
                break;
            case EditableBodyPart.Pleural:
                break;
            case EditableBodyPart.Belly:
                break;
            case EditableBodyPart.UpperArmUp:
                break;
            case EditableBodyPart.UpperArmDown:
                break;
            case EditableBodyPart.UpperLegUp:
                break;
            case EditableBodyPart.UpperLegDown:
                break;
            case EditableBodyPart.LowerLegUp:
                break;
            case EditableBodyPart.LowerLegDown:
                break;
            case EditableBodyPart.Head:
                result = new Transform[1];
                result[0] = ani.GetBoneTransform(HumanBodyBones.Head);
                break;
            case EditableBodyPart.Acromion:
                break;
            case EditableBodyPart.Waist:
                break;
            case EditableBodyPart.Wrist:
                break;
            case EditableBodyPart.Crotch:
                break;
            case EditableBodyPart.Hips:
                break;
            case EditableBodyPart.Knee:
                break;
            case EditableBodyPart.Ankle:
                break;
            case EditableBodyPart.None:
                break;
            default:
                break;
        }

        return result;
    }

    public static void GetNormalAniBonesScale(Animator ani,ref Dictionary<string, Vector3> boneDic)
    {
        for (int i = 0; i < Enum.GetValues(typeof(HumanBodyBones)).Length - 1; i++)
        {
            var trans = ani.GetBoneTransform((HumanBodyBones)i);
            if(trans)
            {
                boneDic.Add(trans.name, trans.lossyScale);
            }
        }
    }

    public static Transform GetChild(Transform trans,string name)
    {
        for (int i = 0; i < trans.childCount; i++)
        {
            if(trans.GetChild(i).name == name)
            {
                return trans.GetChild(i);
            }else
            {
                var childTrans = GetChild(trans.GetChild(i),name);
                if(childTrans != null)
                {
                    return childTrans;
                }
            }
        }
        return null;
    }

    public static void ShowFile()
    {
        FileStream fs = File.Open("E:/key.key", FileMode.Open);
        FileStream fsout = File.Open("E:/keyout9.key", FileMode.Create);
        BinaryReader br = new BinaryReader(fs);
        BinaryWriter bw = new BinaryWriter(fsout);
        Byte[] byData = br.ReadBytes((int)fs.Length);

        var t = "NKnFb79Sxk+4Xw284MQleA==";
        var pid = "1639047545434X1016017";
        fs.Close();
        //var iv = new byte[16];
        //var key = new byte[16];
        //for (int i = 0; i < byData.Length; i++)
        //{
        //    if(i <= 15)
        //    {
        //        iv[i] = byData[i];
        //        var ivx = byData[i].ToString("x");
        //        Debug.Log(iv[i] + " : " + ivx);
        //    }
        //    else
        //    {
        //        key[i - 16] = byData[i];
        //        var keyx = byData[i].ToString("x");
        //        Debug.Log(key[i - 16] + " : " + keyx);
        //    }
        //}

        //var str = DecryptStringFromBytes_Aes(byData, iv, key);
        //Debug.Log("result" + str);

        Debug.Log(byData.Length);

        IList<byte> bData = new List<byte>();
        string[] strHexs = new string[16];
        int[] intData = {
                245,
                217,
                174,
                210,
                90,
                41,
                167,
                178,
                110,
                47,
                158,
                193,
                35,
                162,
                230,
                97
            };
        for (int i = 0; i < 16; i++)
        {
            int a = intData[i];
            strHexs[i] = a.ToString("x");
            //strHexs[i] = a.ToString();
            Debug.Log(a + " : " + a.ToString("x"));
        }

        foreach (var item in strHexs)
        {
            Debug.Log(Convert.ToByte(item, 16));
            bData.Add(Convert.ToByte(item, 16));
        }
        bw.Write(bData.ToArray());
        fsout.Close();
    }
}
