// Warning: Some assembly references could not be resolved automatically. This might lead to incorrect decompilation of some parts,
// for ex. property getter/setter access. To get optimal decompilation results, please manually add the missing references to the list of loaded assemblies.
// EdenAutoMorpherScript, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null
// Eden.AutoMorpher.EdenAutoMorpher_SetUpUtil
using Eden.AutoMorpher;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Text;
using UnityEditor;
using UnityEditorInternal;
using UnityEngine;

public class EdenAutoMorpher_SetUpUtil
{
    public GameObject InstantiateTargetClothes(GameObject sourceClothesObject, GameObject targetAvatarObject, string tagEdenMorpherCloth, bool removeAutoMorphedClothes)
    {
        EnsureTagExists(tagEdenMorpherCloth);
        if (removeAutoMorphedClothes)
        {
            List<GameObject> list = new List<GameObject>();
            Transform[] componentsInChildren = targetAvatarObject.GetComponentsInChildren<Transform>(includeInactive: true);
            foreach (Transform transform in componentsInChildren)
            {
                if (!(transform.gameObject == targetAvatarObject) && transform.CompareTag(tagEdenMorpherCloth))
                {
                    list.Add(transform.gameObject);
                }
            }
            foreach (GameObject item in list)
            {
                UnityEngine.Object.DestroyImmediate(item);
            }
        }
        GameObject gameObject = UnityEngine.Object.Instantiate(sourceClothesObject, targetAvatarObject.transform);
        gameObject.SetActive(value: true);
        gameObject.transform.localPosition = Vector3.zero;
        gameObject.transform.localRotation = Quaternion.identity;
        gameObject.transform.localScale = Vector3.one;
        gameObject.tag = tagEdenMorpherCloth;
        return gameObject;
    }

    private static void EnsureTagExists(string tag)
    {
        if (string.IsNullOrEmpty(tag))
        {
            throw new AutoMorpherException("Clothes Tag is Invalid", "[EdenAutoMorpherManager] EnsureTagExists\n - tagEdenMorpherCloth is null or empty");
        }
        string[] tags = InternalEditorUtility.tags;
        for (int i = 0; i < tags.Length; i++)
        {
            if (tags[i] == tag)
            {
                return;
            }
        }
        SerializedObject serializedObject = new SerializedObject(AssetDatabase.LoadAllAssetsAtPath("ProjectSettings/TagManager.asset")[0]);
        SerializedProperty serializedProperty = serializedObject.FindProperty("tags");
        int arraySize = serializedProperty.arraySize;
        serializedProperty.InsertArrayElementAtIndex(arraySize);
        serializedProperty.GetArrayElementAtIndex(arraySize).stringValue = tag;
        serializedObject.ApplyModifiedProperties();
    }

    public void AutoSetup(ref EdenAutoMorpherConfig config, out Dictionary<HumanBodyBones, HashSet<Transform>> clothesHumanoidMatchedBones, out Dictionary<Transform, ClothBoneType> clothBoneTypeMap)
    {
        config.targetClothesObject = this.InstantiateTargetClothes(config.sourceClothesObject, config.targetAvatarObject, config.tagEdenMorpehrCloth, config.isRemoveAutoMorphedClothes);
        if (config.targetClothesObject == null)
        {
            throw new AutoMorpherException("Target Clothes Object is Null", "[EdenAutoMorpher_SetUpUtil] AutoSetup\n - config.targetClothesObject is null");
        }
        BoneMatchUtil boneMatchUtil = new BoneMatchUtil();
        List<BoneMatchUtil.BoneRootLocalData> bodyRootLocalBones = boneMatchUtil.GetBodyRootLocalBones(config.sourceAvatarObject.transform, config.sourceAvatarObject.GetComponent<Animator>(), config.sourceBodyMeshes.ToList());
        List<BoneMatchUtil.BoneRootLocalData> rootLocalBones = boneMatchUtil.GetRootLocalBones(config.targetClothesObject.transform, boneMatchUtil.GetMeshBones(config.targetClothesObject.GetComponentsInChildren<SkinnedMeshRenderer>().ToList()));
        boneMatchUtil.MatchClothesToBodyBones(bodyRootLocalBones, rootLocalBones, out clothesHumanoidMatchedBones, out clothBoneTypeMap, out var clothToBodyMatched);
        Dictionary<Transform, Transform> sourceToProxy;
        GameObject gameObject = new BodyPoseMatchUtil().AutoAdjustBodyPose(config.sourceAvatarObject, config.sourceBodyMeshes, config.targetAvatarObject, config.targetBodyMeshes, out sourceToProxy);
        if (gameObject == null)
        {
            throw new AutoMorpherException(LanguageManager.Get("UI.Exception.title.BodyProxyNull"), LanguageManager.Get("UI.Exception.message.BodyProxyNull"));
        }
        try
        {
            if (clothesHumanoidMatchedBones == null || clothesHumanoidMatchedBones.Count == 0)
            {
                throw new AutoMorpherException("Clothes Humanoid Matched Bones is Null", "[EdenAutoMorpher_SetUpUtil] AutoSetup\n - clothesHumanoidMatchedBones is null\n - Please check whether the outfit’s bones match the bones of the source avatar.");
            }
            if (clothBoneTypeMap == null)
            {
                throw new AutoMorpherException("Cloth Bone Type Map is Null", "[EdenAutoMorpher_SetUpUtil] AutoSetup\n - clothBoneTypeMap is null\n - Please check whether the outfit’s bones match the bones of the source avatar.");
            }
            if (AutoMorpherDev.isDeveloperMode)
            {
                this.DebugPrintSameNameBonePaths(clothToBodyMatched, sourceToProxy);
            }
            new BodyPoseToClothApplier().ApplyBodyPoseToClothes(gameObject.transform, config.targetClothesObject.transform, clothToBodyMatched, sourceToProxy);
        }
        finally
        {
            UnityEngine.Object.DestroyImmediate(gameObject);
        }
    }

    public void DebugPrintSameNameBonePaths(Dictionary<Transform, BoneMatchUtil.BoneRootLocalData> clothToBodyMatched, Dictionary<Transform, Transform> sourceToProxy)
    {
        if (clothToBodyMatched == null)
        {
            throw new AutoMorpherException("clothToBodyMatched is Missing", "[DebugBonePath] DebugPrintSameNameBonePaths\n - clothToBodyMatched is null");
        }
        if (sourceToProxy == null)
        {
            throw new AutoMorpherException("sourceToProxy is Missing", "[DebugBonePath] DebugPrintSameNameBonePaths\n - sourceToProxy is null");
        }
        Dictionary<string, List<Transform>> dictionary = new Dictionary<string, List<Transform>>();
        foreach (KeyValuePair<Transform, Transform> item in sourceToProxy)
        {
            Transform key = item.Key;
            if (!(key == null))
            {
                if (!dictionary.TryGetValue(key.name, out var value))
                {
                    value = new List<Transform>();
                    dictionary.Add(key.name, value);
                }
                value.Add(key);
            }
        }
        StringBuilder stringBuilder = new StringBuilder();
        stringBuilder.AppendLine("[DebugBonePath] Same-name bone path comparison");
        stringBuilder.AppendLine("--------------------------------------------------");
        foreach (KeyValuePair<Transform, BoneMatchUtil.BoneRootLocalData> item2 in clothToBodyMatched)
        {
            _ = item2.Key;
            Transform transform = GetSourceTransform(item2.Value);
            if (transform == null)
            {
                continue;
            }
            string name = transform.name;
            if (!dictionary.TryGetValue(name, out var value2))
            {
                continue;
            }
            stringBuilder.AppendLine("[Bone Name] " + name);
            stringBuilder.AppendLine("  - BoneRootLocalData Source Path: " + GetPath(transform));
            foreach (Transform item3 in value2)
            {
                stringBuilder.AppendLine("  - sourceToProxy Source Path   : " + GetPath(item3));
            }
            stringBuilder.AppendLine("--------------------------------------------------");
        }
        Debug.Log(stringBuilder.ToString());
        static string GetPath(Transform t)
        {
            if (t == null)
            {
                return "(null)";
            }
            StringBuilder stringBuilder2 = new StringBuilder();
            while (t != null)
            {
                stringBuilder2.Insert(0, t.name);
                t = t.parent;
                if (t != null)
                {
                    stringBuilder2.Insert(0, "/");
                }
            }
            return stringBuilder2.ToString();
        }
        static Transform GetSourceTransform(BoneMatchUtil.BoneRootLocalData data)
        {
            if (data == null)
            {
                return null;
            }
            FieldInfo[] fields = data.GetType().GetFields(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
            foreach (FieldInfo fieldInfo in fields)
            {
                if (typeof(Transform).IsAssignableFrom(fieldInfo.FieldType))
                {
                    return fieldInfo.GetValue(data) as Transform;
                }
            }
            return null;
        }
    }

    public void ManulSetup(ref EdenAutoMorpherConfig config, out Dictionary<HumanBodyBones, HashSet<Transform>> clothesHumanoidMatchedBones, out Dictionary<Transform, ClothBoneType> clothBoneTypeMap)
    {
        BoneMatchUtil boneMatchUtil = new BoneMatchUtil();
        List<BoneMatchUtil.BoneRootLocalData> bodyRootLocalBones = boneMatchUtil.GetBodyRootLocalBones(config.sourceAvatarObject.transform, config.sourceAvatarObject.GetComponent<Animator>(), config.sourceBodyMeshes.ToList());
        List<BoneMatchUtil.BoneRootLocalData> rootLocalBones = boneMatchUtil.GetRootLocalBones(config.sourceClothesObject.transform, boneMatchUtil.GetMeshBones(config.sourceClothesObject.GetComponentsInChildren<SkinnedMeshRenderer>().ToList()));
        boneMatchUtil.MatchClothesToBodyBones(bodyRootLocalBones, rootLocalBones, out var clothHumanBones, out var clothBoneTypeMap2, out var _);
        boneMatchUtil.RemapSourceClothMatchToTargetCloth(config.sourceClothesObject.transform, config.targetClothesObject.transform, clothHumanBones, clothBoneTypeMap2, out clothesHumanoidMatchedBones, out clothBoneTypeMap);
        if (clothesHumanoidMatchedBones == null || clothesHumanoidMatchedBones.Count == 0)
        {
            throw new AutoMorpherException("Clothes Humanoid Matched Bones is Null", "[EdenAutoMorpher_SetUpUtil] ManulSetup\n - clothesHumanoidMatchedBones is null\n - Please check whether the Source Clothes’s bones match the bones of the source avatar.");
        }
        if (clothBoneTypeMap == null)
        {
            throw new AutoMorpherException("Cloth Bone Type Map is Null", "[EdenAutoMorpher_SetUpUtil] ManulSetup\n - clothBoneTypeMap is null\n - Please check whether the Source Clothes’s bones match the bones of the source avatar.");
        }
        MeshClassifier meshClassifier = new MeshClassifier();
        Dictionary<HumanBodyBones, HashSet<Transform>> humanBoneMap = meshClassifier.MeshHumanoidBoneMatcher(config.sourceAvatarObject.GetComponent<Animator>(), config.sourceBodyMeshes);
        Dictionary<HumanBodyBones, HashSet<Transform>> humanBoneMap2 = meshClassifier.MeshHumanoidBoneMatcher(config.targetAvatarObject.GetComponent<Animator>(), config.sourceBodyMeshes);
        BodyPoseMatchSetupUtil bodyPoseMatchSetupUtil = new BodyPoseMatchSetupUtil();
        bodyPoseMatchSetupUtil.AdjustAvatarScaleByNeck(config.sourceAvatarObject.transform, humanBoneMap, 1.5f);
        bodyPoseMatchSetupUtil.AdjustAvatarScaleByNeck(config.targetAvatarObject.transform, humanBoneMap2, 1.5f);
    }

    public void ProfileAutoSetup(ref EdenAutoMorpherConfig config, out Dictionary<HumanBodyBones, HashSet<Transform>> clothesHumanoidMatchedBones, out Dictionary<Transform, ClothBoneType> clothBoneTypeMap)
    {
        config.targetClothesObject = this.InstantiateTargetClothes(config.sourceClothesObject, config.targetAvatarObject, config.tagEdenMorpehrCloth, config.isRemoveAutoMorphedClothes);
        if (config.targetClothesObject == null)
        {
            throw new AutoMorpherException("Target Clothes Object is Null", "[EdenAutoMorpher_SetUpUtil] ProfileAutoSetup\n - config.targetClothesObject is null");
        }
        ProfileData profileData = new ProfileLoader().LoadProfileData(config.profileName);
        if (profileData == null)
        {
            throw new AutoMorpherException("Clothes Humanoid Matched Bones is Null", "[EdenAutoMorpher_SetUpUtil] ProfileAutoSetup\n - profile Data is null");
        }
        BoneMatchUtil boneMatchUtil = new BoneMatchUtil();
        List<BoneMatchUtil.BoneRootLocalData> bodyBones = boneMatchUtil.ConvertProfileBoneDataToRootLocalData(profileData.bones);
        List<BoneMatchUtil.BoneRootLocalData> rootLocalBones = boneMatchUtil.GetRootLocalBones(config.targetClothesObject.transform, boneMatchUtil.GetMeshBones(config.targetClothesObject.GetComponentsInChildren<SkinnedMeshRenderer>().ToList()));
        boneMatchUtil.MatchClothesToBodyBones(bodyBones, rootLocalBones, out clothesHumanoidMatchedBones, out clothBoneTypeMap, out var _);
        if (clothesHumanoidMatchedBones == null || clothesHumanoidMatchedBones.Count == 0)
        {
            throw new AutoMorpherException("Cloth Body Bones is Null", "[EdenAutoMorpher_SetUpUtil] ProfileAutoSetup\n - clothesHumanoidMatchedBones is null\n - Please check whether you have selected the correct profile for the outfit.");
        }
        if (clothBoneTypeMap == null)
        {
            throw new AutoMorpherException("Cloth Bone Type Map is Null", "[EdenAutoMorpher_SetUpUtil] ProfileAutoSetup\n - clothBoneTypeMap is null\n - Please check whether you have selected the correct profile for the outfit.");
        }
        new ProfilePoseMatchUtil().ProfilePoseMatcher(config.targetAvatarObject, config.targetBodyMeshes, config.targetClothesObject, profileData, clothesHumanoidMatchedBones, clothBoneTypeMap);
    }

    public List<SkinnedMeshRenderer> SetupBodyMeshes(GameObject bodyObject, bool isBodyAutoSetup, List<SkinnedMeshRenderer> userAllocatedBoeyMeshes, string errorPreFix = "")
    {
        new EdenAutoMorpherManager();
        List<SkinnedMeshRenderer> list = (isBodyAutoSetup ? this.GetBodyMeshes(bodyObject) : userAllocatedBoeyMeshes);
        if (list == null)
        {
            throw new AutoMorpherException(errorPreFix + "Body Mesh Is Null or Empty", errorPreFix + "Body Mesh list is null or empty");
        }
        foreach (SkinnedMeshRenderer item in list)
        {
            if (item == null)
            {
                throw new AutoMorpherException(errorPreFix + "Body Mesh Is Null", "Null Mesh in " + errorPreFix + " Body Meshes");
            }
        }
        return list;
    }

    public List<SkinnedMeshRenderer> GetBodyMeshes(GameObject avatarObject)
    {
        MeshClassifier meshClassifier = new MeshClassifier();
        List<SkinnedMeshRenderer> list = new List<SkinnedMeshRenderer>();
        Animator component = avatarObject.GetComponent<Animator>();
        if (component != null && component.avatar != null && component.avatar.isHuman)
        {
            list.Add(meshClassifier.GetBodyMesh(avatarObject.transform, component));
            {
                foreach (SkinnedMeshRenderer item in list)
                {
                    if (item == null)
                    {
                        throw new AutoMorpherException(LanguageManager.Get("UI.Exception.title.BodyMeshNull"), LanguageManager.GetFormat("UI.Exception.message.BodyMeshNull", new object[1] { avatarObject.name }));
                    }
                }
                return list;
            }
        }
        throw new AutoMorpherException(LanguageManager.Get("UI.Exception.title.BodyMeshNull"), LanguageManager.GetFormat("UI.Exception.message.BodyMeshNull", new object[1] { avatarObject.name }));
    }

    public ClothInstance SetupClothInstance(SkinnedMeshRenderer clothSMR, Dictionary<HumanBodyBones, HashSet<Transform>> clothesHumanoidMatchedBones, bool duplicateMesh)
    {
        ClothHumanoidMaskUtil clothHumanoidMaskUtil = new ClothHumanoidMaskUtil();
        if (clothSMR == null || clothSMR.sharedMesh == null)
        {
            throw new AutoMorpherException(LanguageManager.Get("UI.Exception.title.TargetRendererNull"), LanguageManager.Get("UI.Exception.message.TargetRendererNull"));
        }
        ClothInstance clothInstance = new ClothInstance(clothSMR, duplicateMesh);
        clothInstance.humanoidMatchedBones = clothesHumanoidMatchedBones;
        clothHumanoidMaskUtil.BuildExcludedVertexMaskForHandsAndHead(clothInstance);
        return clothInstance;
    }

    public ClothInstance SetupClothInstance(SkinnedMeshRenderer clothSMR, SkinnedMeshRenderer coupledSMR, MeshMatcher meshMatcher, Dictionary<HumanBodyBones, HashSet<Transform>> clothesHumanoidMatchedBones, bool duplicateMesh)
    {
        if (coupledSMR == null)
        {
            throw new AutoMorpherException("Coupled Skinned Mesh Renderer is Null", "[EdenAutoMorpher_SetupUtil] SetupClothInstance\n\n - Coupled Skinned Mesh Renderer is null");
        }
        if (coupledSMR.sharedMesh == null || coupledSMR.sharedMesh.vertexCount == 0)
        {
            throw new AutoMorpherException("Coupled Skinned Mesh Renderer's Mesh is Null or empty", "[EdenAutoMorpher_SetupUtil] SetupClothInstance\n\n - Coupled Skinned Mesh Renderer's mesh is null or no vertices");
        }
        ClothInstance clothInstance = this.SetupClothInstance(clothSMR, clothesHumanoidMatchedBones, duplicateMesh);
        if (clothInstance == null)
        {
            return null;
        }
        Vector3[] worldVertices = new WorldVertexUtil().GetWorldVertices(coupledSMR);
        clothInstance.minDistanceVector = meshMatcher.GetMinDistanceToBody(worldVertices);
        if (clothInstance.minDistanceVector == null || clothInstance.minDistanceVector.Length == 0)
        {
            throw new AutoMorpherException("Min Distance is Null", "[EdenAutoMorpher_SetupUtil] SetupClothInstance\n - minDistanceVector is null or empty");
        }
        if (clothInstance.minDistanceVector != null)
        {
            clothInstance.minDistance = clothInstance.minDistanceVector.Select((Vector3 v) => v.magnitude).ToArray();
        }
        clothInstance.isInsideVertex = meshMatcher.GetBodyInsideFlags(worldVertices);
        if (clothInstance.isInsideVertex == null || clothInstance.isInsideVertex.Length == 0)
        {
            throw new AutoMorpherException("isInsideVertex is Null", "[EdenAutoMorpher_SetupUtil] SetupClothInstance\n - isInsideVertex is null or empty");
        }
        return clothInstance;
    }

    public Transform CreateClothesArmature(EdenAutoMorpherConfig config, out Dictionary<Transform, Transform> clonedBoneMap)
    {
        clonedBoneMap = null;
        if (config.targetClothesObject == null)
        {
            throw new AutoMorpherException("Target Clothes Object is Missing", "[EdenAutoMorpherManager] CreateClothesArmature\n - config.targetClothesObject is null");
        }
        if (config.targetAvatarObject == null)
        {
            throw new AutoMorpherException("Target Avatar Object is Missing", "[EdenAutoMorpherManager] CreateClothesArmature\n - config.targetAvatarObject is null");
        }
        Animator component = config.targetAvatarObject.GetComponent<Animator>();
        if (component == null || !component.isHuman)
        {
            throw new AutoMorpherException("Target Avatar Animator is Invalid", "[EdenAutoMorpherManager] CreateClothesArmature\n - targetAvatarAnimator is null or not a Humanoid");
        }
        Transform boneTransform = component.GetBoneTransform(HumanBodyBones.Hips);
        if (boneTransform == null)
        {
            throw new AutoMorpherException("Humanoid Root Bone is Missing", "[EdenAutoMorpherManager] CreateClothesArmature\n - Animator.GetBoneTransform(HumanBodyBones.Hips) returned null");
        }
        if (config.targetBodyMeshes == null || config.targetBodyMeshes.Count == 0)
        {
            throw new AutoMorpherException("Target Body Meshes are Missing", "[EdenAutoMorpherManager] CreateClothesArmature\n - config.targetBodyMeshes is null or empty");
        }
        Transform transform = config.targetClothesObject.transform;
        Transform transform2 = this.FindArmature(config, config.targetClothesObject.transform);
        if (transform2 == null)
        {
            transform2 = new GameObject("Armature.1").transform;
            transform2.SetParent(transform, worldPositionStays: false);
            transform2.localPosition = Vector3.zero;
            transform2.localRotation = Quaternion.identity;
            transform2.localScale = Vector3.one;
        }
        if (transform2.name == "Armature")
        {
            transform2.name = "Armature.1";
        }
        Dictionary<Transform, Transform> dictionary = new Dictionary<Transform, Transform>();
        if (config.clothesHumanoidMatchedBones != null && config.clothesHumanoidMatchedBones.Count > 0)
        {
            foreach (KeyValuePair<HumanBodyBones, HashSet<Transform>> clothesHumanoidMatchedBone in config.clothesHumanoidMatchedBones)
            {
                HumanBodyBones key = clothesHumanoidMatchedBone.Key;
                HashSet<Transform> value = clothesHumanoidMatchedBone.Value;
                if (value == null || value.Count == 0)
                {
                    continue;
                }
                Transform boneTransform2 = component.GetBoneTransform(key);
                if (boneTransform2 == null)
                {
                    continue;
                }
                Transform transform3 = null;
                int num = int.MaxValue;
                foreach (Transform item in value)
                {
                    if (!(item == null))
                    {
                        int num2 = 0;
                        Transform transform4 = item;
                        while (transform4 != null)
                        {
                            num2++;
                            transform4 = transform4.parent;
                        }
                        if (num2 < num)
                        {
                            num = num2;
                            transform3 = item;
                        }
                        else if (num2 == num && transform3 != null && string.Compare(item.name, transform3.name, StringComparison.Ordinal) < 0)
                        {
                            transform3 = item;
                        }
                    }
                }
                if (!(transform3 == null) && !dictionary.ContainsKey(boneTransform2))
                {
                    dictionary.Add(boneTransform2, transform3);
                }
            }
        }
        MeshClassifier meshClassifier = new MeshClassifier();
        HashSet<Transform> hashSet = new HashSet<Transform>();
        for (int i = 0; i < config.targetBodyMeshes.Count; i++)
        {
            SkinnedMeshRenderer skinnedMeshRenderer = config.targetBodyMeshes[i];
            if (skinnedMeshRenderer == null)
            {
                continue;
            }
            HashSet<Transform> activeBones = meshClassifier.GetActiveBones(skinnedMeshRenderer);
            if (activeBones == null)
            {
                continue;
            }
            foreach (Transform item2 in activeBones)
            {
                if (item2 != null)
                {
                    hashSet.Add(item2);
                }
            }
        }
        HashSet<Transform> hashSet2 = new HashSet<Transform>(hashSet);
        foreach (Transform item3 in hashSet)
        {
            if (item3 == null)
            {
                continue;
            }
            Transform transform5 = item3;
            while (transform5 != null)
            {
                hashSet2.Add(transform5);
                if (transform5 == boneTransform)
                {
                    break;
                }
                transform5 = transform5.parent;
            }
        }
        Dictionary<Transform, Transform> dictionary2 = new Dictionary<Transform, Transform>(hashSet2.Count);
        Dictionary<Transform, Transform> dictionary3 = new Dictionary<Transform, Transform>(hashSet2.Count);
        foreach (Transform item4 in hashSet2)
        {
            if (item4 == null)
            {
                continue;
            }
            Transform transform6 = null;
            Transform transform7 = null;
            if (dictionary.TryGetValue(item4, out var value2) && value2 != null)
            {
                transform6 = value2;
                if (config.addAnchorBone)
                {
                    transform7 = new GameObject(item4.name).transform;
                    transform7.SetParent(transform2, worldPositionStays: false);
                    transform7.position = item4.position;
                    transform7.rotation = item4.rotation;
                    transform7.localScale = Vector3.one;
                    transform6.SetParent(transform7, worldPositionStays: true);
                    transform6.name = item4.name + "_clothes";
                    transform6.localPosition = Vector3.zero;
                    transform6.localScale = Vector3.one;
                }
                else
                {
                    transform6.name = item4.name;
                    transform6.position = item4.position;
                    this.ChildBonePositionPreserve(transform6, item4);
                    if (config.armatureBoneScaleCopy)
                    {
                        transform6.localScale = item4.localScale;
                    }
                    else
                    {
                        transform6.localScale = Vector3.one;
                    }
                }
            }
            else
            {
                transform6 = new GameObject(item4.name).transform;
                transform6.SetParent(transform2, worldPositionStays: false);
                transform6.position = item4.position;
                transform6.rotation = item4.rotation;
                if (config.armatureBoneScaleCopy)
                {
                    transform6.localScale = item4.localScale;
                }
                else
                {
                    transform6.localScale = Vector3.one;
                }
            }
            if (!(transform6 == null))
            {
                dictionary2[item4] = transform6;
                dictionary3[item4] = ((transform7 != null) ? transform7 : transform6);
            }
        }
        foreach (Transform item5 in hashSet2)
        {
            if (item5 == null)
            {
                continue;
            }
            if (!dictionary2.TryGetValue(item5, out var value3) || value3 == null)
            {
                throw new AutoMorpherException("Mapped Clothes Bone is Missing", "[EdenAutoMorpherManager] CreateClothesArmature\n - clonedByOriginal does not contain originalBone or mappedClothesBone is null\n - originalBone: " + item5.name);
            }
            if (!dictionary3.TryGetValue(item5, out var value4) || value4 == null)
            {
                throw new AutoMorpherException("Mapped Anchor Bone is Missing", "[EdenAutoMorpherManager] CreateClothesArmature\n - parentAnchorByOriginal does not contain originalBone or mappedAnchorBone is null\n - originalBone: " + item5.name);
            }
            if (item5 == boneTransform)
            {
                value4.SetParent(transform2, worldPositionStays: true);
                continue;
            }
            Transform parent = item5.parent;
            Transform value5;
            if (parent == null)
            {
                value4.SetParent(transform2, worldPositionStays: true);
            }
            else if (dictionary3.TryGetValue(parent, out value5) && value5 != null)
            {
                value4.SetParent(value5, worldPositionStays: true);
            }
            else
            {
                value4.SetParent(transform2, worldPositionStays: true);
            }
        }
        if (!dictionary3.TryGetValue(boneTransform, out var value6) || value6 == null)
        {
            throw new AutoMorpherException("Cloned Humanoid Root Bone is Missing", "[EdenAutoMorpherManager] CreateClothesArmature\n - failed to map clone for HumanBodyBones.Hips");
        }
        value6.SetParent(transform2, worldPositionStays: true);
        clonedBoneMap = dictionary2;
        return transform2;
    }

    private Transform FindArmature(EdenAutoMorpherConfig config, Transform clothesRoot)
    {
        if (clothesRoot == null)
        {
            throw new AutoMorpherException("Armature Root Resolve Failed", "[EdenAutoMorpherManager] FindSingleArmatureRootFromHumanoidMatchedBones\n - config is null or clothesRoot is null");
        }
        if (config.clothesHumanoidMatchedBones == null || config.clothesHumanoidMatchedBones.Count == 0)
        {
            return null;
        }
        Transform transform = null;
        bool flag = false;
        foreach (KeyValuePair<HumanBodyBones, HashSet<Transform>> clothesHumanoidMatchedBone in config.clothesHumanoidMatchedBones)
        {
            HashSet<Transform> value = clothesHumanoidMatchedBone.Value;
            if (value == null || value.Count == 0)
            {
                continue;
            }
            foreach (Transform item in value)
            {
                if (!(item == null) && (!(item != clothesRoot) || item.IsChildOf(clothesRoot)))
                {
                    flag = true;
                    Transform topChildUnderRoot = this.GetTopChildUnderRoot(item, clothesRoot);
                    if (topChildUnderRoot == null || topChildUnderRoot == clothesRoot)
                    {
                        return null;
                    }
                    if (transform == null)
                    {
                        transform = topChildUnderRoot;
                    }
                    else if (transform != topChildUnderRoot)
                    {
                        return null;
                    }
                }
            }
        }
        if (!flag)
        {
            return null;
        }
        if (transform == null || transform == clothesRoot)
        {
            return null;
        }
        return transform;
    }

    private Transform GetTopChildUnderRoot(Transform bone, Transform clothesRoot)
    {
        if (bone == null || clothesRoot == null)
        {
            return null;
        }
        if (bone == clothesRoot)
        {
            return clothesRoot;
        }
        Transform transform = bone;
        while (transform.parent != null && transform.parent != clothesRoot)
        {
            transform = transform.parent;
        }
        if (transform.parent == clothesRoot)
        {
            return transform;
        }
        return clothesRoot;
    }

    private void ChildBonePositionPreserve(Transform reusableClothBone, Transform referenceAvatarBone)
    {
        if (reusableClothBone == null || referenceAvatarBone == null)
        {
            throw new AutoMorpherException("Reusable Bone Sync Failed", "[EdenAutoMorpherManager] SyncReusableBoneRotationPreserveChildrenWorld\n - reusableClothBone or referenceAvatarBone is null");
        }
        List<Transform> list = new List<Transform>();
        List<Vector3> list2 = new List<Vector3>();
        List<Quaternion> list3 = new List<Quaternion>();
        for (int i = 0; i < reusableClothBone.childCount; i++)
        {
            Transform child = reusableClothBone.GetChild(i);
            if (!(child == null))
            {
                this.CollectDescendants(child, list);
            }
        }
        for (int j = 0; j < list.Count; j++)
        {
            Transform transform = list[j];
            list2.Add(transform.position);
            list3.Add(transform.rotation);
        }
        reusableClothBone.localRotation = referenceAvatarBone.localRotation;
        for (int k = 0; k < list.Count; k++)
        {
            list[k].SetPositionAndRotation(list2[k], list3[k]);
        }
    }

    private void CollectDescendants(Transform root, List<Transform> resultList)
    {
        if (root == null)
        {
            return;
        }
        resultList.Add(root);
        for (int i = 0; i < root.childCount; i++)
        {
            Transform child = root.GetChild(i);
            if (!(child == null))
            {
                this.CollectDescendants(child, resultList);
            }
        }
    }
}
