private void DrawNewPrefab(ObjectPool.CategoryData categoryData, CategoryEditData editData)
    {
        //Add new prefab
        EditorGUILayout.BeginHorizontal();
        {
            EditorGUILayout.LabelField("New", GUILayout.Width(50));
            editData.newPrefab = EditorGUILayout.ObjectField(editData.newPrefab, typeof(GameObject), false) as GameObject;

            string newSizeControlName = "newSize" + categoryData.category;
            GUI.SetNextControlName(newSizeControlName);
            editData.newSize = EditorGUILayout.IntField(editData.newSize, GUILayout.Width(50));

            SetGUIColor(Color.green);
            string addButtonControlName = "addButton" + categoryData.category;
            GUI.SetNextControlName(addButtonControlName);
            if (GUILayout.Button("Add", GUILayout.Width(40)) || IsReturnPressedOn(newSizeControlName))
            {
                if (editData.newPrefab != null && editData.newSize > 0)
                {
                    if (IsSamePrefabExists(editData.newPrefab))
                    {
                        editData.newPrefab = null;
                        EditorUtility.DisplayDialog("Warning!", "이미 등록된 Prefab입니다.", "Ok");
                        ResetFocus();

                        EditorUtility.SetDirty(target);
                    }
                    else
                    {
                        categoryData.dataList.Add(new ObjectPool.StartupPool()
                        {
                            prefab = editData.newPrefab, size = editData.newSize
                        });
                        editData.newPrefab = null;
                        editData.newSize   = 0;
                    }
                }
                else
                {
                    string msg = editData.newPrefab == null ? "Prefab이 없습니다!\n" : "";
                    msg += editData.newSize <= 0 ? "Size에 0보다 큰 수를 입력해주세요!" : "";
                    EditorUtility.DisplayDialog("Warning!", msg, "Ok");
                    ResetFocus();
                }
            }
            UnsetGUIColor();
        }
        EditorGUILayout.EndHorizontal();

        EditorGUILayout.Space();

        Rect rect = GUILayoutUtility.GetLastRect();

        EditorGUI.DrawRect(new Rect(rect.x, rect.y + rect.height, rect.width, 1), Color.grey);

        EditorGUILayout.Space();
    }
    private bool SwapCategoryData(List <ObjectPool.CategoryData> list, int firstIndex, int secondIndex)
    {
        if (firstIndex < 0 || firstIndex >= list.Count ||
            secondIndex < 0 || secondIndex >= list.Count)
        {
            return(false);
        }

        ObjectPool.CategoryData firstData  = list[firstIndex];
        ObjectPool.CategoryData secondData = list[secondIndex];
        list[firstIndex]  = secondData;
        list[secondIndex] = firstData;

        return(true);
    }
    private void AddNewCategory(string newCategoryName)
    {
        if (objectPool.startupPools.Find((category) => category.category.Equals(newCategoryName)) == null)
        {
            ObjectPool.CategoryData data = new ObjectPool.CategoryData();
            data.category = newCategoryName;
            data.dataList = new List <ObjectPool.StartupPool>();

            objectPool.startupPools.Add(data);
            editDataDict.Add(data, new CategoryEditData {
                isVisible = true, isEditingCategory = false
            });

            EditorApplication.MarkSceneDirty();
        }
    }
    private void DrawCategoryDataList(ObjectPool.CategoryData categoryData, CategoryEditData editData)
    {
        //draw items
        for (int i = 0; i < categoryData.dataList.Count; i++)
        {
            ObjectPool.StartupPool data = categoryData.dataList[i];

            //Contents
            EditorGUILayout.BeginHorizontal();
            {
                data.prefab = EditorGUILayout.ObjectField(data.prefab, typeof(GameObject), false) as GameObject;
                data.size   = EditorGUILayout.IntField(data.size, GUILayout.Width(50));

                if (GUILayout.Button("X", GUILayout.Width(30)))
                {
                    categoryData.dataList.RemoveAt(i);
                    i--;
                }
            }
            EditorGUILayout.EndHorizontal();
        }
    }
    public override void OnInspectorGUI()
    {
        serializedObject.Update();

        DrawTopMenu();

        DrawFocusOutObject();

        DrawNewCategory();

        for (int i = 0; i < objectPool.startupPools.Count; i++)
        {
            ObjectPool.CategoryData categoryData = objectPool.startupPools[i];
            CategoryEditData        editData     = editDataDict[categoryData];

            string textFieldControlName = CONTROL_NAME_EDIT_CATEGORY_TEXTFIELD + i;

            EditorGUILayout.BeginHorizontal();
            {
                if (GUILayout.Button(editData.isVisible ? "-" : "+", GUILayout.Width(20)))
                {
                    editData.isVisible = !editData.isVisible;
                }

                if (editData.isEditingCategory)
                {
                    GUI.SetNextControlName(textFieldControlName);
                    editData.editingCategoryName = EditorGUILayout.TextField(editData.editingCategoryName);
                }
                else
                {
                    EditorGUILayout.LabelField(categoryData.category + " (" + categoryData.dataList.Count + ")", EditorStyles.boldLabel);
                }
            }
            EditorGUILayout.EndHorizontal();


            EditorGUILayout.BeginHorizontal();
            {
                if (editData.isEditingCategory)
                {
                    if (GUILayout.Button("Save") || IsReturnPressedOn(textFieldControlName))
                    {
                        if (categoryData.category.ToLower().Equals(editData.editingCategoryName.ToLower()))
                        {
                        }
                        else if (CheckValidCategoryName(editData.editingCategoryName))
                        {
                            categoryData.category = editData.editingCategoryName;
                        }
                        else
                        {
                            editData.editingCategoryName = categoryData.category;
                        }

                        editData.isEditingCategory = false;

                        ResetFocus();
                        EditorUtility.SetDirty(target);
                        EditorApplication.MarkSceneDirty();
                    }
                }
                else
                {
                    if (GUILayout.Button("Edit"))
                    {
                        editData.editingCategoryName = categoryData.category;
                        editData.isEditingCategory   = true;

                        EditorGUI.FocusTextInControl(textFieldControlName);
                        EditorUtility.SetDirty(target);
                    }
                }

                if (GUILayout.Button("Sort"))
                {
                    categoryData.dataList.Sort((first, second) => { return(first.prefab.name.CompareTo(second.prefab.name)); });
                    EditorApplication.MarkSceneDirty();
                }

                SetGUIColor(Color.red);
                if (GUILayout.Button("Delete"))
                {
                    if (EditorUtility.DisplayDialog("Warning!", "카테고리에 포함되어 있는 프리팹 리스트도 사라집니다. 정말 삭제하시겠습니까?", "Yes", "No"))
                    {
                        objectPool.startupPools.RemoveAt(i);
                        i--;
                        editDataDict.Remove(categoryData);

                        EditorApplication.MarkSceneDirty();
                    }
                }
                UnsetGUIColor();

                if (GUILayout.Button("▲", GUILayout.Width(30)))
                {
                    if (SwapCategoryData(objectPool.startupPools, i - 1, i))
                    {
                        EditorApplication.MarkSceneDirty();
                    }
                }

                if (GUILayout.Button("▼", GUILayout.Width(30)))
                {
                    if (SwapCategoryData(objectPool.startupPools, i + 1, i))
                    {
                        EditorApplication.MarkSceneDirty();
                    }
                }
            }
            EditorGUILayout.EndHorizontal();


            EditorGUILayout.Space();

            if (editData.isVisible)
            {
                EditorGUI.indentLevel += 1;
                {
                    DrawCategoryDataList(categoryData, editData);
                    DrawNewPrefab(categoryData, editData);
                }
                EditorGUI.indentLevel -= 1;
            }
        }

        serializedObject.ApplyModifiedProperties();
    }