/// <summary>
        /// Handles the event for tile selection.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">An System.EventArgs that contains no event data.</param>
        private void MainPreviewTileSelection(object sender, TileSelectionEventArgs e)
        {
            // do nothing until selection has completed or if no texture selected 
            if (e.Status != TileSelectionStatus.Complete || this.materialControls.TextureAsset == null)
            {
                return;
            }

            // check if already has entry for a texture
            // var textureId = this.materialControls.TextureAsset.GetInstanceID();
            var textureId = AssetDatabase.AssetPathToGUID(AssetDatabase.GetAssetOrScenePath(this.materialControls.TextureAsset));
            if (!this.tileMaterials.ContainsKey(textureId))
            {
                // no entry so add one
                this.tileMaterials.Add(textureId, new List<TileSelectionModel>());

                // generate a generic image for the texture so it can be used for previews
                this.images.Add(textureId, this.materialControls.TextureAsset.CreateGenericImage());
            }

            // get entry list
            var list = this.tileMaterials[textureId];

            // get tile size, shader name & color
            var size = new Size(this.mainPreview.TileWidth, this.mainPreview.TileHeight);
            var shaderName = this.materialControls.SelectedShaderName;
            var color = this.materialControls.MaterialColor;

            var settings = SettingsManager.Instance;
            var shaderListStyle = settings.GetSetting(GlobalConstants.AutoMaterialCreationShaderListStyleKey, 0);

            // check for matching top/left bottom/right, size, shader name & color values
            var result = list.FirstOrDefault(x => e.Min == x.Min &&
                                                  e.Max == x.Max &&
                                                  size == x.TileSize &&
                                                  shaderName == x.ShaderName &&
                                                  color == x.Color);

            var local = Localization.LocalizationManager.Instance;
            if (result == null)
            {
                // attempt to create a a new material 
                var model = new TileSelectionModel();
                try
                {
                    shaderName = shaderListStyle == 1 ? shaderName.Replace(Path.DirectorySeparatorChar, Path.AltDirectorySeparatorChar) : shaderName;
                    var shader = Shader.Find(shaderName);
                    model.Material = new Material(shader);
                }
                catch (Exception ex)
                {
                    // report error
                    EditorUtility.DisplayDialog(local.Get("Warning"), ex.Message, local.Get("Close"));
                    return;
                }

                // get texture co-ordinates for the material
                var textureCoordinates = this.mainPreview.GetTextureCoordinates(this.materialControls, 0);
                model.Material.mainTextureOffset = new Vector2(textureCoordinates.xMin, textureCoordinates.yMin);
                model.Material.mainTextureScale = new Vector2(textureCoordinates.width, textureCoordinates.height);
                model.Material.mainTexture = this.materialControls.TextureAsset;
                model.Material.color = color;

                model.Min = e.Min;
                model.Max = e.Max;
                model.IsDirty = true;
                model.TileSize = size;
                model.ShaderName = shaderName;

                // set model preview texture
                var image = model.Material.ToGenericImage();
                image.Tint(color, TintType.Alpha);
                model.TexturePreview = image.ToTexture2D();

                list.Add(model);
                result = model;

                // save material selections to settings to keep a record of selections
                this.SaveToSettings(result);
            }

            // set current material
            GridMappingService.Instance.CurrentMaterial = result.Material;

#if DEBUG
            Debug.Log(string.Format("{0} textures {1} unique", this.tileMaterials.Count, this.tileMaterials.Sum(x => x.Value.Count)));
#endif
        }
        /// <summary>
        /// Handles the event for tile selection.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">An System.EventArgs that contains no event data.</param>
        private void MainPreviewTileSelection(object sender, TileSelectionEventArgs e)
        {
            // do nothing until selection has completed or if no texture selected 
            if (e.Status != TileSelectionStatus.Complete || this.materialControls.TextureAsset == null)
            {
                return;
            }

            var image = new GenericImage<Color>(this.mainPreview.TileWidth, this.mainPreview.TileHeight);
            image.Draw(
                this.materialControls.TextureAsset.CreateGenericImage(),
                0,
                0,
                e.Min.X,
                e.Min.Y,
                this.mainPreview.TileWidth,
                this.mainPreview.TileHeight,
                (source, blendWith) => blendWith);

            this.SelectedTile = image;
        }