using System;
using System.IO;
using System.Linq;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Rendering;
using UnityEditor;
using UnityEditor.SceneManagement;

namespace EmbatteStudio.Editor
{
    // Original, lightweight meshes for Embatte's second arena. No external models.
    public static class LibraryAssets
    {
        const string Root="Assets/EmbatteStudio";
        static string Output=>Path.GetFullPath("../artifacts/studio");
        static readonly Dictionary<string,Material> Mats=new Dictionary<string,Material>();
        static readonly System.Random Rng=new System.Random(91427);
        static Vector3 V(float x,float y,float z)=>new Vector3(x,y,z);
        static Color C(string value){ColorUtility.TryParseHtmlString("#"+value,out var color);return color;}
        static float Rand(float min,float max)=>min+(float)Rng.NextDouble()*(max-min);
        static GameObject Group(string name,Transform p=null){var g=new GameObject(name);if(p)g.transform.SetParent(p,false);return g;}
        static GameObject MeshObject(string name,Mesh mesh,string mat,Transform p,Vector3 position)
        {
            var g=Group(name,p);g.transform.localPosition=position;g.AddComponent<MeshFilter>().sharedMesh=mesh;
            var r=g.AddComponent<MeshRenderer>();r.sharedMaterial=Mats[mat];r.receiveShadows=true;r.shadowCastingMode=ShadowCastingMode.On;return g;
        }
        static GameObject Primitive(string name,PrimitiveType type,Vector3 scale,Vector3 pos,string mat,Transform p)
        {
            var g=GameObject.CreatePrimitive(type);g.name=name;g.transform.SetParent(p,false);g.transform.localPosition=pos;g.transform.localScale=scale;UnityEngine.Object.DestroyImmediate(g.GetComponent<Collider>());g.GetComponent<Renderer>().sharedMaterial=Mats[mat];return g;
        }
        static GameObject Box(string name,Vector3 scale,Vector3 pos,string mat,Transform p)=>Primitive(name,PrimitiveType.Cube,scale,pos,mat,p);
        static Mesh Lathe(Vector2[] profile,int sides=12)
        {
            var points=new List<Vector3>();var normals=new List<Vector3>();var uv=new List<Vector2>();var indices=new List<int>();
            for(int j=0;j<profile.Length;j++)for(int i=0;i<=sides;i++){
                float a=i*Mathf.PI*2/sides;var tangent=profile[Mathf.Min(j+1,profile.Length-1)]-profile[Mathf.Max(0,j-1)];
                points.Add(V(Mathf.Sin(a)*profile[j].x,profile[j].y,Mathf.Cos(a)*profile[j].x));
                var normal=V(Mathf.Sin(a)*tangent.y,-tangent.x,Mathf.Cos(a)*tangent.y).normalized;
                if(Mathf.Abs(profile[j].x)<.0001f)normal=j<profile.Length/2?Vector3.down:Vector3.up;
                normals.Add(normal);uv.Add(new Vector2((float)i/sides,(float)j/(profile.Length-1)));
                if(j>0&&i<sides){int b=j*(sides+1)+i,a0=b-sides-1;indices.AddRange(new[]{a0,a0+1,b+1,a0,b+1,b});}
            }
            var mesh=new Mesh{name="Turned original surface"};mesh.SetVertices(points);mesh.SetNormals(normals);mesh.SetUVs(0,uv);mesh.SetTriangles(indices,0);mesh.RecalculateBounds();return mesh;
        }
        static GameObject Cone(string name,float bottom,float top,float height,Vector3 pos,string mat,Transform p,int sides=12)
        {return MeshObject(name,Lathe(new[]{new Vector2(0,-height/2),new Vector2(bottom,-height/2),new Vector2(top,height/2),new Vector2(0,height/2)},sides),mat,p,pos);}
        static GameObject Sphere(string name,Vector3 scale,Vector3 pos,string mat,Transform p)
        {
            var profile=new List<Vector2>();for(int i=0;i<=8;i++){float a=i*Mathf.PI/8;profile.Add(new Vector2(Mathf.Sin(a)*.5f,-Mathf.Cos(a)*.5f));}
            var g=MeshObject(name,Lathe(profile.ToArray(),12),mat,p,pos);g.transform.localScale=scale;return g;
        }
        static GameObject Rod(string name,Vector3 a,Vector3 b,float radius,string mat,Transform p,int sides=8)
        {var g=Cone(name,radius,radius*.92f,Vector3.Distance(a,b),(a+b)/2,mat,p,sides);g.transform.localRotation=Quaternion.FromToRotation(Vector3.up,b-a);return g;}
        static Material Material(string name,string color,float metal=0,float rough=.8f,bool texture=false,string glow=null)
        {
            var m=new Material(Shader.Find("Standard")){name=name,color=C(color),enableInstancing=true};m.SetFloat("_Metallic",metal);m.SetFloat("_Glossiness",1-rough);
            if(texture){int n=128;var tex=new Texture2D(n,n,TextureFormat.RGB24,false);var pixels=new Color[n*n];var rand=new System.Random(name.Length*121);
                for(int y=0;y<n;y++)for(int x=0;x<n;x++){
                    float grain=(float)rand.NextDouble(),coarse=Mathf.PerlinNoise(x/19f,y/19f),v=.62f+.25f*coarse+.13f*grain;
                    if(name.Contains("Cloth"))v=.8f+(x%3==0||y%3==0?-.09f:.08f)+grain*.07f;
                    if(name.Contains("Wood"))v=.7f+.2f*Mathf.PerlinNoise(x/3f,y/35f)+grain*.1f;
                    pixels[y*n+x]=new Color(v,v,v,1);
                }tex.SetPixels(pixels);tex.Apply();var file=Root+"/Textures/"+name+".png";File.WriteAllBytes(file,tex.EncodeToPNG());UnityEngine.Object.DestroyImmediate(tex);AssetDatabase.ImportAsset(file);var imp=(TextureImporter)AssetImporter.GetAtPath(file);imp.isReadable=true;imp.wrapMode=TextureWrapMode.Repeat;imp.SaveAndReimport();m.mainTexture=AssetDatabase.LoadAssetAtPath<Texture2D>(file);
            }
            if(glow!=null){m.EnableKeyword("_EMISSION");m.SetColor("_EmissionColor",C(glow)*1.1f);}
            var path=Root+"/Materials/"+name+".mat";if(File.Exists(path))AssetDatabase.DeleteAsset(path);AssetDatabase.CreateAsset(m,path);Mats[name]=m;return m;
        }
        static void Materials()
        {
            Material("Snow","eef4f6",0,.92f,true);Material("Ice","92c9db",.15f,.28f,true);Material("DeepIce","426982",.2f,.36f,true);Material("Water","173f54",.2f,.22f);
            Material("Rock","566470",.06f,.92f,true);Material("Pine","344f4c",0,.96f,true);Material("BarkWood","6c5648",0,.89f,true);Material("Leather","483c39",0,.72f,true);
            Material("TeamBand","db6552",.04f,.64f,true);Material("Copper","ae7954",.67f,.4f);Material("Steel","a3b8c1",.68f,.35f);Material("Glass","263f48",.65f,.18f);Material("WoolCloth","43637b",0,.94f,true);
            Material("GoldGlow","ffe3a6",0,.45f,false,"e5b468");Material("BlueGlow","aadfed",.1f,.4f,false,"70b8d4");Material("AmberCloth","b69a4c",0,.82f,true);Material("TealCloth","3d7172",0,.87f,true);
            Material("GreenCloth","536b52",0,.91f,true);Material("IceCloth","849aaa",0,.86f,true);Material("Mushroom","a17663",0,.83f,true);Material("MushroomStem","d2c5a7",0,.93f,true);
            Material("Brick","715148",0,.91f,true);Material("Concrete","93938a",.08f,.88f,true);Material("DarkMetal","404b50",.52f,.56f,true);Material("Grass","607657",0,.97f,true);Material("PaleStone","afafa5",.05f,.82f,true);
        }
        static void Combine(GameObject root)
        {
            var filters=root.GetComponentsInChildren<MeshFilter>();
            foreach(var group in filters.GroupBy(f=>f.GetComponent<Renderer>().sharedMaterial).ToArray()){
                var mesh=new Mesh{name=root.name+"_"+group.Key.name,indexFormat=IndexFormat.UInt32};mesh.CombineMeshes(group.Select(f=>new CombineInstance{mesh=f.sharedMesh,transform=root.transform.worldToLocalMatrix*f.transform.localToWorldMatrix}).ToArray(),true,true);
                var g=Group(group.Key.name,root.transform);g.AddComponent<MeshFilter>().sharedMesh=mesh;g.AddComponent<MeshRenderer>().sharedMaterial=group.Key;
            }
            foreach(var f in filters)if(f)UnityEngine.Object.DestroyImmediate(f.gameObject);
        }
        static GameObject Clone(string path,string name)
        {var g=UnityEngine.Object.Instantiate(AssetDatabase.LoadAssetAtPath<GameObject>(path));g.name=name;return g;}
        static void Replace(GameObject g,Func<string,string> map)
        {foreach(var r in g.GetComponentsInChildren<MeshRenderer>()){var key=map(r.sharedMaterial.name);if(key!=null)r.sharedMaterial=Mats[key];}}
        static GameObject Painter(string name,bool engineer)
        {
            var g=Clone("Assets/Tinta/Prefabs/PainterAzure.prefab",name);var p=g.transform;
            Replace(g,n=>n.Contains("Azure")||n.Contains("Blue")?engineer?"TealCloth":"AmberCloth":null);
            if(engineer){
                Sphere("Reinforced helmet",V(.59f,.18f,.59f),V(0,1.79f,0),"TealCloth",p);Box("Helmet lamp",V(.15f,.12f,.11f),V(0,1.83f,.27f),"Steel",p);Sphere("Lamp lens",V(.08f,.08f,.04f),V(0,1.83f,.34f),"GoldGlow",p);
                for(int i=0;i<3;i++)Box("Utility pouch",V(.16f,.2f,.13f),V((i-1)*.19f,.9f,.24f),"Leather",p);
                Rod("Long roller handle",V(.36f,.7f,.12f),V(.5f,1.45f,.52f),.025f,"Steel",p);Rod("Paint roller",V(.32f,1.48f,.52f),V(.68f,1.48f,.52f),.065f,"TeamBand",p,12);
            }else{
                Sphere("Protective hood",V(.63f,.6f,.58f),V(0,1.57f,-.03f),"AmberCloth",p);Sphere("Wraparound faceplate",V(.52f,.31f,.18f),V(0,1.6f,.25f),"Glass",p);
                for(int side=-1;side<=1;side+=2)Cone("Air filter",.1f,.1f,.08f,V(side*.17f,1.39f,.33f),"DarkMetal",p,12).transform.localRotation=Quaternion.Euler(90,0,0);
                foreach(float y in new[]{.45f,.74f})Box("Reflective strip",V(.43f,.045f,.025f),V(0,y,.22f),"Steel",p);
            }
            return g;
        }
        static GameObject Witch(string name,bool frost)
        {
            var g=Clone("Assets/Vassouras/Prefabs/WitchAmber.prefab",name);var p=g.transform;
            Replace(g,n=>n=="AmberCloth"?frost?"IceCloth":"GreenCloth":n=="GoldMagic"?frost?"BlueGlow":"GoldGlow":n=="Bronze"?frost?"Steel":"Copper":null);
            if(frost){
                for(int i=0;i<9;i++){float a=i*Mathf.PI*2/9;Sphere("Fur mantle",V(.2f,.18f,.2f),V(Mathf.Sin(a)*.24f,1.32f,Mathf.Cos(a)*.18f),"Snow",p);}
                for(int i=0;i<5;i++){var shard=Cone("Ice broom fin",.085f,0,.6f,V((i-2)*.09f,.48f,-1.35f),"Ice",p,5);shard.transform.localEulerAngles=V(65+(i%2)*12,0,(i-2)*12);}
                Cone("Hat ice pin",.05f,0,.27f,V(.22f,2.12f,.04f),"BlueGlow",p,5);
            }else{
                for(int i=0;i<7;i++){float a=i*Mathf.PI*2/7;Sphere("Leaf brim",V(.19f,.05f,.32f),V(Mathf.Sin(a)*.43f,1.9f,Mathf.Cos(a)*.34f),"Pine",p).transform.localEulerAngles=V(0,a*Mathf.Rad2Deg,0);}
                Rod("Broom branch",V(0,.67f,.3f),V(.23f,.9f,1.07f),.045f,"BarkWood",p);Sphere("Amber seed charm",V(.13f,.18f,.13f),V(.23f,.79f,1.02f),"GoldGlow",p);
                Cone("Herbal canister",.09f,.09f,.25f,V(.33f,.89f,-.16f),"Copper",p,10);
            }
            Combine(g);return g;
        }
        static GameObject Snowball(string name,int style)
        {
            var g=Group(name);var p=g.transform;var profile=new List<Vector2>();for(int i=0;i<=16;i++){float a=i*Mathf.PI/16;profile.Add(new Vector2(Mathf.Sin(a),-Mathf.Cos(a)));}
            var mesh=Lathe(profile.ToArray(),28);var vertices=mesh.vertices;for(int i=0;i<vertices.Length;i++){var v=vertices[i];float n=Mathf.PerlinNoise(v.x*3.5f+4,v.y*4+v.z*2+9);vertices[i]=v*(.976f+n*.048f);}mesh.vertices=vertices;mesh.normals=vertices.Select(v=>v.normalized).ToArray();MeshObject("Packed snow body",mesh,"Snow",p,Vector3.zero);
            // A fabric equator makes the identity readable while the snow rotates.
            var band=Lathe(new[]{new Vector2(.996f,-.065f),new Vector2(1.013f,-.04f),new Vector2(1.013f,.04f),new Vector2(.996f,.065f)},40);var b=MeshObject("Team identity band",band,"TeamBand",p,Vector3.zero);b.transform.localEulerAngles=V(18,0,12);
            foreach(int side in new[]{-1,1})Sphere("Obsidian eye",V(.16f,.17f,.095f),V(side*.24f,.2f,.944f),"Glass",p);
            if(style==0){
                for(int i=0;i<4;i++)Sphere("Snow clump",V(.19f,.15f,.21f),V(Mathf.Sin(i*2)*.69f,Mathf.Cos(i*2)*.62f,.55f),"Snow",p);
                var scarf=Box("Trailing fabric knot",V(.15f,.48f,.07f),V(.73f,-.2f,.6f),"TeamBand",p);scarf.transform.localEulerAngles=V(8,0,-25);
            }else if(style==1){
                for(int i=0;i<7;i++){float a=i*Mathf.PI*2/7;var crystal=Cone("Layered ice armour",.25f,.11f,.52f,V(Mathf.Sin(a)*.84f,.28f,Mathf.Cos(a)*.84f),"Ice",p,5);crystal.transform.localEulerAngles=V(Mathf.Cos(a)*32,0,-Mathf.Sin(a)*32);}
                for(int i=0;i<3;i++){var shard=Cone("Frost crest",.12f,0,.43f,V((i-1)*.21f,.95f,-.1f),"DeepIce",p,5);shard.transform.localEulerAngles=V(-12,0,(i-1)*-15);}
            }else{
                Sphere("Knitted cap",V(1.47f,.75f,1.47f),V(0,.84f,0),"WoolCloth",p);Cone("Ribbed wool brim",.75f,.71f,.15f,V(0,.71f,0),"WoolCloth",p,32);Sphere("Wool pompom",V(.34f,.32f,.34f),V(.05f,1.28f,0),"Snow",p);
                foreach(int side in new[]{-1,1}){Sphere("Leather goggle rim",V(.39f,.28f,.1f),V(side*.24f,.2f,.94f),"Leather",p);Sphere("Amber goggle lens",V(.3f,.2f,.07f),V(side*.24f,.2f,1.003f),"GoldGlow",p);}
                Rod("Goggle bridge",V(-.12f,.2f,1f),V(.12f,.2f,1f),.035f,"Copper",p);
            }
            Combine(g);return g;
        }
        static void Pine(Transform p,Vector3 pos,float h)
        {
            var root=Group("Snow laden fir",p);root.transform.localPosition=pos;Rod("Pine trunk",V(0,0,0),V(0,h*.85f,0),h*.06f,"BarkWood",root.transform,7);
            for(int k=0;k<4;k++){float y=h*(.27f+k*.19f),r=h*(.31f-k*.065f);Cone("Asymmetric fir branches",r,.02f,h*.4f,V(0,y,0),"Pine",root.transform,9).transform.localEulerAngles=V(0,k*34,4);Cone("Snow on boughs",r*.82f,.02f,h*.27f,V(0,y+h*.07f,0),"Snow",root.transform,9).transform.localEulerAngles=V(0,k*34,4);}
        }
        static void Lamp(Transform p,Vector3 pos)
        {
            var root=Group("Storm lantern",p);root.transform.localPosition=pos;Cone("Lantern plinth",.25f,.19f,.25f,V(0,.12f,0),"Rock",root.transform,8);Rod("Forged post",V(0,.2f,0),V(0,1.3f,0),.05f,"DarkMetal",root.transform);Box("Lantern glass",V(.24f,.33f,.24f),V(0,1.35f,0),"GoldGlow",root.transform);Cone("Weather hood",.24f,.02f,.17f,V(0,1.59f,0),"Copper",root.transform,4);
        }
        static GameObject Lake(string name,int style)
        {
            var g=Group(name);var p=g.transform;
            for(int i=0;i<36;i++){float a=i*Mathf.PI*2/36,r=10.3f+Rand(-.3f,.3f);Sphere("Sculpted snowbank",V(Rand(1.5f,2.6f),Rand(.5f,1f),Rand(1.4f,2.2f)),V(Mathf.Sin(a)*r,-.28f,Mathf.Cos(a)*r),"Snow",p);}
            for(int i=0;i<16;i++){float a=i*Mathf.PI*2/16+.17f,r=11.7f+Rand(-.4f,1f);if(style==0||style==2&&i%2==0)Pine(p,V(Mathf.Sin(a)*r,-.35f,Mathf.Cos(a)*r),Rand(2.5f,4.5f));else{
                var rock=Cone("Glacier wall",Rand(.65f,1.05f),Rand(.3f,.65f),Rand(1.5f,3.8f),V(Mathf.Sin(a)*r,.8f,Mathf.Cos(a)*r),style==1?"Ice":"Rock",p,6);rock.transform.localEulerAngles=V(Rand(-15,15),i*21,Rand(-10,10));
            }}
            for(int i=0;i<14;i++){float a=Rand(0,Mathf.PI*2),r=Rand(10,13);var b=Sphere("Weathered shore stone",V(Rand(.5f,1.1f),Rand(.3f,.8f),Rand(.4f,1f)),V(Mathf.Sin(a)*r,0,Mathf.Cos(a)*r),"Rock",p);b.transform.localRotation=Quaternion.Euler(Rand(-15,15),Rand(0,180),Rand(-15,15));}
            if(style==2)for(int i=0;i<8;i++){float a=i*Mathf.PI/4;Lamp(p,V(Mathf.Sin(a)*10.3f,0,Mathf.Cos(a)*10.3f));}
            if(style==0){Box("Abandoned wooden pier",V(2.1f,.15f,2.9f),V(-7.4f,.06f,8.5f),"BarkWood",p);for(int i=0;i<4;i++)Rod("Pier post",V(-8.3f+i*.6f,-.5f,9.8f),V(-8.3f+i*.6f,.7f,9.8f),.075f,"BarkWood",p);}
            Combine(g);
            // Kept separate: the running game replaces this showcase surface with breakable cells.
            Cone("LakeSurface",9,9,.38f,V(0,-.23f,0),style==2?"DeepIce":"Ice",p,72);
            Cone("LakeWater",9.2f,9.2f,.06f,V(0,-.6f,0),"Water",p,64);
            return g;
        }
        static GameObject WitchMap(string name,bool grove)
        {
            var g=Clone("Assets/Vassouras/Prefabs/TwilightEnvironment.prefab",name);var p=g.transform;
            Replace(g,n=>n=="Basalt"?grove?"Rock":"PaleStone":n=="EdgeStone"?grove?"Grass":"Concrete":n=="Moss"?"Grass":n=="Rune"?"BlueGlow":null);
            for(int i=0;i<8;i++){float a=(i+.5f)*Mathf.PI/4,r=10.8f;var root=Group(grove?"Tall forest mushroom":"Moon sanctuary column",p);root.transform.localPosition=V(Mathf.Sin(a)*r,0,Mathf.Cos(a)*r);
                if(grove){Cone("Mushroom stem",.19f,.13f,2.1f,V(0,1.05f,0),"MushroomStem",root.transform);Sphere("Weathered mushroom cap",V(1.5f,.43f,1.5f),V(0,2.05f,0),"Mushroom",root.transform);for(int j=0;j<5;j++){float b=j*1.2566f;Sphere("Cap fleck",V(.16f,.02f,.15f),V(Mathf.Sin(b)*.4f,2.235f,Mathf.Cos(b)*.4f),"MushroomStem",root.transform);}}
                else {Cone("Fluted column",.29f,.26f,2.9f,V(0,1.45f,0),"PaleStone",root.transform,10);Box("Column capital",V(.8f,.19f,.8f),V(0,2.91f,0),"PaleStone",root.transform);Cone("Moon shard",.24f,0,.9f,V(0,3.45f,0),"BlueGlow",root.transform,5);}
            }
            Combine(g);return g;
        }
        static GameObject PaintMap(string name,bool garden)
        {
            var g=Group(name);var p=g.transform;Box("Playable deck",V(11.3f,.42f,20.3f),V(5.5f,-.27f,10),garden?"Concrete":"DarkMetal",p);
            for(int side=0;side<2;side++){float x=side==0?-.95f:11.95f;Box("Perimeter walkway",V(1.6f,.3f,21.5f),V(x,-.12f,10),garden?"PaleStone":"Brick",p);
                for(int z=0;z<=20;z+=2){Rod("Fence post",V(x,0,z),V(x,1.05f,z),.045f,"DarkMetal",p);if(garden&&z%4==0){Box("Planter box",V(.84f,.55f,1.2f),V(x,.29f,z),"Concrete",p);for(int j=0;j<3;j++){Rod("Plant stem",V(x,.5f,z+(j-1)*.3f),V(x+.12f,.96f,z+(j-1)*.3f),.024f,"Grass",p);Sphere("Garden leaves",V(.37f,.3f,.29f),V(x+.05f,.9f,z+(j-1)*.3f),"Grass",p);}}}
                Rod("Perimeter handrail",V(x,1.05f,0),V(x,1.05f,20),.04f,"DarkMetal",p);
            }
            foreach(float z in new[]{-.95f,20.95f}){Box("End walkway",V(14.5f,.25f,1.65f),V(5.5f,-.1f,z),garden?"PaleStone":"Brick",p);if(!garden){foreach(float x in new[]{-.55f,11.55f})Box("Foundry upright",V(.24f,2.9f,.24f),V(x,1.4f,z),"DarkMetal",p);Box("Foundry lintel",V(12.4f,.28f,.32f),V(5.5f,2.9f,z),"DarkMetal",p);for(int x=0;x<11;x+=2)Cone("Copper pressure pipe",.15f,.15f,1.7f,V(x,.78f,z),"Copper",p,10);}}
            if(garden)for(int i=0;i<4;i++)Lamp(p,V(i%2==0?-.95f:11.95f,0,i<2?2:18));Combine(g);return g;
        }
        static void Save(GameObject g)
        {
            foreach(var f in g.GetComponentsInChildren<MeshFilter>())if(!AssetDatabase.Contains(f.sharedMesh))AssetDatabase.CreateAsset(f.sharedMesh,AssetDatabase.GenerateUniqueAssetPath(Root+"/Meshes/"+g.name+"_"+f.name+".asset"));
            PrefabUtility.SaveAsPrefabAsset(g,Root+"/Prefabs/"+g.name+".prefab");Tinta.Editor.NativeExport.Write(g,Output+"/"+g.name+".json");
        }
        static void Capture(Camera camera,string path)
        {
            const int size=640;var rt=new RenderTexture(size,size,24){antiAliasing=4};rt.Create();camera.targetTexture=rt;camera.Render();var old=RenderTexture.active;RenderTexture.active=rt;var tex=new Texture2D(size,size,TextureFormat.RGB24,false);tex.ReadPixels(new Rect(0,0,size,size),0,0);tex.Apply();File.WriteAllBytes(path,tex.EncodeToPNG());camera.targetTexture=null;RenderTexture.active=old;rt.Release();UnityEngine.Object.DestroyImmediate(rt);UnityEngine.Object.DestroyImmediate(tex);
        }
        public static void CaptureExisting()
        {
            Directory.CreateDirectory(Output);EditorSceneManager.NewScene(NewSceneSetup.EmptyScene,NewSceneMode.Single);PlayerSettings.colorSpace=ColorSpace.Linear;
            RenderSettings.ambientMode=AmbientMode.Trilight;RenderSettings.ambientSkyColor=C("b7c7d6")*.65f;RenderSettings.ambientEquatorColor=C("8395a4")*.5f;RenderSettings.ambientGroundColor=C("52616b")*.35f;
            var sun=new GameObject("Studio sun").AddComponent<Light>();sun.type=LightType.Directional;sun.color=C("ffe8ca");sun.intensity=1.2f;sun.transform.rotation=Quaternion.Euler(47,-28,0);sun.shadows=LightShadows.Soft;
            var fill=new GameObject("Studio fill").AddComponent<Light>();fill.type=LightType.Directional;fill.color=C("b0d0ee");fill.intensity=.45f;fill.transform.rotation=Quaternion.Euler(30,145,0);
            var camera=new GameObject("Catalog camera").AddComponent<Camera>();camera.clearFlags=CameraClearFlags.SolidColor;camera.backgroundColor=C("23333e");camera.fieldOfView=38;
            foreach(var path in new[]{"Tinta/Prefabs/PainterAzure","Tinta/Prefabs/CargoCase","Tinta/Prefabs/PumpStation","Vassouras/Prefabs/WitchAmber","Vassouras/Prefabs/PaintCharge","Vassouras/Prefabs/Runestone","Vassouras/Prefabs/MoonBrazier"}){
                string name=Path.GetFileName(path);var g=Clone("Assets/"+path+".prefab",name);var renderers=g.GetComponentsInChildren<Renderer>();var bounds=renderers[0].bounds;foreach(var r in renderers)bounds.Encapsulate(r.bounds);float distance=Mathf.Max(bounds.size.x,bounds.size.y,bounds.size.z)*2.2f;camera.transform.position=bounds.center+V(.7f,.36f,1).normalized*distance;camera.transform.LookAt(bounds.center);Capture(camera,Output+"/"+name+".png");UnityEngine.Object.DestroyImmediate(g);
            }
            Debug.Log("EMBATTE_EXISTING_THUMBNAILS_OK");
        }
        [MenuItem("Embatte/Gerar biblioteca de variantes")]
        public static void Generate()
        {
            foreach(var dir in new[]{"Materials","Textures","Meshes","Prefabs","Scenes"})Directory.CreateDirectory(Root+"/"+dir);Directory.CreateDirectory(Output);AssetDatabase.Refresh();Mats.Clear();Materials();
            var scene=EditorSceneManager.NewScene(NewSceneSetup.EmptyScene,NewSceneMode.Single);PlayerSettings.colorSpace=ColorSpace.Linear;GraphicsSettings.defaultRenderPipeline=null;QualitySettings.renderPipeline=null;
            var assets=new[]{Painter("PainterHazmat",false),Painter("PainterEngineer",true),Witch("WitchVerdant",false),Witch("WitchFrost",true),Snowball("SnowballClassic",0),Snowball("SnowballGlacier",1),Snowball("SnowballExpedition",2),Lake("BorealLake",0),Lake("GlacialFjord",1),Lake("MidnightLake",2),WitchMap("MoonSanctuary",false),WitchMap("MushroomGrove",true),PaintMap("FoundryCourt",false),PaintMap("RoofGarden",true)};
            foreach(var g in assets){Save(g);g.SetActive(false);}AssetDatabase.SaveAssets();
            RenderSettings.ambientMode=AmbientMode.Trilight;RenderSettings.ambientSkyColor=C("b7c7d6")*.65f;RenderSettings.ambientEquatorColor=C("8395a4")*.5f;RenderSettings.ambientGroundColor=C("52616b")*.35f;
            var sun=new GameObject("Studio sun").AddComponent<Light>();sun.type=LightType.Directional;sun.color=C("ffe8ca");sun.intensity=1.2f;sun.transform.rotation=Quaternion.Euler(47,-28,0);sun.shadows=LightShadows.Soft;
            var fill=new GameObject("Studio fill").AddComponent<Light>();fill.type=LightType.Directional;fill.color=C("b0d0ee");fill.intensity=.45f;fill.transform.rotation=Quaternion.Euler(30,145,0);
            var camera=new GameObject("Catalog camera").AddComponent<Camera>();camera.clearFlags=CameraClearFlags.SolidColor;camera.backgroundColor=C("23333e");camera.fieldOfView=38;
            if(SystemInfo.graphicsDeviceType!=GraphicsDeviceType.Null)foreach(var g in assets){g.SetActive(true);var renderers=g.GetComponentsInChildren<Renderer>();var bounds=renderers[0].bounds;foreach(var r in renderers)bounds.Encapsulate(r.bounds);bool map=bounds.size.x>5;float distance=Mathf.Max(bounds.size.x,bounds.size.y,bounds.size.z)*(map?1.75f:2.2f);var angle=map?V(.37f,1,.68f):V(.7f,.36f,1);camera.transform.position=bounds.center+angle.normalized*distance;camera.transform.LookAt(bounds.center);Capture(camera,Output+"/"+g.name+".png");g.SetActive(false);}
            AssetDatabase.ExportPackage(new[]{Root,"Assets/Tinta","Assets/Vassouras"},Output+"/Embatte-BibliotecaDeVariantes.unitypackage",ExportPackageOptions.Recurse);Debug.Log("EMBATTE_STUDIO_ASSETS_OK");
        }
    }
}
