using UnityEngine;
using UnityEditor;
using System.IO;

public class FileCreator
{
    //Asset create folder paths
    const string ASSET_CREATE_PATH = "Assets/Create/CustomFile/";
    const string CREATE_TEMPLATE_FOLDER_PATH = ASSET_CREATE_PATH + "Template/";
    const string CREATE_FILE_FOLDER_PATH = ASSET_CREATE_PATH + "File/";
    const string CREATE_FILE_MONO_FOLDER_PATH = CREATE_FILE_FOLDER_PATH + "MonoBehaviour/";
    const string CREATE_FILE_PROPATTR_FOLDER_PATH = CREATE_FILE_FOLDER_PATH + "Property Attribute/";
    const string CREATE_FILE_OTHER_FOLDER_PATH = CREATE_FILE_FOLDER_PATH + "Other/";

    public static string templateFolderPathAssets = "_FeariDev/CustomFileCreator/FileTemplates";
    public static readonly string templateFolderPath = Path.Combine(Application.dataPath, templateFolderPathAssets);

    [MenuItem(ASSET_CREATE_PATH, priority = -201)]
    public static void Folder()
    {

    }

    #region Template File

    [MenuItem(CREATE_TEMPLATE_FOLDER_PATH + "Empty file template", secondaryPriority = 0)]
    public static void CreateEmptyTemplateFile()
    {
        string fileName = "NewEmptyFileTemplate.txt";
        CreateNewTemplateFileBase(fileName);
    }

    #endregion



    #region Asset File

    //File/Mono
    [MenuItem(ASSET_CREATE_PATH + "Empty Monobehaviour c# file", secondaryPriority = -100)]
    [MenuItem(CREATE_FILE_MONO_FOLDER_PATH + "Empty Monobehaviour c# file", secondaryPriority = 120)]
    public static void CreateEmptyMonoCsFile()
    {
        string fileName = "NewEmptyMonoCsFile.cs";
        string template = "EmptyMonoCsFileTemplate.txt";
        CreateNewAssetFileBase(fileName, template);
    }

    //File/Property Attribute
    [MenuItem(CREATE_FILE_PROPATTR_FOLDER_PATH + "Empty PropertyAttribute file", secondaryPriority = 150)]
    public static void CreateEmptyPropAttrFile()
    {
        string fileName = "NewEmptyPropAttrFile.cs";
        string template = "EmptyPropAttrFileTemplate.txt";
        CreateNewAssetFileBase(fileName, template);
    }

    //File/Other
    [MenuItem(ASSET_CREATE_PATH + "Empty c# file", secondaryPriority = -99)]
    [MenuItem(CREATE_FILE_OTHER_FOLDER_PATH + "Empty c# file", secondaryPriority = 200)]
    public static void CreateEmptyCsFile()
    {
        string fileName = "NewEmptyCsFile.cs";
        string template = "EmptyCsFileTemplate.txt";
        CreateNewAssetFileBase(fileName, template);
    }

    #endregion



    static void CreateNewTemplateFileBase(string fileName)
    {
        string path = GetUniquePath(fileName);

        ProjectWindowUtil.StartNameEditingIfProjectWindowExists(
            0, ScriptableObject.CreateInstance<EndNameEditActionTemplate>(), path, EditorGUIUtility.IconContent("TextAsset Icon").image as Texture2D, null
        );
    }
    static void CreateNewAssetFileBase(string fileName, string templateName)
    {
        string templatePath = Path.Combine(templateFolderPath, templateName);
        string path = GetUniquePath(fileName);

        ProjectWindowUtil.StartNameEditingIfProjectWindowExists(
            0, ScriptableObject.CreateInstance<EndNameEditActionNonTemplate>(), path, EditorGUIUtility.IconContent("cs Script Icon").image as Texture2D, templatePath
        );
    }



    static string GetPath(string fileName)
    {
        string path = "Assets";

        foreach (var obj in Selection.GetFiltered(typeof(Object), SelectionMode.Assets))
        {
            path = AssetDatabase.GetAssetPath(obj);

            if (!string.IsNullOrEmpty(path) && File.Exists(path))
            {
                path = Path.GetDirectoryName(path);
            }

            break;
        }

        path = Path.Combine(path, fileName);

        return path;
    }
    static string GetUniquePath(string fileName)
    {
        return AssetDatabase.GenerateUniqueAssetPath(GetPath(fileName));
    }
}

class EndNameEditActionTemplate : UnityEditor.ProjectWindowCallback.EndNameEditAction 
{
    public override void Action(int instanceId, string pathName, string resourceFile)
    {
        File.WriteAllText(pathName, "");

        AssetDatabase.ImportAsset(pathName);
        Object obj = AssetDatabase.LoadAssetAtPath<Object>(pathName);
        ProjectWindowUtil.ShowCreatedAsset(obj);
    }
}

class EndNameEditActionNonTemplate : UnityEditor.ProjectWindowCallback.EndNameEditAction
{
    public override void Action(int instanceId, string pathName, string resourceFile)
    {
        string contents = File.ReadAllText(resourceFile);
        string className = Path.GetFileNameWithoutExtension(pathName);
        contents = contents.Replace("#CLASSNAME#", className);
        File.WriteAllText(pathName, contents);

        AssetDatabase.ImportAsset(pathName);
        Object obj = AssetDatabase.LoadAssetAtPath<Object>(pathName);
        ProjectWindowUtil.ShowCreatedAsset(obj);
    }
}
