//
        public static SavePresetWindow Init(string name, InputResult callback)
        {
            Rect             rect   = new Rect(Screen.width * 0.5f, Screen.height * 0.5f, 300f, 60f);
            SavePresetWindow window = GetWindowWithRect <SavePresetWindow>(rect, true, "Specify Preset Name", true);

            window.callback   = callback;
            window.presetName = name;
            return(window);
        }
        //
        protected virtual void CloseWindow()
        {
            if (window == null)
            {
                return;
            }

            window.Close();
            window = null;
        }
        //
        protected void RendererGUI()
        {
                        #if UNITY_IPHONE || UNITY_ANDROID || UNITY_WP8 || UNITY_BLACKBERRY
            if (!PlayerSettings.use32BitDisplayBuffer)
            {
                EditorGUILayout.HelpBox("Highlighting System requires 32-bit display buffer. Set the 'Use 32-bit Display Buffer' checkbox under the 'Resolution and Presentation' section of Player Settings.", MessageType.Error);
            }
                        #endif

            if (hb.blitter == null)
            {
                EditorGUILayout.HelpBox("Use order of this component (relatively to other Image Effects applied to this camera) to control the point at which highlighting will be applied to the framebuffer (click on a little gear icon to the right and choose Move Up / Move Down) or assign HighlightingBlitter component from the other camera.", MessageType.Info);
            }
            else if (hb.GetComponent <Camera>() == hb.blitter.GetComponent <Camera>())
            {
                EditorGUILayout.HelpBox("Assigned HighlightingBlitter component exists on the same camera. This is not really necessary in most situations and affects rendering performance! Please make sure this is intended.", MessageType.Warning);
            }
            hb.blitter = EditorGUILayout.ObjectField("Blitter (Optional)", hb.blitter, typeof(HighlightingBlitter), true) as HighlightingBlitter;

            EditorGUILayout.HelpBox("Depth Offset properties should be used only when Dynamic Batching is enabled in Player Settings. Otherwise set them to 0's to avoid rendering artifacts.", MessageType.Info);
            EditorGUI.BeginChangeCheck();
            hb.offsetFactor = EditorGUILayout.Slider("Depth Offset Factor:", hb.offsetFactor, -1f, 0f);
            hb.offsetUnits  = EditorGUILayout.Slider("Depth Offset Units:", hb.offsetUnits, -100f, 0f);
            if (EditorGUI.EndChangeCheck())
            {
                EditorUtility.SetDirty(hb);
            }

            EditorGUILayout.Space();

            EditorGUILayout.LabelField("Preset:");

            int oldIndex = presetIndex;
            int newIndex = EditorGUILayout.Popup(presetIndex, presetNames);
            if (oldIndex != newIndex)
            {
                SetPresetSettings(newIndex);
                presetIndex = newIndex;
            }

            Preset currentPreset = new Preset();
            if (presetIndex >= 0)
            {
                currentPreset = presets[presetIndex];
            }

            EditorGUI.BeginChangeCheck();

            SetBoldDefaultFont(presetIndex < 0 || hb.downsampleFactor != currentPreset.downsampleFactor);
            hb.downsampleFactor = _downsampleSet[EditorGUILayout.Popup("Downsampling:", _downsampleGet[hb.downsampleFactor], downsampleOptions)];

            SetBoldDefaultFont(presetIndex < 0 || hb.iterations != currentPreset.iterations);
            hb.iterations = Mathf.Clamp(EditorGUILayout.IntField("Iterations:", hb.iterations), 0, 50);

            SetBoldDefaultFont(presetIndex < 0 || hb.blurMinSpread != currentPreset.blurMinSpread);
            hb.blurMinSpread = EditorGUILayout.Slider("Min Spread:", hb.blurMinSpread, 0f, 3f);

            SetBoldDefaultFont(presetIndex < 0 || hb.blurSpread != currentPreset.blurSpread);
            hb.blurSpread = EditorGUILayout.Slider("Spread:", hb.blurSpread, 0f, 3f);

            SetBoldDefaultFont(presetIndex < 0 || hb.blurIntensity != currentPreset.blurIntensity);
            hb.blurIntensity = EditorGUILayout.Slider("Intensity:", hb.blurIntensity, 0f, 1f);

            SetBoldDefaultFont(false);

            if (EditorGUI.EndChangeCheck())
            {
                // If settings have changed when default preset has been selected
                if (presetIndex < defaultPresets.Count)
                {
                    presetIndex = -1;
                }
                EditorUtility.SetDirty(hb);
            }

            int customPresetIndex = presetIndex - defaultPresets.Count;

            EditorGUILayout.BeginHorizontal();
            if (GUILayout.Button("Save Preset"))
            {
                string defaultName;
                if (customPresetIndex < 0)
                {
                    defaultName = "My Preset";
                }
                else
                {
                    defaultName = customPresets[customPresetIndex].name;
                }
                window = SavePresetWindow.Init(defaultName, SavePresetAs);
            }

            if (presetIndex < defaultPresets.Count)
            {
                GUI.enabled = false;
            }
            if (GUILayout.Button(GUI.enabled ? removeButtonContent : removeButtonContentDisabled))
            {
                bool delete = EditorUtility.DisplayDialog("Removing Preset", "Are you sure - you want to remove Preset '" + customPresets[customPresetIndex].name + "'?", "Yes", "No");
                if (delete)
                {
                    customPresets.RemoveAt(customPresetIndex);
                    SavePresets();
                    LoadPresets();
                    SetPresetSettings(0);
                    presetIndex = 0;
                }
            }
            GUI.enabled = true;
            EditorGUILayout.EndHorizontal();
        }
        //
        protected virtual PresetSaveResult SavePresetAs(string name, bool overwrite)
        {
            window = null;

            if (string.IsNullOrEmpty(name))
            {
                return(PresetSaveResult.Null);
            }

            int customPresetIndex = -1;

            for (int i = 0, imax = presets.Count; i < imax; i++)
            {
                if (presets[i].name == name)
                {
                    if (i < defaultPresets.Count)
                    {
                        // Overwriting default presets is not allowed
                        return(PresetSaveResult.Default);
                    }
                    else if (!overwrite)
                    {
                        // Preset with this name already exists
                        return(PresetSaveResult.Exists);
                    }
                    else
                    {
                        // Overwrite custom preset with this name
                        customPresetIndex = i - defaultPresets.Count;
                        break;
                    }
                }
            }

            Preset p = new Preset();

            p.name             = name;
            p.downsampleFactor = hb.downsampleFactor;
            p.iterations       = hb.iterations;
            p.blurMinSpread    = hb.blurMinSpread;
            p.blurSpread       = hb.blurSpread;
            p.blurIntensity    = hb.blurIntensity;

            int newIndex = -1;

            if (overwrite && customPresetIndex >= 0)
            {
                customPresets[customPresetIndex] = p;
                newIndex = customPresetIndex + defaultPresets.Count;
            }
            else
            {
                customPresets.Add(p);
                newIndex = customPresets.Count + defaultPresets.Count - 1;
            }

            SavePresets();
            LoadPresets();
            presetIndex = newIndex;
            EditorUtility.SetDirty(hb);

            return(PresetSaveResult.Success);
        }