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

namespace Thousandto.Launcher.ExternalLibs
{
    /// <summary>
    /// 材质球资源数据
    /// </summary>
    [Serializable]
    public class MatrialAssetData
    {
        //材质属性索引
        public int Index = -1;
        //是否是拖尾材质球
        public bool IsTrail = false;
        private SceneAssetsDiscriptFile _script = null;

        #region//公共函数
        /// <summary>
        /// 
        /// </summary>
        /// <param name="node"></param>
        /// <param name="mat"></param>
        /// <param name="script"></param>
        /// <param name="isSubMat">是否是子材质球</param>
        public void SetMatrialAssetData(SceneNodeCommpent node, Material mat, Material defaultMat, SceneAssetsDiscriptFile script, bool isSubMat = false, int index= 0)
        {
#if UNITY_EDITOR
            if (!isSubMat)
            {
                //if (!node.IsSaveTexture)
                //{
                //    SetMatSaveData(node, mat, defaultMat, script);
                //}
                //else
                //{
                //    Index = node.MatProList[index];
                //}
                SetMatSaveData(node, mat, defaultMat, script);
            }
            else
            {
                if (!node.IsSaveSuMatTex(index))
                {
                    SetMatSaveData(node, mat, defaultMat, script, true);
                }
                else
                {
                    Index = node.MatProList[index];
                }
            }
#endif
        }
        #endregion

        #region//私有函数

        //设置材质球数据
        private void SetMatSaveData(SceneNodeCommpent node, Material mat, Material defaultMat, SceneAssetsDiscriptFile script, bool isSubMat = false)
        {
            if (mat == null)
                return;
            var shader = mat.shader;
            Shader defaultShader = null;
            if (defaultMat != null)
            {
                defaultShader = defaultMat.shader;
            }
            _script = script;
            //获取shader属性个数
            List<MatTexPropertyIndex> texPrIndex = new List<MatTexPropertyIndex>();
            List<MatPropertyVector> vectorList = new List<MatPropertyVector>();
            List<MatPropertyColor> colorList = new List<MatPropertyColor>();
            List<MatPropertyFloat> floatList = new List<MatPropertyFloat>();
            List<Vector2> texOffsetList = new List<Vector2>();
            List<Vector2> texScaleList = new List<Vector2>();
            MatAssetsProperty property = new MatAssetsProperty();
            property.name = shader.name;//mat.name;
            property.matName = mat.name;
#if UNITY_EDITOR
            int shaderPropertyCount = UnityEditor.ShaderUtil.GetPropertyCount(shader);
            for (int i = 0; i < shaderPropertyCount; i++)
            {
                var type = UnityEditor.ShaderUtil.GetPropertyType(shader, i);
                var name = UnityEditor.ShaderUtil.GetPropertyName(shader, i);
                if (node.IsUseDefaultShader)
                {
                    if (type != UnityEditor.ShaderUtil.ShaderPropertyType.TexEnv)
                        continue;
                }
                switch (type)
                {
                    case UnityEditor.ShaderUtil.ShaderPropertyType.TexEnv:
                        Texture tex = null;
                        Vector2 offset = Vector2.zero;
                        Vector2 scale = Vector2.one;
                        if (node.IsUseDefaultShader)
                        {
                            tex = mat.mainTexture;
                        }
                        else
                        {
                            tex = mat.GetTexture(name);
                            offset = mat.GetTextureOffset(name);
                            scale = mat.GetTextureScale(name);
                        }
                        
                        if (tex != null)
                        {
                            string folderPath = string.Empty;
                            bool isVfxTex = false;
                            string path = UnityEditor.AssetDatabase.GetAssetPath(tex);
                            if (path.Contains("vfx/fxresources/texture"))
                            {
                                isVfxTex = true;
                            }
                            //string path = GetTexturePath(tex, ref folderPath, ref isVfxTex);
                            MatTexPropertyIndex texData = new MatTexPropertyIndex();
                            if (isVfxTex)
                            {
                                //string fullPath = GetFullTexPath(tex);
                                int index = script.GetTexturePathIndex(name, path);
                                texData.Index = index;
                                texData.tex = null;
                            }
                            else
                            {
                                texData.Index = -1;
                                texData.tex = tex;
                            }
                            texData.Name = name;
                            var multiScript = _script.GetMultiTexScript();
                            List<MultiTexIndex> tempList = new List<MultiTexIndex>();
                            if (multiScript != null)
                            {
                                int length = multiScript.MultiTexs.Length;
                                for (int k = 0; k < length; k++)
                                {
                                    var multiTex = multiScript.MultiTexs[k];
                                    string[] strs = tex.name.Split('_');
                                    if (strs.Length > 1)
                                    {
                                        if (multiTex.name.Contains(strs[0]))
                                        {
                                            strs = multiTex.name.Split('_');
                                            if (strs.Length > 1)
                                            {
                                                int multiIndex = int.TryParse(strs[1], out multiIndex) ? multiIndex : 0;
                                                MultiTexIndex data = new MultiTexIndex();
                                                data.Index = k;
                                                data.MultiIndex = multiIndex;
                                                tempList.Add(data);
                                            }
                                        }
                                    }
                                }
                            }
                            texData.MultiIndex = tempList.ToArray();
                            texPrIndex.Add(texData);
                            //保存texture资源
//                            folderPath = GetFolderPath(folderPath);
//                            if (!Directory.Exists(folderPath))
//                                Directory.CreateDirectory(folderPath);
//                            var savePath = GetSaveTexPath(tex);
//#if UNITY_EDITOR
//                            if (node != null && !node.IsSaveTexture)
//                            {
//                                if (!File.Exists(savePath) && File.Exists(fullPath))
//                                {
//                                    UnityEditor.AssetDatabase.CopyAsset(UnityEditor.AssetDatabase.GetAssetPath(tex), savePath);
//                                }
//                            }
//#endif
                        }
                        texOffsetList.Add(offset);
                        texScaleList.Add(scale);
                        break;
                    case UnityEditor.ShaderUtil.ShaderPropertyType.Vector:
                        var vect = mat.GetVector(name);
                        vectorList.Add(new MatPropertyVector() { Name = name, Value = vect });
                        break;
                    case UnityEditor.ShaderUtil.ShaderPropertyType.Color:
                        var color = mat.GetColor(name);
                        colorList.Add(new MatPropertyColor() { Name = name, Value = color });
                        break;
                    default:
                        var f = mat.GetFloat(name);
                        floatList.Add(new MatPropertyFloat() { Name = name, Value = f });
                        break;
                }
            }
#endif
            //设置序列化的值
            if (node.IsUseDefaultShader)
            {
                if(defaultShader!= null)
                    property.ShaderName = defaultShader.name;
            }
            else
            {
                property.ShaderName = shader.name;
            }
            property.TexIndexs = texPrIndex.ToArray();
            property.TexOffset = texOffsetList.ToArray();
            property.TexScale = texScaleList.ToArray();
            property.Vec = vectorList.ToArray();
            property.Color = colorList.ToArray();
            property.Float = floatList.ToArray();
            if (mat.renderQueue <= 0)
            {
                property.Rdq = shader.renderQueue;
            }
            else
            {
                property.Rdq = mat.renderQueue;
            }
            Index = _script.GetMatPropertyIndex(property);
            //if (!isSubMat)
            //{
            //    if (node.MatProList.Count == 0)
            //    {
            //        node.MatProList.Add(MatPrIndex);
            //    }
            //}
            //else
            //{
            //    node.MatProList.Add(MatPrIndex);
            //}
            node.MatProList.Add(Index);
        }

        private string GetTexturePath(Texture tex, ref string folderPath, ref bool isVfxTex)
        {
            isVfxTex = false;
            string path = string.Empty;
            if (tex == null)
                return path;
#if UNITY_EDITOR
            path = UnityEditor.AssetDatabase.GetAssetPath(tex);
            if (path.Contains("vfx/fxresources/texture"))
            {
                isVfxTex = true;
            }
#endif
            string[] strs = path.Split('.');
            if (strs != null && strs.Length != 0)
            {
                path = strs[0];
            }
            path = path.Replace("Assets/GameAssets/RawResources/scene/","");
            string newName = tex.name;
            if (string.Equals(UnityEngine.SceneManagement.SceneManager.GetActiveScene().name, newName))
            {
                newName = string.Format("{0}_tex", newName);
                path = path.Replace(string.Format("/{0}", tex.name),"");
                path = path + "/"+newName;
            }
            path = string.Format("Texture/scene/{0}", path);
            folderPath = path.Replace(string.Format("/{0}", tex.name), "");
            return path;
        }
        //获取纹理完整路径
        private string GetFullTexPath(Texture tex)
        {
            string fullPath = string.Empty;
            if (tex != null)
            {
                string assetPath = string.Empty;
#if UNITY_EDITOR
                assetPath = UnityEditor.AssetDatabase.GetAssetPath(tex);
#endif
                int index = assetPath.LastIndexOf("GameAssets");
                if (index >= 0)
                {
                    assetPath = assetPath.Substring(index);
                }
                fullPath = Application.dataPath + "/" + assetPath;
            }
            //string[] strs = fullPath.Split('.');
            //if (strs != null && strs.Length != 0)
            //{
            //    fullPath = strs[0];
            //}
            return fullPath;
        }
        //获取纹理文件夹的路径
        private string GetFolderPath(string path)
        {
            var folderPath = string.Format("GameAssets/Resources/{0}", path);
            folderPath = Application.dataPath + "/" + folderPath;
            return folderPath;
        }
        //获取纹理资源路劲
        public string GetSaveTexPath( Texture tex )
        {
            string path = string.Empty;
            if (tex == null)
                return path;
#if UNITY_EDITOR
            path = UnityEditor.AssetDatabase.GetAssetPath(tex);
#endif
            path = path.Replace("Assets/GameAssets/RawResources/scene/", "");
            string newName = tex.name;
            if (string.Equals(UnityEngine.SceneManagement.SceneManager.GetActiveScene().name, newName))
            {
                newName = string.Format("{0}_tex", newName);
                path = path.Replace(string.Format("/{0}", tex.name), "/");
                path = path.Replace(".", string.Format("{0}.",newName));//path + "/"+newName;
            }
            path = string.Format("Texture/scene/{0}", path);
            string savePath = Application.dataPath + string.Format("/GameAssets/Resources/{0}", path);
            return savePath;
        }
        #endregion
    }
    /// <summary>
    /// 材质球资源属性
    /// </summary>
    [Serializable]
    public class MatAssetsProperty
    {
        public string matName = string.Empty;
        public string name = string.Empty;
        //shader名字
        public string ShaderName = string.Empty;
        //纹理列表
        public MatTexPropertyIndex[] TexIndexs;
        //四元值列表
        public MatPropertyVector[] Vec;
        //颜色列表
        public MatPropertyColor[] Color;
        //浮点值列表
        public MatPropertyFloat[] Float;
        //纹理的偏移
        public Vector2[] TexOffset;
        //纹理的缩放信息--tile
        public Vector2[] TexScale;
        //记录RenderQueen
        public int Rdq = 0;
    }
}