﻿using UnityEngine;
using UnityEditor;
using System;

namespace BattleRoyale
{
    [Serializable]
    public class PrefabManagerWindow : SearchableEditorWindow
    {
        public string toggleText = "", leftRightText = "", upDownText = "", leftRightSpecial = "", upDownSpecial = "";
        public int toggleInt = 0;
        public Vector2 scrollPosition = Vector2.zero;
        public Color buttonColor = Color.green, buttonColor2 = Color.cyan, buttonColor3 = Color.yellow, buttonColor4 = Color.red, buttonColor5 = Color.gray, buttonColor6 = Color.magenta;
        public Color lrColor, udColor;
        public UnityEngine.Object guiSkinHolder;
        public int menuTab = 0, trackStyleTab = 0;
        public int environmentSelect = -1;

        public float straightSlider = 1f;

        public string settingsLockCode = "";

        public Color defaultColor;
        public GUIStyle buttonStyle, lableStyle, gridStyle;
        public GUISkin defaultSkin, customSkin;

        public static GameObject[] propObs;
        public static string[] propNames;
        public static Texture2D[] propTextures;
        public static bool[] propsInitialized;

        public static GameObject[] rockObs;
        public static string[] rockNames;
        public static Texture2D[] rockTextures;
        public static bool[] rocksInitialized;

        public static GameObject[] vegObs;
        public static string[] vegNames;
        public static Texture2D[] vegTextures;
        public static bool[] vegsInitialized;

        public static GameObject[] landObs;
        public static string[] landNames;
        public static Texture2D[] landTextures;
        public static bool[] landsInitialized;

        public static GameObject[] buildObs;
        public static string[] buildNames;
        public static Texture2D[] buildTextures;
        public static bool[] buildsInitialized;

        public static GameObject[] bridgeObs;
        public static string[] bridgeNames;
        public static Texture2D[] bridgeTextures;
        public static bool[] bridgesInitialized;

        public static GameObject[] boardObs;
        public static string[] boardNames;
        public static Texture2D[] boardTextures;
        public static bool[] boardsInitialized;

        public static GameObject[] tinkerObs;
        public static string[] tinkerNames;
        public static Texture2D[] tinkerTextures;
        public static bool[] tinkersInitialized;

        public static GameObject[] wandObs;
        public static string[] wandNames;
        public static Texture2D[] wandTextures;
        public static bool[] wandsInitialized;

        public static GameObject[] customWandObs;
        public static string[] customWandNames;
        public static Texture2D[] customWandTextures;
        public static bool[] customWandsInitialized;

        public static GameObject[] specObs;
        public static string[] specNames;
        public static Texture2D[] specTextures;
        public static bool[] specsInitialized;

        [MenuItem("Battle Royale/Prefab Manager Window", false, 26)]
        public static void DisplayWindow()
        {
            AssetPreview.SetPreviewTextureCacheSize(1000);

            // LOAD ASSETS //
            #region
            InitializeObjectData();
            #endregion
        }

        private void OnFocus()
        {
            InitializeObjectData();    
        }

        private static void InitializeObjectData(string _folder = "")
        {
            if (_folder == "Props" || _folder == "")
            {
                propObs = Resources.LoadAll<GameObject>("Props");
                propNames = new string[propObs.Length];
                propTextures = new Texture2D[propObs.Length];
                propsInitialized = new bool[propObs.Length];

                for (int i = 0; i < propObs.Length; i++)
                {
                    propNames[i] = propObs[i].name;
                    propsInitialized[i] = false;
                }

                for (int i = 0; i < propTextures.Length; i++)
                {
                    Texture2D _newTexture = GetPreviewAtPath("Props/" + propNames[i]);
                    propTextures[i] = _newTexture;
                    propsInitialized[i] = true;
                }
            }


            if (_folder == "Rocks" || _folder == "")
            {
                rockObs = Resources.LoadAll<GameObject>("Rocks");
                rockNames = new string[rockObs.Length];
                rockTextures = new Texture2D[rockObs.Length];
                rocksInitialized = new bool[rockObs.Length];
                for (int i = 0; i < rockObs.Length; i++)
                {
                    rockNames[i] = rockObs[i].name;
                    rocksInitialized[i] = false;
                }

                for (int i = 0; i < rockTextures.Length; i++)
                {
                    Texture2D _newTexture = GetPreviewAtPath("Rocks/" + rockNames[i]);
                    rockTextures[i] = _newTexture;
                    rocksInitialized[i] = true;
                }
            }

            if (_folder == "Vegetation" || _folder == "")
            {
                vegObs = Resources.LoadAll<GameObject>("Vegetation");
                vegNames = new string[vegObs.Length];
                vegTextures = new Texture2D[vegObs.Length];
                vegsInitialized = new bool[vegObs.Length];
                for (int i = 0; i < vegObs.Length; i++)
                {
                    vegNames[i] = vegObs[i].name;
                    vegsInitialized[i] = false;
                }

                for (int i = 0; i < vegTextures.Length; i++)
                {
                    Texture2D _newTexture = GetPreviewAtPath("Vegetation/" + vegNames[i]);
                    vegTextures[i] = _newTexture;
                    vegsInitialized[i] = true;
                }
            }

            if (_folder == "Land Pieces" || _folder == "")
            {
                landObs = Resources.LoadAll<GameObject>("Land Pieces");
                landNames = new string[landObs.Length];
                landTextures = new Texture2D[landObs.Length];
                landsInitialized = new bool[landObs.Length];
                for (int i = 0; i < landObs.Length; i++)
                {
                    landNames[i] = landObs[i].name;
                    landsInitialized[i] = false;
                }

                for (int i = 0; i < landTextures.Length; i++)
                {
                    Texture2D _newTexture = GetPreviewAtPath("Land Pieces/" + landNames[i]);
                    landTextures[i] = _newTexture;
                    landsInitialized[i] = true;
                }
            }

            if (_folder == "Buildings & Ruins" || _folder == "")
            {
                buildObs = Resources.LoadAll<GameObject>("Buildings & Ruins");
                buildNames = new string[buildObs.Length];
                buildTextures = new Texture2D[buildObs.Length];
                buildsInitialized = new bool[buildObs.Length];
                for (int i = 0; i < buildObs.Length; i++)
                {
                    buildNames[i] = buildObs[i].name;
                    buildsInitialized[i] = false;
                }

                for (int i = 0; i < buildTextures.Length; i++)
                {
                    Texture2D _newTexture = GetPreviewAtPath("Buildings & Ruins/" + buildNames[i]);
                    buildTextures[i] = _newTexture;
                    buildsInitialized[i] = true;
                }
            }

            if (_folder == "Bridges" || _folder == "")
            {
                bridgeObs = Resources.LoadAll<GameObject>("Bridges");
                bridgeNames = new string[bridgeObs.Length];
                bridgeTextures = new Texture2D[bridgeObs.Length];
                bridgesInitialized = new bool[bridgeObs.Length];
                for (int i = 0; i < bridgeObs.Length; i++)
                {
                    bridgeNames[i] = bridgeObs[i].name;
                    bridgesInitialized[i] = false;
                }

                for (int i = 0; i < bridgeTextures.Length; i++)
                {
                    Texture2D _newTexture = GetPreviewAtPath("Bridges/" + bridgeNames[i]);
                    bridgeTextures[i] = _newTexture;
                    bridgesInitialized[i] = true;
                }
            }

            if (_folder == "Boardgame Parts" || _folder == "")
            {
                boardObs = Resources.LoadAll<GameObject>("Boardgame Parts");
                boardNames = new string[boardObs.Length];
                boardTextures = new Texture2D[boardObs.Length];
                boardsInitialized = new bool[boardObs.Length];
                for (int i = 0; i < boardObs.Length; i++)
                {
                    boardNames[i] = boardObs[i].name;
                    boardsInitialized[i] = false;
                }

                for (int i = 0; i < boardTextures.Length; i++)
                {
                    Texture2D _newTexture = GetPreviewAtPath("Boardgame Parts/" + boardNames[i]);
                    boardTextures[i] = _newTexture;
                    boardsInitialized[i] = true;
                }
            }

            if (_folder == "Tinkercad" || _folder == "")
            {
                tinkerObs = Resources.LoadAll<GameObject>("Tinkercad");
                tinkerNames = new string[tinkerObs.Length];
                tinkerTextures = new Texture2D[tinkerObs.Length];
                tinkersInitialized = new bool[tinkerObs.Length];
                for (int i = 0; i < tinkerObs.Length; i++)
                {
                    tinkerNames[i] = tinkerObs[i].name;
                    tinkersInitialized[i] = false;
                }

                for (int i = 0; i < tinkerTextures.Length; i++)
                {
                    Texture2D _newTexture = GetPreviewAtPath("Tinkercad/" + tinkerNames[i]);
                    tinkerTextures[i] = _newTexture;
                    tinkersInitialized[i] = true;
                }
            }

            if (_folder == "Wands" || _folder == "")
            {
                wandObs = Resources.LoadAll<GameObject>("Wands");
                wandNames = new string[wandObs.Length];
                wandTextures = new Texture2D[wandObs.Length];
                wandsInitialized = new bool[wandObs.Length];
                for (int i = 0; i < wandObs.Length; i++)
                {
                    wandNames[i] = wandObs[i].name;
                    wandsInitialized[i] = false;
                }

                for (int i = 0; i < wandTextures.Length; i++)
                {
                    Texture2D _newTexture = GetPreviewAtPath("Wands/" + wandNames[i]);
                    wandTextures[i] = _newTexture;
                    wandsInitialized[i] = true;
                }
            }

            if (_folder == "Custom Wands" || _folder == "")
            {
                customWandObs = Resources.LoadAll<GameObject>("Custom Wands");
                customWandNames = new string[customWandObs.Length];
                customWandTextures = new Texture2D[customWandObs.Length];
                customWandsInitialized = new bool[customWandObs.Length];
                for (int i = 0; i < customWandObs.Length; i++)
                {
                    customWandNames[i] = customWandObs[i].name;
                    customWandsInitialized[i] = false;
                }

                for (int i = 0; i < customWandTextures.Length; i++)
                {
                    Texture2D _newTexture = GetPreviewAtPath("Custom Wands/" + customWandNames[i]);
                    customWandTextures[i] = _newTexture;
                    customWandsInitialized[i] = true;
                }
            }

            if (_folder == "Special" || _folder == "")
            {
                specObs = Resources.LoadAll<GameObject>("Special");
                specNames = new string[specObs.Length];
                specTextures = new Texture2D[specObs.Length];
                specsInitialized = new bool[specObs.Length];
                for (int i = 0; i < specObs.Length; i++)
                {
                    specNames[i] = specObs[i].name;
                    specsInitialized[i] = false;
                }

                for (int i = 0; i < specTextures.Length; i++)
                {
                    Texture2D _newTexture = GetPreviewAtPath("Special/" + specNames[i]);
                    specTextures[i] = _newTexture;
                    specsInitialized[i] = true;
                }
            }

            PrefabManagerWindow window = GetWindow<PrefabManagerWindow>("Prefab Manager");

            window.minSize = new Vector2(482f, 180f);
            if (!window.guiSkinHolder)
            {
                window.guiSkinHolder = Resources.Load<GUISkin>("Button Images/CustomSkin");
            }
        }

        private static Texture2D GetPreviewAtPath(string _path)
        {
            Texture2D _newTexture;
            var editor = Editor.CreateEditor(Resources.Load<GameObject>(_path));
            _newTexture = editor.RenderStaticPreview(_path, null, 100, 100);
            EditorWindow.DestroyImmediate(editor);
            return _newTexture;
        }

        // Update is called once per frame
        void OnGUI()
        {
            if (!guiSkinHolder)
            {
                guiSkinHolder = Resources.Load<GUISkin>("Button Images/CustomSkin");

                GUIUtility.ExitGUI();
            }

            if (guiSkinHolder)
            {
                customSkin = (GUISkin)guiSkinHolder;
                buttonStyle = new GUIStyle(customSkin.button);
                lableStyle = new GUIStyle(customSkin.label);
                gridStyle = new GUIStyle();
                gridStyle.wordWrap = true;
            }

            defaultSkin = GUI.skin;
            defaultColor = GUI.backgroundColor;

            GUILayout.BeginArea(new Rect(0, 0, position.width, position.height));

            float _tileSize = 100;
            int _columns = 0;
            float _width = position.width * 0.8f;

            while (_width > 0)
            {
                _columns++;
                _width -= _tileSize;
            }

            scrollPosition = GUILayout.BeginScrollView(scrollPosition, GUILayout.Width(position.width), GUILayout.Height(position.height));
            #region

            GUILayout.BeginVertical();

            GUILayout.BeginHorizontal();
            GUILayout.FlexibleSpace();
            GUILayout.BeginVertical();
            GUILayout.BeginHorizontal();
            GUILayout.FlexibleSpace();
            GUILayout.Label("Click on an Object to place it in the Scene", EditorStyles.boldLabel);
            GUILayout.FlexibleSpace();
            GUILayout.EndHorizontal();
            GUILayout.BeginHorizontal();
            GUILayout.FlexibleSpace();
            GUILayout.Label("See blank squares? Click another editor window, then this one!", EditorStyles.miniLabel);
            GUILayout.FlexibleSpace();
            GUILayout.EndHorizontal();
            GUILayout.EndVertical();
            GUILayout.FlexibleSpace();
            GUILayout.EndHorizontal();

            // PROPS //
            #region

            if (customWandObs == null)
                InitializeObjectData("Props");
            
            int _itemCount = propObs.Length;
            int _rows = 0;
            while (_itemCount > 0)
            {
                _itemCount -= _columns;
                _rows++;
            }

            //if (propObs == null)
            //{
            //    propObs = Resources.LoadAll<GameObject>("Props");
            //    propNames = new string[propObs.Length];
            //    propTextures = new Texture2D[propObs.Length];
            //    propsInitialized = new bool[propObs.Length];
            //    for (int i = 0; i < propObs.Length; i++)
            //    {
            //        propNames[i] = propObs[i].name;
            //        propsInitialized[i] = false;
            //    }
            //}

            //while (_itemCount > 0)
            //{
            //    _itemCount -= _columns;
            //    _rows++;
            //}

            GUILayout.BeginVertical("HelpBox", GUILayout.Height(_rows * _tileSize));

            GUILayout.BeginHorizontal();
            GUILayout.FlexibleSpace();
            GUILayout.Label("Props", EditorStyles.boldLabel);
            GUILayout.FlexibleSpace();
            GUILayout.EndHorizontal();

            GUILayout.BeginHorizontal(gridStyle);
            GUILayout.FlexibleSpace();

            CreatePrefabGrid(_tileSize, _columns, _rows, "Props", propNames, ref propTextures, ref propsInitialized);

            GUILayout.FlexibleSpace();
            GUILayout.EndHorizontal();

            GUILayout.BeginHorizontal();
            GUILayout.Label("");
            GUILayout.EndHorizontal();

            GUILayout.EndVertical();
            #endregion

            // ROCKS //
            #region
            if (rockObs == null)
                InitializeObjectData("Rocks");

            _itemCount = rockObs.Length;
            _rows = 0;
            while (_itemCount > 0)
            {
                _itemCount -= _columns;
                _rows++;
            }

            GUILayout.BeginVertical("HelpBox", GUILayout.Height(_rows * _tileSize));

            GUILayout.BeginHorizontal();
            GUILayout.FlexibleSpace();
            GUILayout.Label("Rocks", EditorStyles.boldLabel);
            GUILayout.FlexibleSpace();
            GUILayout.EndHorizontal();

            GUILayout.BeginHorizontal(gridStyle);
            GUILayout.FlexibleSpace();

            CreatePrefabGrid(_tileSize, _columns, _rows, "Rocks", rockNames, ref rockTextures, ref rocksInitialized);

            GUILayout.FlexibleSpace();
            GUILayout.EndHorizontal();

            GUILayout.BeginHorizontal();
            GUILayout.Label("");
            GUILayout.EndHorizontal();

            GUILayout.EndVertical();
            #endregion

            // VEGETATION //
            #region
            if (vegObs == null)
                InitializeObjectData("Vegetation");

            _itemCount = vegObs.Length;
            _rows = 0;
            while (_itemCount > 0)
            {
                _itemCount -= _columns;
                _rows++;
            }

            GUILayout.BeginVertical("HelpBox", GUILayout.Height(_rows * _tileSize));

            GUILayout.BeginHorizontal();
            GUILayout.FlexibleSpace();
            GUILayout.Label("Vegetation", EditorStyles.boldLabel);
            GUILayout.FlexibleSpace();
            GUILayout.EndHorizontal();

            GUILayout.BeginHorizontal(gridStyle);
            GUILayout.FlexibleSpace();

            CreatePrefabGrid(_tileSize, _columns, _rows, "Vegetation", vegNames, ref vegTextures, ref vegsInitialized);

            GUILayout.FlexibleSpace();
            GUILayout.EndHorizontal();

            GUILayout.BeginHorizontal();
            GUILayout.Label("");
            GUILayout.EndHorizontal();

            GUILayout.EndVertical();
            #endregion

            // LAND PIECES //
            #region
            if (landObs == null)
                InitializeObjectData("Land Pieces");

            _itemCount = landObs.Length;
            _rows = 0;
            while (_itemCount > 0)
            {
                _itemCount -= _columns;
                _rows++;
            }

            GUILayout.BeginVertical("HelpBox", GUILayout.Height(_rows * _tileSize));

            GUILayout.BeginHorizontal();
            GUILayout.FlexibleSpace();
            GUILayout.Label("Land Pieces", EditorStyles.boldLabel);
            GUILayout.FlexibleSpace();
            GUILayout.EndHorizontal();

            GUILayout.BeginHorizontal(gridStyle);
            GUILayout.FlexibleSpace();

            CreatePrefabGrid(_tileSize, _columns, _rows, "Land Pieces", landNames, ref landTextures, ref landsInitialized);

            GUILayout.FlexibleSpace();
            GUILayout.EndHorizontal();

            GUILayout.BeginHorizontal();
            GUILayout.Label("");
            GUILayout.EndHorizontal();

            GUILayout.EndVertical();
            #endregion

            // BUILDINGS & RUINS //
            #region
            if (buildObs == null)
                InitializeObjectData("Buildings & Ruins");

            _itemCount = buildObs.Length;
            _rows = 0;
            while (_itemCount > 0)
            {
                _itemCount -= _columns;
                _rows++;
            }

            GUILayout.BeginVertical("HelpBox", GUILayout.Height(_rows * _tileSize));

            GUILayout.BeginHorizontal();
            GUILayout.FlexibleSpace();
            GUILayout.Label("Buildings & Ruins", EditorStyles.boldLabel);
            GUILayout.FlexibleSpace();
            GUILayout.EndHorizontal();

            GUILayout.BeginHorizontal(gridStyle);
            GUILayout.FlexibleSpace();

            CreatePrefabGrid(_tileSize, _columns, _rows, "Buildings & Ruins", buildNames, ref buildTextures, ref buildsInitialized);

            GUILayout.FlexibleSpace();
            GUILayout.EndHorizontal();

            GUILayout.BeginHorizontal();
            GUILayout.Label("");
            GUILayout.EndHorizontal();

            GUILayout.EndVertical();
            #endregion

            // BRIDGES //
            #region
            if (bridgeObs == null)
                InitializeObjectData("Bridges");

            _itemCount = bridgeObs.Length;
            _rows = 0;
            while (_itemCount > 0)
            {
                _itemCount -= _columns;
                _rows++;
            }

            GUILayout.BeginVertical("HelpBox", GUILayout.Height(_rows * _tileSize));

            GUILayout.BeginHorizontal();
            GUILayout.FlexibleSpace();
            GUILayout.Label("Bridges", EditorStyles.boldLabel);
            GUILayout.FlexibleSpace();
            GUILayout.EndHorizontal();

            GUILayout.BeginHorizontal(gridStyle);
            GUILayout.FlexibleSpace();

            CreatePrefabGrid(_tileSize, _columns, _rows, "Bridges", bridgeNames, ref bridgeTextures, ref bridgesInitialized);

            GUILayout.FlexibleSpace();
            GUILayout.EndHorizontal();

            GUILayout.BeginHorizontal();
            GUILayout.Label("");
            GUILayout.EndHorizontal();

            GUILayout.EndVertical();
            #endregion

            // BOARDGAME PARTS //
            #region
            if (boardObs == null)
                InitializeObjectData("Boardgame Parts");

            _itemCount = boardObs.Length;
            _rows = 0;
            while (_itemCount > 0)
            {
                _itemCount -= _columns;
                _rows++;
            }

            GUILayout.BeginVertical("HelpBox", GUILayout.Height(_rows * _tileSize));

            GUILayout.BeginHorizontal();
            GUILayout.FlexibleSpace();
            GUILayout.Label("Boardgame Parts", EditorStyles.boldLabel);
            GUILayout.FlexibleSpace();
            GUILayout.EndHorizontal();

            GUILayout.BeginHorizontal(gridStyle);
            GUILayout.FlexibleSpace();

            CreatePrefabGrid(_tileSize, _columns, _rows, "Boardgame Parts", boardNames, ref boardTextures, ref boardsInitialized);

            GUILayout.FlexibleSpace();
            GUILayout.EndHorizontal();

            GUILayout.BeginHorizontal();
            GUILayout.Label("");
            GUILayout.EndHorizontal();

            GUILayout.EndVertical();
            #endregion

            // TINKERCAD PREFABS //
            #region
            if (customWandObs == null)
                InitializeObjectData("Tinkercad");

            _itemCount = tinkerObs.Length;
            _rows = 0;
            while (_itemCount > 0)
            {
                _itemCount -= _columns;
                _rows++;
            }

            GUILayout.BeginVertical("HelpBox", GUILayout.Height(_rows * _tileSize));

            GUILayout.BeginHorizontal();
            GUILayout.FlexibleSpace();
            GUILayout.Label("Tinkercad Models", EditorStyles.boldLabel);
            GUILayout.FlexibleSpace();
            GUILayout.EndHorizontal();

            GUILayout.BeginHorizontal(gridStyle);
            GUILayout.FlexibleSpace();

            CreatePrefabGrid(_tileSize, _columns, _rows, "Tinkercad", tinkerNames, ref tinkerTextures, ref tinkersInitialized);

            GUILayout.FlexibleSpace();
            GUILayout.EndHorizontal();

            GUILayout.BeginHorizontal();
            GUILayout.Label("");
            GUILayout.EndHorizontal();

            GUILayout.EndVertical();
            #endregion

            // DEFAULT WANDS //
            #region
            if (wandObs == null)
                InitializeObjectData("Wands");

            _itemCount = wandObs.Length;
            _rows = 0;
            while (_itemCount > 0)
            {
                _itemCount -= _columns;
                _rows++;
            }

            GUILayout.BeginVertical("HelpBox", GUILayout.Height(_rows * _tileSize));

            GUILayout.BeginHorizontal();
            GUILayout.FlexibleSpace();
            GUILayout.Label("Default Wands", EditorStyles.boldLabel);
            GUILayout.FlexibleSpace();
            GUILayout.EndHorizontal();

            GUILayout.BeginHorizontal(gridStyle);
            GUILayout.FlexibleSpace();

            CreatePrefabGrid(_tileSize, _columns, _rows, "Wands", wandNames, ref wandTextures, ref wandsInitialized);

            GUILayout.FlexibleSpace();
            GUILayout.EndHorizontal();

            GUILayout.BeginHorizontal();
            GUILayout.Label("");
            GUILayout.EndHorizontal();

            GUILayout.EndVertical();
            #endregion

            // CUSTOM WANDS //
            #region
            if (customWandObs == null)
                InitializeObjectData("Custom Wands");

            _itemCount = customWandObs.Length;
            _rows = 0;
            while (_itemCount > 0)
            {
                _itemCount -= _columns;
                _rows++;
            }

            GUILayout.BeginVertical("HelpBox", GUILayout.Height(_rows * _tileSize));

            GUILayout.BeginHorizontal();
            GUILayout.FlexibleSpace();
            GUILayout.Label("Custom Wands", EditorStyles.boldLabel);
            GUILayout.FlexibleSpace();
            GUILayout.EndHorizontal();

            GUILayout.BeginHorizontal(gridStyle);
            GUILayout.FlexibleSpace();

            CreatePrefabGrid(_tileSize, _columns, _rows, "Custom Wands", customWandNames, ref customWandTextures, ref customWandsInitialized);

            GUILayout.FlexibleSpace();
            GUILayout.EndHorizontal();

            GUILayout.BeginHorizontal();
            GUILayout.Label("");
            GUILayout.EndHorizontal();

            GUILayout.EndVertical();
            #endregion

            // SPECIAL //
            #region
            if (specObs == null)
                InitializeObjectData("Special");

            _itemCount = specObs.Length;
            _rows = 0;
            while (_itemCount > 0)
            {
                _itemCount -= _columns;
                _rows++;
            }

            GUILayout.BeginVertical("HelpBox", GUILayout.Height(_rows * _tileSize));

            GUILayout.BeginHorizontal();
            GUILayout.FlexibleSpace();
            GUILayout.Label("Special", EditorStyles.boldLabel);
            GUILayout.FlexibleSpace();
            GUILayout.EndHorizontal();

            GUILayout.BeginHorizontal(gridStyle);
            GUILayout.FlexibleSpace();

            CreatePrefabGrid(_tileSize, _columns, _rows, "Special", specNames, ref specTextures, ref specsInitialized);

            GUILayout.FlexibleSpace();
            GUILayout.EndHorizontal();

            GUILayout.BeginHorizontal();
            GUILayout.Label("");
            GUILayout.EndHorizontal();

            GUILayout.EndVertical();
            #endregion

            GUILayout.EndVertical();

            #endregion
            GUILayout.EndScrollView();

            GUILayout.EndArea();

            Repaint();
        }

        private void CreatePrefabGrid(float _tileSize, int _columns, int _rows, string _folderName, string[] _gridNames, ref Texture2D[] _gridTextures, ref bool[] _gridInitialized)
        {
            if (_gridTextures.Length > 0)
            {
                int _selectNum = -1;

                if (_gridTextures == null)
                    return;

                GUIContent[] _contents = new GUIContent[_gridTextures.Length];

                for (int i = 0; i < _gridTextures.Length; i++)
                    _contents[i] = new GUIContent(_gridTextures[i], _gridNames[i]);

                _selectNum = GUILayout.SelectionGrid(_selectNum, _contents, _columns, GUILayout.Width(_tileSize * _columns), GUILayout.Height(_tileSize * _rows));

                if (_selectNum != -1)
                {
                    Vector3 _pos = Vector3.zero;

                    Event e = Event.current;

                    Ray ray = SceneView.lastActiveSceneView.camera.ScreenPointToRay(new Vector3(Screen.width/2, Screen.height/2, 0));
                    RaycastHit hit;
                    if (e.type == EventType.MouseDown)
                    {
                        if (Physics.Raycast(ray, out hit, 100.0f, LayerMask.GetMask("Environment")))
                        {
                            _pos = hit.point;
                        }
                    }

                    GameObject _newObj = GameObject.Instantiate(Resources.Load<GameObject>(_folderName + "/" + _gridNames[_selectNum]), _pos, Quaternion.identity);
                    _newObj.name = _newObj.name.Replace("(Clone)", "");
                    Undo.RegisterCreatedObjectUndo(_newObj, "New " + _folderName + " Prefab Instantiated");

                    if (_newObj.GetComponent<ColorChanger>())
                        _newObj.GetComponent<ColorChanger>().InitializeColorChanger();

                    if (_newObj.transform.childCount > 0)
                        if (_newObj.transform.GetChild(0).name.Contains("group"))
                            _newObj.AddComponent<Tinkercad>();

                    Selection.activeTransform = _newObj.transform;
                    SceneView.lastActiveSceneView.FrameSelected();
                    _selectNum = -1;
                }
            }
            else
            {
                GUILayout.Label("No " + _folderName + " found!");
            }
        }
    }
}