/// <summary>
        /// Initializes a new instance of the <see cref="Map2DTileSelection"/> class.
        /// </summary>
        public Map2DTileSelection()
        {
            // setup controls and variables
            this.materialControls = new GenericMaterialCreationControl();
            this.mainPreview      = new TileSelectionControl();
            this.materialControls.ShowFreeform     = false;
            this.materialControls.ShowColor        = false;
            this.materialControls.ShowShader       = false;
            this.mainPreview.MultipleTileSelection = false;
            this.mainPreview.ShowHoverRectangle    = false;

            // hook into the before spacing drawn event to allow us to customize the look
            this.materialControls.BeforeSpacingDrawn = () => GUILayout.BeginVertical();

            // hook into the after spacing drawn event to allow us to customize the look
            this.materialControls.AfterSpacingDrawn = () =>
            {
                GUILayout.BeginHorizontal(GUILayout.ExpandWidth(false));

                var items = new bool[4];
                items[this.mainPreview.Zoom - 1] = true;
                ControlGrid.DrawGenericGrid(
                    (data, index, style, options) =>
                {
                    var result = GUILayout.Toggle(data[index], (index + 1).ToString(CultureInfo.InvariantCulture), style, options);
                    if (result != data[index])
                    {
                        this.mainPreview.Zoom = index + 1;
                    }

                    return(result);
                },
                    items,
                    items.Length,
                    GUI.skin.button);

                GUILayout.EndHorizontal();
                GUILayout.EndVertical();
            };

            // hook into the tile selection event on the main preview control
            this.mainPreview.TileSelection += this.MainPreviewTileSelection;

            // hook into the main preview texture changed so we can generate a generic image for the selected texture
            this.mainPreview.TextureChanged += this.MainPreviewTextureChanged;

            // Hook into the texture changed event and update the texture and selected texture id's
            this.materialControls.TextureChanged += (s, e) =>
            {
                this.mainPreview.TextureAsset = this.materialControls.TextureAsset;
            };

            // ensure preview texture size is updated
            this.materialControls.TileSizeChanged += (s, e) =>
            {
                this.mainPreview.TileHeight = this.materialControls.TileHeight;
                this.mainPreview.TileWidth  = this.materialControls.TileWidth;
            };

            // hook into events to sync control properties
            this.materialControls.StartSpacingChanged += (s, e) => { this.mainPreview.StartSpacing = this.materialControls.StartSpacing; };
            this.materialControls.SpacingChanged      += (s, e) => { this.mainPreview.Spacing = this.materialControls.Spacing; };
            this.materialControls.FreeformChanged     += (s, e) => { this.mainPreview.FreeForm = this.materialControls.FreeForm; };

            // sync control properties
            this.mainPreview.Refresh     += (s, e) => this.Repaint();
            this.mainPreview.StartSpacing = this.materialControls.StartSpacing;
            this.mainPreview.Spacing      = this.materialControls.Spacing;
            this.mainPreview.FreeForm     = this.materialControls.FreeForm;
        }
        /// <summary>
        /// Initializes a new instance of the <see cref="AutomaticMaterialCreationWindow"/> class.
        /// </summary>
        public AutomaticMaterialCreationWindow()
        {
            // setup controls and variables
            this.tileMaterials    = new Dictionary <string, List <TileSelectionModel> >();
            this.images           = new Dictionary <string, GenericImage <Color> >();
            this.materialControls = new GenericMaterialCreationControl();
            this.mainPreview      = new TileSelectionControl();

            // hook into the before spacing drawn event to allow us to customize the look
            this.materialControls.BeforeSpacingDrawn = () =>
            {
                GUILayout.BeginHorizontal();
                GUILayout.BeginVertical();
            };

            // hook into the after spacing drawn event to allow us to customize the look
            this.materialControls.AfterSpacingDrawn = () =>
            {
                GUILayout.EndVertical();

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

            // draw a show materials toggle button after the texture controls have been drawn
            this.materialControls.AfterTextureDrawn = () =>
            {
                this.showMaterials = GUILayout.Toggle(this.showMaterials, "Show\r\nMaterials", GUI.skin.button);
            };

            // hook into the tile selection event on the main preview control
            this.mainPreview.TileSelection += this.MainPreviewTileSelection;

            // Hook into the texture changed event and update the texture and selected texture id's
            this.materialControls.TextureChanged += (s, e) =>
            {
                this.mainPreview.TextureAsset = this.materialControls.TextureAsset;
                this.selectedTextureId        = AssetDatabase.AssetPathToGUID(AssetDatabase.GetAssetOrScenePath(this.materialControls.TextureAsset));
            };

            // ensure preview texture size is updated
            this.materialControls.TileSizeChanged += (s, e) =>
            {
                this.mainPreview.TileHeight = this.materialControls.TileHeight;
                this.mainPreview.TileWidth  = this.materialControls.TileWidth;
            };

            // hook into events to sync control properties
            this.materialControls.StartSpacingChanged += (s, e) => { this.mainPreview.StartSpacing = this.materialControls.StartSpacing; };
            this.materialControls.SpacingChanged      += (s, e) => { this.mainPreview.Spacing = this.materialControls.Spacing; };
            this.materialControls.FreeformChanged     += (s, e) => { this.mainPreview.FreeForm = this.materialControls.FreeForm; };

            // sync control properties
            this.mainPreview.Refresh     += (s, e) => this.Repaint();
            this.mainPreview.StartSpacing = this.materialControls.StartSpacing;
            this.mainPreview.Spacing      = this.materialControls.Spacing;
            this.mainPreview.FreeForm     = this.materialControls.FreeForm;

            // get grid mapping service and hook into the prefab drawn event
            var gridMappingService = GridMappingService.Instance;

            gridMappingService.PrefabDrawn += this.GridMappingService_PrefabDrawn;
        }