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

public enum VariableType
{
    String, 
    Bool,
    Float,
    Int,
    Vector2,
    Vector3,
    ImageType,
    Direction,
}

public class ClassData
{
    public VariableType Type;
    public string Name;
    public string Des;
}



public class ReactiveClass : EditorWindow
{
    [MenuItem("Tools/Class/Reactive Class")]

    static void ReactiveClassWindow()
    {
        var window = (ReactiveClass)EditorWindow.GetWindow(typeof(ReactiveClass), true, "Reactive Class");
        window.Show();
    }

    private Vector2 UIScrollow;
    public string ScriptName = "Reactive";
    public int DataCount=5;

    public List<ClassData> classDatas = new List<ClassData>();

    private void OnGUI()
    {
        UIScrollow = EditorGUILayout.BeginScrollView(UIScrollow, false, false);
        GUILayout.BeginVertical("HelpBox");

        GUILayout.BeginVertical("Box");
        ScriptName = EditorGUILayout.TextField("脚本名称:", ScriptName);
        GUILayout.EndVertical();

        GUILayout.BeginHorizontal("Box");
        DataCount = EditorGUILayout.IntSlider("数据量:", DataCount, 0, 20 );
        if (GUILayout.Button("创建"))
        {
            classDatas.Clear();
            for(int i = 0; i < DataCount; i++)
            {
                ClassData data = new ClassData();
                classDatas.Add(data);
            }
           
        }
        if (GUILayout.Button("新增"))
        {
            ClassData data = new ClassData();
            classDatas.Add(data);
        }
        GUILayout.EndHorizontal();

        for(int i = 0; i < classDatas.Count; i++)
        {
            GUILayout.BeginHorizontal("Box");
            classDatas[i].Type = (VariableType)EditorGUILayout.EnumPopup("类型:", classDatas[i].Type);
            classDatas[i].Name = EditorGUILayout.TextField("名称:", classDatas[i].Name);
            classDatas[i].Des = EditorGUILayout.TextField("描述:", classDatas[i].Des);
            GUILayout.EndHorizontal();
        }

        GUILayout.BeginVertical("Box");
        if (GUILayout.Button("Save")) { CreateClass(); }
        GUILayout.EndVertical();
        GUILayout.EndVertical();
        //滑条结束,所有包含在滑条内的UI在此之上
        EditorGUILayout.EndScrollView();
    }

    private void CreateClass()
    {
        string copyPath = "Assets/Scripts/Reactive/" + ScriptName + ".cs";
        if (File.Exists(copyPath)) { File.Delete(copyPath); }
        using (StreamWriter outfile =
                new StreamWriter(copyPath))
        {
            outfile.WriteLine("using UniRx;");
            outfile.WriteLine("using UnityEngine;");
            outfile.WriteLine("");
            outfile.WriteLine("public class " + ScriptName);
            outfile.WriteLine("{");
            for (int i = 0; i < classDatas.Count; i++)
            {
                outfile.WriteLine("    /// <summary>" );
                outfile.WriteLine("    ///"+classDatas[i].Des);
                outfile.WriteLine("    /// <summary>");
                outfile.WriteLine("    public " + GetMode(classDatas[i].Type) +" "+classDatas[i].Name+"{get;set;}");

            }
            outfile.WriteLine("}");
            outfile.WriteLine("public class " + ScriptName+ "Reactive:ISetData<"+ ScriptName+">");
            outfile.WriteLine("{");
            outfile.WriteLine("    /// <summary>");
            outfile.WriteLine("    ///Data");
            outfile.WriteLine("    /// <summary>");
            outfile.WriteLine("    private "+ScriptName+" Data{get;set;}= new "+ScriptName+"();");
            for (int i = 0; i < classDatas.Count; i++)
            {
                outfile.WriteLine("    /// <summary>");
                outfile.WriteLine("    ///" + classDatas[i].Des);
                outfile.WriteLine("    /// <summary>");
                outfile.WriteLine("    public ReactiveProperty<" + GetMode(classDatas[i].Type) + "> "  + classDatas[i].Name + "{get;set;}= new ReactiveProperty<" + GetMode(classDatas[i].Type) + ">();");

            }
            outfile.WriteLine("");
            outfile.WriteLine("    public " + ScriptName+ "Reactive()");
            outfile.WriteLine("    {");
            for(int i = 0; i < classDatas.Count; i++)
            {
                outfile.WriteLine("        "+classDatas[i].Name+ ".Subscribe(value => Data."+ classDatas[i].Name+ "= value);");
            }
            outfile.WriteLine("    }");
            outfile.WriteLine("");
            outfile.WriteLine("    public void SetData("+ScriptName+" data)");
            outfile.WriteLine("    {");
            outfile.WriteLine("        Data = data;");
            for (int i = 0; i < classDatas.Count; i++)
            {
                outfile.WriteLine("        " + classDatas[i].Name +".Value = data."+classDatas[i].Name+";");
            }
            outfile.WriteLine("    }");
            outfile.WriteLine("");
            outfile.WriteLine("    public "+ScriptName+" GetData()");
            outfile.WriteLine("    {");
            outfile.WriteLine("        return Data;");
            outfile.WriteLine("    }");


            outfile.WriteLine("}");
        }//File written
        AssetDatabase.Refresh();
    }

    public string GetMode(VariableType type)
    {
        string str = "";
        switch (type)
        {
            case VariableType.String:
                str = "string";
                break;
            case VariableType.Bool:
                str = "bool";
                break;
            case VariableType.Float:
                str = "float";
                break;
            case VariableType.Int:
                str = "int";
                break;
            case VariableType.Vector2:
                str = "Vector2";
                break;
            case VariableType.Vector3:
                str = "Vector3";
                break;
            case VariableType.ImageType:
                str = "OriginalImageType";
                break;
            case VariableType.Direction:
                str = "DirectionMode";
                break;
        }
        return str;

    }

}