using UnityEngine;
using UnityEditor;
using System.Collections.Generic;
#if UNITY_EDITOR
using UnityEditor.SceneManagement;

public class ObjectRename : EditorWindow
{
    public string m_replaceA; // can be empty to consider replacing the whole range with B
    public string m_replaceB; // can include # character for counter. Can be empty to remove the range.
    public bool m_useRange = false;
    public int m_rangeStart = 0; // start of replacing range in A. Accepts negative value to count from the end.
    public int m_rangeLength = -1; // length of replacing range in A in characters. Accepts negative value to consider the rest of the string. Accepts 0 to insert B at start pos.
    public int m_counter = 1; // start of counter
    public string m_counterFormat; // 00 for 2 digit format
    public bool m_renameParentPrefabs = false;

    // Add menu named "My Window" to the Window menu
    [MenuItem("Tools/GF/Object Rename")]
    static void Init()
    {
        // Get existing open window or if none, make a new one:
        ObjectRename window = (ObjectRename)EditorWindow.GetWindow(typeof(ObjectRename));
        window.Show();
    }

    void OnGUI()
    {
        m_replaceA = EditorGUILayout.TextField("Replace A", m_replaceA);
        m_replaceB = EditorGUILayout.TextField("With B", m_replaceB);
        m_useRange = EditorGUILayout.ToggleLeft("Use range", m_useRange);
        m_rangeStart = EditorGUILayout.IntField("Range start", m_rangeStart);
        m_rangeLength = EditorGUILayout.IntField("Range length", m_rangeLength);
        m_counter = EditorGUILayout.IntField("Counter #", m_counter);
        m_counterFormat = EditorGUILayout.TextField("Counter format", m_counterFormat);
        m_renameParentPrefabs = EditorGUILayout.ToggleLeft("Rename parent prefabs", m_renameParentPrefabs);

        if (m_replaceA == null)
            m_replaceA = "";
        if (m_replaceB == null)
            m_replaceB = "";
        if (m_counterFormat == null)
            m_counterFormat = "";

        if (GUILayout.Button("Replace A with B in names"))
        {
            Undo.RegisterCompleteObjectUndo(Selection.gameObjects, "rename");

            int counter = m_counter;

            // reorder objects list by sibling index, as seen in the hierarchy
            GameObject[] objects = Selection.gameObjects;
            System.Array.Sort(objects, new UnitySiblingsSort());

            foreach (GameObject go in objects)
            {
                int s = 0;
                int l = go.name.Length;
                if (m_useRange)
                {
                    if (m_rangeStart < 0)
                        s = go.name.Length + m_rangeStart;
                    else
                        s = m_rangeStart;
                    if (s < 0)
                        s = 0;

                    if (m_rangeLength < 0)
                        l = go.name.Length - s;
                    else
                        l = m_rangeLength;
                    if (l > go.name.Length - s)
                        l = go.name.Length - s;
                }

                string n = go.name.Substring(s, l);

                string b = m_replaceB;

                if (b.Contains("#"))
                    b = b.Replace("#", counter.ToString(m_counterFormat));

                if (l == 0)
                {
                    n = b;
                }
                else
                {
                    if (m_replaceA == "")
                    {
                        n = b;
                    }
                    else
                    {
                        n = n.Replace(m_replaceA, b);
                    }
                }

                string newName = go.name.Substring(0, s) + n + go.name.Substring(s+l);
                Debug.Log("Rename " + go.name + " to " + newName);
                go.name = newName;

                bool isAsset = AssetDatabase.Contains(go);
                bool isInstance = PrefabUtility.GetPrefabType(go) == PrefabType.PrefabInstance || PrefabUtility.GetPrefabType(go) == PrefabType.ModelPrefabInstance;
                bool doTheParentPrefab = m_renameParentPrefabs && isInstance;
                if (isAsset || doTheParentPrefab)
                {
                    string assetPath = "";
                    if (isAsset)
                    {
                        assetPath = AssetDatabase.GetAssetPath(go);
                    }
                    else if (doTheParentPrefab)
                    {
                        Object parentPrefab = PrefabUtility.GetCorrespondingObjectFromSource(go);
                        if (parentPrefab)
                            assetPath = AssetDatabase.GetAssetPath(parentPrefab);
                    }
                    if (assetPath != "")
                    {
                        string ret = AssetDatabase.RenameAsset(assetPath, newName);
                        if (ret != "")
                            Debug.Log("  ERROR: " + ret);
                    }
                }

                counter++;
            }

            EditorSceneManager.MarkAllScenesDirty();
        }
    }
}
#endif