void DrawLut(AmplifyColorVolume volume)
 {
     GUILayout.Space(0);
     volume.LutTexture = ( Texture2D )EditorGUILayout.ObjectField(volume.LutTexture, typeof(Texture2D), false, GUILayout.Width(lutWidth), GUILayout.Height(lutWidth));
     GUILayout.FlexibleSpace();
     GUILayout.Space(5);
 }
    bool GetFoldout(AmplifyColorVolume volume)
    {
        string key = GetEditorPrefsKey(volume);

        if (!EditorPrefs.HasKey(key))
        {
            EditorPrefs.SetBool(key, false);
        }
        return(EditorPrefs.GetBool(key));
    }
    void DrawVolumeEffects(AmplifyColorVolume volume)
    {
        GUIStyle layerTitleStyle = new GUIStyle(EditorStyles.miniBoldLabel);

        layerTitleStyle.alignment = TextAnchor.MiddleLeft;
        layerTitleStyle.margin    = new RectOffset(0, 0, 0, 0);

        GUIStyle foldoutTitleStyle = new GUIStyle(EditorStyles.foldout);

        foldoutTitleStyle.fontSize = 10;

        GUILayout.BeginHorizontal();
        GUILayout.Space(10);
        GUILayout.Label("", GUILayout.MinWidth(iconMinWidth), GUILayout.MaxWidth(iconMaxWidth - 10));
        GUILayout.Space(2);

        GUILayout.BeginVertical();
        GUILayout.Space(0);

        GUILayout.BeginHorizontal();
        bool foldout = SetFoldout(volume, EditorGUILayout.Foldout(GetFoldout(volume), "Blend Effects", foldoutTitleStyle));

        GUILayout.EndHorizontal();

        GUILayout.Space(3);

        if (foldout)
        {
            DrawVolumeEffectFields(volume);
        }

        GUILayout.EndVertical();

        GUILayout.Space(0);
        GUILayout.EndHorizontal();
    }
    void DrawVolumeEffectFields(AmplifyColorVolume volume)
    {
        List <VolumeEffect> effectsToDelete = new List <VolumeEffect>();
        float removeButtonSize = 16;

        List <NewLineContainer> volumeLines = null;

        if (!(newLines.TryGetValue(volume, out volumeLines)))
        {
            volumeLines = newLines[volume] = new List <NewLineContainer>();
        }

        GUIStyle minusStyle = new GUIStyle(( GUIStyle )"OL Minus");
        GUIStyle plusStyle  = new GUIStyle(( GUIStyle )"OL Plus");

        minusStyle.margin.top = 2;
        plusStyle.margin.top  = 2;

        #region CurrentEffectFields
        int fieldPosition = 0;
        foreach (VolumeEffect effectVol in volume.EffectContainer.volumes)
        {
            if (effectVol.gameObject == null)
            {
                continue;
            }

            AmplifyColorBase             effect        = effectVol.gameObject;
            List <VolumeEffectComponent> compsToDelete = new List <VolumeEffectComponent>();

            foreach (VolumeEffectComponent comp in effectVol.components)
            {
                Component c = effect.GetComponent(comp.componentName);
                if (c == null)
                {
                    continue;
                }

                List <VolumeEffectField>           fieldsToDelete = new List <VolumeEffectField>();
                List <KeyValuePair <string, int> > fieldsToAdd    = new List <KeyValuePair <string, int> >();

                foreach (VolumeEffectField field in comp.fields)
                {
                    EditorGUILayout.BeginHorizontal();
                    GUILayout.Label("", GUILayout.MinWidth(minIndentWidth), GUILayout.MaxWidth(maxIndentWidth));
                    GUILayout.Space(0);

                    if (GUILayout.Button("", minusStyle, GUILayout.MinWidth(18), GUILayout.MaxWidth(18), GUILayout.Height(20)))
                    {
                        fieldsToDelete.Add(field);
                    }

                    AmplifyColorBase[]      effectArray = Resources.FindObjectsOfTypeAll(typeof(AmplifyColorBase)) as AmplifyColorBase[];
                    List <AmplifyColorBase> effectList  = effectArray.ToList();
                    int selectedEffect = -1;

                    if (effectArray.Count() > 0)
                    {
                        int popupSelected = effectList.IndexOf(effect);
                        selectedEffect = EditorGUILayout.Popup(popupSelected, (from e in effectList select e.gameObject.name).ToArray(), GUILayout.MinWidth(minColumnWidth), GUILayout.MaxWidth(maxColumnWidth));
                        if (selectedEffect != popupSelected)
                        {
                            fieldsToDelete.Add(field);
                            dirtyVolumeFlags = true;
                            volumeLines.Add(new NewLineContainer(effectList.ElementAtOrDefault(selectedEffect)));
                        }
                    }

                    Component[]   compArray      = VolumeEffect.ListAcceptableComponents(effectVol.gameObject);
                    List <string> compFlagsArray = compArray.Select(s => s.GetType().Name).ToList();
                    compFlagsArray.Remove(comp.componentName);
                    string[] compNamesArray = new string[] { comp.componentName }.Concat(compFlagsArray).ToArray();
                    int      selectedComponent = 0;
                    selectedComponent = EditorGUILayout.Popup(selectedComponent, compNamesArray, GUILayout.MinWidth(minColumnWidth), GUILayout.MaxWidth(maxColumnWidth));
                    if (selectedComponent != 0)
                    {
                        volumeLines.Add(new NewLineContainer(effect, compNamesArray[selectedComponent]));
                        fieldsToDelete.Add(field);
                        dirtyVolumeFlags = true;
                    }

                    FieldInfo[] fieldArray      = VolumeEffectComponent.ListAcceptableFields(c);
                    string[]    fieldFlagsArray = fieldArray.Select(s => s.Name).ToArray();
                    string[]    fieldNamesArray = comp.GetFieldNames();
                    fieldFlagsArray = fieldFlagsArray.Except(fieldNamesArray).ToArray();

                    List <string> names = new List <string>();
                    names.Add(field.fieldName);
                    names.AddRange(fieldFlagsArray);
                    for (int i = 0; i < names.Count; i++)
                    {
                        if (i == 0)
                        {
                            continue;
                        }

                        FieldInfo fi = Array.Find(fieldArray, s => (names[i] == s.Name));
                        if (fi != null)
                        {
                            names[i] += " : " + fi.FieldType.Name;
                        }
                    }

                    int selectedField = 0;
                    selectedField = EditorGUILayout.Popup(selectedField, names.ToArray(), GUILayout.MinWidth(minColumnWidth), GUILayout.MaxWidth(maxColumnWidth));
                    if (selectedField != 0)
                    {
                        fieldsToAdd.Add(new KeyValuePair <string, int>(fieldFlagsArray[selectedField - 1], fieldPosition));
                        fieldsToDelete.Add(field);
                        dirtyVolumeFlags = true;
                    }
                    fieldPosition++;

                    switch (field.fieldType)
                    {
                    case "System.Single": field.valueSingle = EditorGUILayout.FloatField(field.valueSingle, GUILayout.MinWidth(minValueWidth), GUILayout.MaxWidth(maxValueWidth)); break;

                    case "System.Boolean": field.valueBoolean = EditorGUILayout.Toggle("", field.valueBoolean, GUILayout.MinWidth(minValueWidth), GUILayout.MaxWidth(maxValueWidth)); break;

                    case "UnityEngine.Vector2": field.valueVector2 = EditorGUILayout.Vector2Field("", field.valueVector2, GUILayout.MinWidth(minValueWidth), GUILayout.MaxWidth(maxValueWidth), GUILayout.MaxHeight(16)); break;

                    case "UnityEngine.Vector3": field.valueVector3 = EditorGUILayout.Vector3Field("", field.valueVector3, GUILayout.MinWidth(minValueWidth), GUILayout.MaxWidth(maxValueWidth), GUILayout.MaxHeight(16)); break;

                    case "UnityEngine.Vector4": field.valueVector4 = DrawFixedVector4Field(field.valueVector4); break;

                    case "UnityEngine.Color": field.valueColor = EditorGUILayout.ColorField(field.valueColor, GUILayout.MinWidth(minValueWidth), GUILayout.MaxWidth(maxValueWidth)); break;

                    default: EditorGUILayout.LabelField(field.fieldType, GUILayout.MinWidth(minValueWidth), GUILayout.MaxWidth(maxValueWidth)); break;
                    }

                    // COPY TO CLIPBOARD
                    string luid   = NewLineContainer.GenerateUniqueID(effect, comp.componentName, field.fieldName);
                    bool   copied = copyLines.ContainsKey(luid);
                    bool   keep   = GUILayout.Toggle(copied, "c", removeButtonStyle, GUILayout.Width(removeButtonSize), GUILayout.Height(removeButtonSize));
                    if (keep != copied)
                    {
                        if (keep)
                        {
                            object valueCopy = null;
                            switch (field.fieldType)
                            {
                            case "System.Single": valueCopy = field.valueSingle; break;

                            case "System.Boolean": valueCopy = field.valueBoolean; break;

                            case "UnityEngine.Vector2": valueCopy = field.valueVector2; break;

                            case "UnityEngine.Vector3": valueCopy = field.valueVector3; break;

                            case "UnityEngine.Vector4": valueCopy = field.valueVector4; break;

                            case "UnityEngine.Color": valueCopy = field.valueColor; break;
                            }
                            copyLines.Add(luid, new NewLineContainer(effect, comp.componentName, field.fieldName, field.fieldType, valueCopy));
                        }
                        else
                        {
                            copyLines.Remove(luid);
                        }

                        //Debug.Log( "CopyComplete: " + luid + ", " + keep + ", " + volume.name );
                    }

                    EditorGUILayout.EndHorizontal();
                    GUILayout.Space(2);
                }

                bool fieldRemoved = false;
                foreach (VolumeEffectField field in fieldsToDelete)
                {
                    comp.RemoveEffectField(field);
                    fieldRemoved = true;
                }

                foreach (KeyValuePair <string, int> pair in fieldsToAdd)
                {
                    FieldInfo pi = c.GetType().GetField(pair.Key);
                    if (pi != null)
                    {
                        comp.AddField(pi, c, pair.Value);
                    }
                }

                if (fieldRemoved && comp.fields.Count <= 0)
                {
                    compsToDelete.Add(comp);
                }
            }

            bool compRemoved = false;
            foreach (VolumeEffectComponent comp in compsToDelete)
            {
                effectVol.RemoveEffectComponent(comp);
                compRemoved = true;
            }

            if (compRemoved && effectVol.components.Count <= 0)
            {
                effectsToDelete.Add(effectVol);
            }
        }

        foreach (VolumeEffect effectVol in effectsToDelete)
        {
            volume.EffectContainer.RemoveVolumeEffect(effectVol);
        }
        #endregion

        #region NewLines
        List <NewLineContainer> linesToDelete = new List <NewLineContainer>();
        foreach (NewLineContainer line in volumeLines)
        {
            EditorGUILayout.BeginHorizontal();
            GUILayout.Label("", GUILayout.MinWidth(minIndentWidth), GUILayout.MaxWidth(maxIndentWidth));
            GUILayout.Space(0);

            if (GUILayout.Button("", minusStyle, GUILayout.MinWidth(18), GUILayout.MaxWidth(18), GUILayout.Height(20)))
            {
                linesToDelete.Add(line);
            }

            AmplifyColorBase[]      colorEffectArray = Resources.FindObjectsOfTypeAll(typeof(AmplifyColorBase)) as AmplifyColorBase[];
            List <AmplifyColorBase> colorEffectList  = colorEffectArray.ToList();

            if (colorEffectArray.Count() > 0)
            {
                int           popupSelected  = (line.camera != null) ? colorEffectList.IndexOf(line.camera) + 1 : 0;
                int           selectedEffect = popupSelected;
                List <string> names          = (from e in colorEffectList select e.gameObject.name).ToList <string>();
                names.Insert(0, "<Camera>");
                selectedEffect = EditorGUILayout.Popup(selectedEffect, names.ToArray(), GUILayout.MinWidth(minColumnWidth), GUILayout.MaxWidth(maxColumnWidth));
                if (selectedEffect != popupSelected && selectedEffect > 0)
                {
                    line.SetCamera(colorEffectArray[selectedEffect - 1]);
                }
            }

            VolumeEffect effectVol = null;
            if (line.camera != null)
            {
                effectVol = volume.EffectContainer.GetVolumeEffect(line.camera);
            }

            if (line.camera != null)
            {
                Component[]   compArray     = VolumeEffect.ListAcceptableComponents(line.camera);
                List <string> names         = compArray.Select(s => s.GetType().Name).ToList <string>();
                int           popupSelected = names.IndexOf(line.component) + 1;
                names.Insert(0, "<Component>");
                int selectedComponent = popupSelected;
                selectedComponent = EditorGUILayout.Popup(selectedComponent, names.ToArray(), GUILayout.MinWidth(minColumnWidth), GUILayout.MaxWidth(maxColumnWidth));
                if (selectedComponent != popupSelected)
                {
                    line.SetComponent(selectedComponent == 0 ? null : names[selectedComponent]);
                }
            }
            else
            {
                GUI.enabled = false;
                EditorGUILayout.Popup(0, new string[] { "<Component>" }, GUILayout.MaxWidth(maxColumnWidth));
                GUI.enabled = true;
            }

            Component c = (line.camera == null) ? null : line.camera.GetComponent(line.component);

            VolumeEffectComponent comp = null;
            if (effectVol != null)
            {
                comp = effectVol.GetEffectComponent(line.component);
            }

            if (c != null)
            {
                FieldInfo[] fieldArray      = VolumeEffectComponent.ListAcceptableFields(c);
                string[]    fieldFlagsArray = fieldArray.Select(s => s.Name).ToArray();
                if (comp != null)
                {
                    string[] fieldNamesArray = comp.GetFieldNames();
                    fieldFlagsArray = fieldFlagsArray.Except(fieldNamesArray).ToArray();
                }

                List <string> names = fieldFlagsArray.ToList();
                for (int i = 0; i < names.Count; i++)
                {
                    FieldInfo fi = Array.Find(fieldArray, s => (names[i] == s.Name));
                    if (fi != null)
                    {
                        names[i] += " : " + fi.FieldType.Name;
                    }
                }
                names.Insert(0, "<Field>");

                int selectedField = 0;
                selectedField = EditorGUILayout.Popup(selectedField, names.ToArray(), GUILayout.MinWidth(minColumnWidth), GUILayout.MaxWidth(maxColumnWidth));
                if (selectedField > 0)
                {
                    FieldInfo pi = c.GetType().GetField(fieldFlagsArray[selectedField - 1]);
                    if (pi != null)
                    {
                        if (effectVol == null)
                        {
                            effectVol = volume.EffectContainer.AddJustColorEffect(line.camera);
                        }

                        if (comp == null)
                        {
                            comp = effectVol.AddComponent(c, null);
                        }

                        comp.AddField(pi, c);
                        linesToDelete.Add(line);
                        dirtyVolumeFlags = true;
                    }
                }

                EditorGUILayout.LabelField("", GUILayout.MinWidth(minValueWidth), GUILayout.MaxWidth(maxValueWidth));
            }
            else
            {
                GUI.enabled = false;
                EditorGUILayout.Popup(0, new string[] { "<Field>" }, GUILayout.MaxWidth(maxColumnWidth));
                EditorGUILayout.TextField("", GUILayout.MinWidth(minValueWidth), GUILayout.MaxWidth(maxValueWidth));
                GUI.enabled = true;
            }

            if (line.camera != null)
            {
                string luid   = NewLineContainer.GenerateUniqueID(line.camera, line.component, line.fieldName);
                bool   copied = copyLines.ContainsKey(luid);
                bool   keep   = GUILayout.Toggle(copied, "c", removeButtonStyle, GUILayout.Width(removeButtonSize), GUILayout.Height(removeButtonSize));
                if (keep != copied)
                {
                    if (keep)
                    {
                        copyLines.Add(luid, new NewLineContainer(line.camera, line.component, line.fieldName, line.fieldType, line.value));
                    }
                    else
                    {
                        copyLines.Remove(luid);
                    }

                    //Debug.Log( "CopyIncomplete: " + luid + ", " + keep + ", " + volume.name );
                }
            }
            else
            {
                GUI.enabled = false;
                GUILayout.Button("c", removeButtonStyle, GUILayout.Width(removeButtonSize), GUILayout.Height(removeButtonSize));
                GUI.enabled = true;
            }

            EditorGUILayout.EndHorizontal();
            GUILayout.Space(2);
        }

        foreach (NewLineContainer line in linesToDelete)
        {
            copyLines.Remove(line.GenerateUniqueID());
            //Debug.Log( "Removed " + line.GenerateUniqueID() );
            volumeLines.Remove(line);
        }
        #endregion

        #region AddPaste
        EditorGUILayout.BeginHorizontal();
        GUILayout.Label("", GUILayout.MinWidth(minIndentWidth), GUILayout.MaxWidth(maxIndentWidth));
        GUILayout.Space(0);

        bool add = GUILayout.Button("", plusStyle, GUILayout.MinWidth(18), GUILayout.MaxWidth(18), GUILayout.Height(20));
        if (add || GUILayout.Button("Add New", GUILayout.MinWidth(minColumnWidth), GUILayout.MaxWidth(maxColumnWidth), GUILayout.Height(20)))
        {
            volumeLines.Add(new NewLineContainer());
        }

        GUI.enabled = (copyLines.Count > 0);
        if (GUILayout.Button("Paste", GUILayout.MinWidth(minColumnWidth), GUILayout.MaxWidth(maxColumnWidth), GUILayout.Height(20)))
        {
            foreach (var pair in copyLines)
            {
                NewLineContainer line = pair.Value;
                Component        c    = (line.camera == null) ? null : line.camera.GetComponent(line.component);
                FieldInfo        pi   = (c != null) ? c.GetType().GetField(line.fieldName) : null;

                if (pi == null)
                {
                    volumeLines.Add(new NewLineContainer(line.camera, line.component, line.fieldName, line.fieldType, line.value));
                }
                else
                {
                    VolumeEffect effectVol = volume.EffectContainer.GetVolumeEffect(line.camera);
                    if (effectVol == null)
                    {
                        effectVol = volume.EffectContainer.AddJustColorEffect(line.camera);
                    }

                    VolumeEffectComponent comp = effectVol.GetEffectComponent(line.component);
                    if (comp == null)
                    {
                        comp = effectVol.AddComponent(c, null);
                    }

                    VolumeEffectField field = comp.GetEffectField(line.fieldName);
                    if (field == null)
                    {
                        field = comp.AddField(pi, c);
                    }
                    else
                    {
                        Debug.LogWarning("[AmplifyColor] Blend Effect field already added to Volume " + volume.name + ".");
                    }

                    field.UpdateValue(line.value);
                }
            }

            dirtyVolumeFlags = true;
        }
        GUI.enabled = true;

        EditorGUILayout.EndHorizontal();
        GUILayout.Space(5);
        #endregion
    }
    void DrawVolumeProperties(AmplifyColorVolume volume)
    {
        GameObject obj = volume.gameObject;

        GUILayout.BeginHorizontal();
        GUILayout.Space(10);

        volumeIcon = (volumeIcon == null) ? Resources.Load("volume-icon", typeof(Texture2D)) as Texture2D : volumeIcon;
        GUILayout.Label(volumeIcon, GUILayout.MinWidth(iconMinWidth), GUILayout.MaxWidth(iconMaxWidth));

        GUILayout.Space(0);

        #if UNITY_3
        bool active = obj.active;
        #else
        bool active = obj.activeInHierarchy;
        #endif
        bool keep = EditorGUILayout.Toggle(active, GUILayout.MinWidth(activeMinWidth), GUILayout.MaxWidth(activeMaxWidth));
        if (keep != active)
        {
                #if UNITY_3
            obj.active = keep;
                #else
            obj.SetActive(keep);
                #endif
        }

        GUILayout.Space(6);

        volume.ShowInSceneView = EditorGUILayout.Toggle(volume.ShowInSceneView, GUILayout.MinWidth(visibleMinWidth), GUILayout.MaxWidth(visibleMaxWidth));

        GUILayout.Space(6);

        GUI.skin.textField.fontSize  = 10;
        GUI.skin.textField.alignment = TextAnchor.UpperCenter;
        if (GUILayout.Button((Selection.activeObject == obj) ? "●" : "", EditorStyles.textField, GUILayout.Width(16), GUILayout.Height(16)))
        {
            Selection.activeObject = (Selection.activeObject == obj) ? null : obj;
        }

        GUILayout.Space(0);

        GUI.skin.textField.fontSize  = 11;
        GUI.skin.textField.alignment = TextAnchor.MiddleLeft;

        string instId = obj.GetInstanceID().ToString();
        GUI.SetNextControlName(instId);

        if (editObject != obj)
        {
            EditorGUILayout.TextField(obj.name, GUILayout.MinWidth(nameMinWidth), GUILayout.MaxWidth(nameMaxWidth));
        }
        else
        {
            editName = EditorGUILayout.TextField(editName, GUILayout.MinWidth(nameMinWidth), GUILayout.MaxWidth(nameMaxWidth));
        }

        if (GUI.GetNameOfFocusedControl() == instId)
        {
            if (editObject != obj)
            {
                editName   = obj.name;
                editObject = obj;
            }
        }
        if (Event.current.type == EventType.KeyUp && Event.current.keyCode == KeyCode.Return && editObject == obj)
        {
            obj.name   = editName;
            editName   = "";
            editObject = null;
            Repaint();
        }

        GUILayout.Space(3);

        #if UNITY_3
        EditorGUIUtility.LookLikeControls(5);
        #else
        EditorGUIUtility.labelWidth = 5;
        #endif
        volume.EnterBlendTime = EditorGUILayout.FloatField(" ", volume.EnterBlendTime, GUILayout.MinWidth(blendMinWidth), GUILayout.MaxWidth(blendMaxWidth));

        GUILayout.Space(3);

        volume.Priority = EditorGUILayout.IntField(" ", volume.Priority, GUILayout.MinWidth(priorityMinWidth), GUILayout.MaxWidth(priorityMaxWidth));

        GUILayout.EndHorizontal();
    }
 static string GetEditorPrefsKey(AmplifyColorVolume volume)
 {
     return("AmplifyColor.VolumeEditor.Foldout." + volume.GetHashCode());
 }
 bool SetFoldout(AmplifyColorVolume volume, bool state)
 {
     EditorPrefs.SetBool(GetEditorPrefsKey(volume), state);
     return(state);
 }
	void DrawVolumeEffectFields( AmplifyColorVolume volume )
	{
		List<VolumeEffect> effectsToDelete = new List<VolumeEffect>();
		float removeButtonSize = 16;

		List<NewLineContainer> volumeLines = null;
		if ( !( newLines.TryGetValue( volume, out volumeLines ) ) )
			volumeLines = newLines[ volume ] = new List<NewLineContainer>();

		GUIStyle minusStyle = new GUIStyle( ( GUIStyle ) "OL Minus" );
		GUIStyle plusStyle = new GUIStyle( ( GUIStyle ) "OL Plus" );
		minusStyle.margin.top = 2;
		plusStyle.margin.top = 2;

	#region CurrentEffectFields
		int fieldPosition = 0;
		foreach ( VolumeEffect effectVol in volume.EffectContainer.volumes )
		{
			if ( effectVol.gameObject == null )
				continue;

			AmplifyColorBase effect = effectVol.gameObject;
			List<VolumeEffectComponent> compsToDelete = new List<VolumeEffectComponent>();

			foreach ( VolumeEffectComponent comp in effectVol.components )
			{
				Component c = effect.GetComponent( comp.componentName );
				if ( c == null )
					continue;

				List<VolumeEffectField> fieldsToDelete = new List<VolumeEffectField>();
				List<KeyValuePair<string,int>> fieldsToAdd = new List<KeyValuePair<string,int>>();

				foreach ( VolumeEffectField field in comp.fields )
				{
					EditorGUILayout.BeginHorizontal();
					GUILayout.Label( "", GUILayout.MinWidth( minIndentWidth ), GUILayout.MaxWidth( maxIndentWidth ) );
					GUILayout.Space( 0 );

					if ( GUILayout.Button( "", minusStyle, GUILayout.MinWidth( 18 ), GUILayout.MaxWidth( 18 ), GUILayout.Height( 20 ) ) )
						fieldsToDelete.Add( field );

					Camera selectedCamera = EditorGUILayout.ObjectField( effect.GetComponent<Camera>(), typeof( Camera ), true, GUILayout.MinWidth( minColumnWidth * 1.5f ), GUILayout.MaxWidth( maxColumnWidth * 1.5f ) ) as Camera;
					AmplifyColorBase selectedEffect = ( selectedCamera != null ) ? selectedCamera.GetComponent<AmplifyColorBase>() : null;
					if ( selectedEffect != effect )
					{
						fieldsToDelete.Add( field );
						dirtyVolumeFlags = true;
						volumeLines.Add( new NewLineContainer( selectedEffect ) );
					}

					Component[] compArray = VolumeEffect.ListAcceptableComponents( effectVol.gameObject );
					List<string> compFlagsArray = compArray.Select( s => s.GetType().Name ).ToList();
					compFlagsArray.Remove( comp.componentName );
					string[] compNamesArray = new string[] { comp.componentName }.Concat( compFlagsArray ).ToArray();
					int selectedComponent = 0;
					selectedComponent = EditorGUILayout.Popup( selectedComponent, compNamesArray, GUILayout.MinWidth( minColumnWidth ), GUILayout.MaxWidth( maxColumnWidth ) );
					if ( selectedComponent != 0 )
					{
						volumeLines.Add( new NewLineContainer( effect, compNamesArray[ selectedComponent ] ) );
						fieldsToDelete.Add( field );
						dirtyVolumeFlags = true;
					}

					FieldInfo[] fieldArray = VolumeEffectComponent.ListAcceptableFields( c );
					string[] fieldFlagsArray = fieldArray.Select( s => s.Name ).ToArray();
					string[] fieldNamesArray = comp.GetFieldNames();
					fieldFlagsArray = fieldFlagsArray.Except( fieldNamesArray ).ToArray();

					List<string> names = new List<string>();
					names.Add( field.fieldName );
					names.AddRange( fieldFlagsArray );
					for ( int i = 0; i < names.Count; i++ )
					{
						if ( i == 0 )
							continue;

						FieldInfo fi = Array.Find( fieldArray, s => ( names[ i ] == s.Name ) );
						if ( fi != null )
							names[ i ] += " : " + fi.FieldType.Name;
					}

					int selectedField = 0;
					selectedField = EditorGUILayout.Popup( selectedField, names.ToArray(), GUILayout.MinWidth( minColumnWidth ), GUILayout.MaxWidth( maxColumnWidth ) );
					if ( selectedField != 0 )
					{
						fieldsToAdd.Add( new KeyValuePair<string,int>( fieldFlagsArray[ selectedField - 1 ], fieldPosition ) );
						fieldsToDelete.Add( field );
						dirtyVolumeFlags = true;
					}
					fieldPosition++;

					switch ( field.fieldType )
					{
						case "System.Single": field.valueSingle = EditorGUILayout.FloatField( field.valueSingle, GUILayout.MinWidth( minValueWidth ), GUILayout.MaxWidth( maxValueWidth ) ); break;
						case "System.Boolean": field.valueBoolean = EditorGUILayout.Toggle( "", field.valueBoolean, GUILayout.MinWidth( minValueWidth ), GUILayout.MaxWidth( maxValueWidth ) ); break;
						case "UnityEngine.Vector2": field.valueVector2 = EditorGUILayout.Vector2Field( "", field.valueVector2, GUILayout.MinWidth( minValueWidth ), GUILayout.MaxWidth( maxValueWidth ), GUILayout.MaxHeight( 16 ) ); break;
						case "UnityEngine.Vector3": field.valueVector3 = EditorGUILayout.Vector3Field( "", field.valueVector3, GUILayout.MinWidth( minValueWidth ), GUILayout.MaxWidth( maxValueWidth ), GUILayout.MaxHeight( 16 ) ); break;
						case "UnityEngine.Vector4": field.valueVector4 = DrawFixedVector4Field( field.valueVector4 ); break;
						case "UnityEngine.Color": field.valueColor = EditorGUILayout.ColorField( field.valueColor, GUILayout.MinWidth( minValueWidth ), GUILayout.MaxWidth( maxValueWidth ) ); break;
						default: EditorGUILayout.LabelField( field.fieldType, GUILayout.MinWidth( minValueWidth ), GUILayout.MaxWidth( maxValueWidth ) ); break;
					}

					// COPY TO CLIPBOARD
					string luid = NewLineContainer.GenerateUniqueID( effect, comp.componentName, field.fieldName );
					bool copied = copyLines.ContainsKey( luid );
					bool keep = GUILayout.Toggle( copied, "c", removeButtonStyle, GUILayout.Width( removeButtonSize ), GUILayout.Height( removeButtonSize ) );
					if ( keep != copied )
					{
						if ( keep )
						{
							object valueCopy = null;
							switch ( field.fieldType )
							{
								case "System.Single": valueCopy = field.valueSingle; break;
								case "System.Boolean": valueCopy = field.valueBoolean; break;
								case "UnityEngine.Vector2": valueCopy = field.valueVector2; break;
								case "UnityEngine.Vector3": valueCopy = field.valueVector3; break;
								case "UnityEngine.Vector4": valueCopy = field.valueVector4; break;
								case "UnityEngine.Color": valueCopy = field.valueColor; break;
							}
							copyLines.Add( luid, new NewLineContainer( effect, comp.componentName, field.fieldName, field.fieldType, valueCopy ) );
						}
						else
							copyLines.Remove( luid );

						//Debug.Log( "CopyComplete: " + luid + ", " + keep + ", " + volume.name );
					}

					EditorGUILayout.EndHorizontal();
					GUILayout.Space( 2 );
				}

				bool fieldRemoved = false;
				foreach ( VolumeEffectField field in fieldsToDelete )
				{
					comp.RemoveEffectField( field );
					fieldRemoved = true;
				}

				foreach ( KeyValuePair<string,int> pair in fieldsToAdd )
				{
					FieldInfo pi = c.GetType().GetField( pair.Key);
					if ( pi != null )
						comp.AddField( pi, c, pair.Value );
				}

				if ( fieldRemoved && comp.fields.Count <= 0 )
					compsToDelete.Add( comp );
			}

			bool compRemoved = false;
			foreach ( VolumeEffectComponent comp in compsToDelete )
			{
				effectVol.RemoveEffectComponent( comp );
				compRemoved = true;
			}

			if ( compRemoved && effectVol.components.Count <= 0 )
				effectsToDelete.Add( effectVol );
		}

		foreach ( VolumeEffect effectVol in effectsToDelete )
			volume.EffectContainer.RemoveVolumeEffect( effectVol );
	#endregion CurrentEffectFields

	#region NewLines
		List<NewLineContainer> linesToDelete = new List<NewLineContainer>();
		foreach ( NewLineContainer line in volumeLines )
		{
			EditorGUILayout.BeginHorizontal();
			GUILayout.Label( "", GUILayout.MinWidth( minIndentWidth ), GUILayout.MaxWidth( maxIndentWidth ) );
			GUILayout.Space( 0 );

			if ( GUILayout.Button( "", minusStyle, GUILayout.MinWidth( 18 ), GUILayout.MaxWidth( 18 ), GUILayout.Height( 20 ) ) )
				linesToDelete.Add( line );

			Camera selectedCamera  = EditorGUILayout.ObjectField( line.camera, typeof( Camera ), true, GUILayout.MinWidth( minColumnWidth * 1.5f ), GUILayout.MaxWidth( maxColumnWidth * 1.5f ) ) as Camera;
			AmplifyColorBase selectedEffect = ( selectedCamera != null ) ? selectedCamera.GetComponent<AmplifyColorBase>() : null;
			if ( selectedEffect != null && selectedEffect != line.camera )
				line.SetCamera( selectedEffect );

			VolumeEffect effectVol = null;
			if ( line.camera != null )
				effectVol = volume.EffectContainer.GetVolumeEffect( line.camera );

			if ( line.camera != null )
			{
				Component[] compArray = VolumeEffect.ListAcceptableComponents( line.camera );
				List<string> names = compArray.Select( s => s.GetType().Name ).ToList<string>();
				int popupSelected = names.IndexOf( line.component ) + 1;
				names.Insert( 0, "<Component>" );
				int selectedComponent = popupSelected;
				selectedComponent = EditorGUILayout.Popup( selectedComponent, names.ToArray(), GUILayout.MinWidth( minColumnWidth ), GUILayout.MaxWidth( maxColumnWidth ) );
				if ( selectedComponent != popupSelected )
					line.SetComponent( selectedComponent == 0 ? null : names[ selectedComponent ] );
			}
			else
			{
				GUI.enabled = false;
				EditorGUILayout.Popup( 0, new string[] { "<Component>" }, GUILayout.MaxWidth( maxColumnWidth ) );
				GUI.enabled = true;
			}

			Component c = ( line.camera == null ) ? null : line.camera.GetComponent( line.component );

			VolumeEffectComponent comp = null;
			if ( effectVol != null )
				comp = effectVol.GetEffectComponent( line.component );

			if ( c != null )
			{
				FieldInfo[] fieldArray = VolumeEffectComponent.ListAcceptableFields( c );
				string[] fieldFlagsArray = fieldArray.Select( s => s.Name ).ToArray();
				if ( comp != null )
				{
					string[] fieldNamesArray = comp.GetFieldNames();
					fieldFlagsArray = fieldFlagsArray.Except( fieldNamesArray ).ToArray();
				}

				List<string> names = fieldFlagsArray.ToList();
				for ( int i = 0; i < names.Count; i++ )
				{
					FieldInfo fi = Array.Find( fieldArray, s => ( names[ i ] == s.Name ) );
					if ( fi != null )
						names[ i ] += " : " + fi.FieldType.Name;
				}
				names.Insert( 0, "<Field>" );

				int selectedField = 0;
				selectedField = EditorGUILayout.Popup( selectedField, names.ToArray(), GUILayout.MinWidth( minColumnWidth ), GUILayout.MaxWidth( maxColumnWidth ) );
				if ( selectedField > 0 )
				{
					FieldInfo pi = c.GetType().GetField( fieldFlagsArray[ selectedField - 1 ] );
					if ( pi != null )
					{
						if ( effectVol == null )
							effectVol = volume.EffectContainer.AddJustColorEffect( line.camera );

						if ( comp == null )
							comp = effectVol.AddComponent( c, null );

						comp.AddField( pi, c );
						linesToDelete.Add( line );
						dirtyVolumeFlags = true;
					}
				}

				EditorGUILayout.LabelField( "", GUILayout.MinWidth( minValueWidth ), GUILayout.MaxWidth( maxValueWidth ) );
			}
			else
			{
				GUI.enabled = false;
				EditorGUILayout.Popup( 0, new string[] { "<Field>" }, GUILayout.MaxWidth( maxColumnWidth ) );
				EditorGUILayout.TextField( "", GUILayout.MinWidth( minValueWidth ), GUILayout.MaxWidth( maxValueWidth ) );
				GUI.enabled = true;
			}

			if ( line.camera != null )
			{
				string luid = NewLineContainer.GenerateUniqueID( line.camera, line.component, line.fieldName );
				bool copied = copyLines.ContainsKey( luid );
				bool keep = GUILayout.Toggle( copied, "c", removeButtonStyle, GUILayout.Width( removeButtonSize ), GUILayout.Height( removeButtonSize ) );
				if ( keep != copied )
				{
					if ( keep )
						copyLines.Add( luid, new NewLineContainer( line.camera, line.component, line.fieldName, line.fieldType, line.value ) );
					else
						copyLines.Remove( luid );

					//Debug.Log( "CopyIncomplete: " + luid + ", " + keep + ", " + volume.name );
				}
			}
			else
			{
				GUI.enabled = false;
				GUILayout.Button( "c", removeButtonStyle, GUILayout.Width( removeButtonSize ), GUILayout.Height( removeButtonSize ) );
				GUI.enabled = true;
			}

			EditorGUILayout.EndHorizontal();
			GUILayout.Space( 2 );
		}

		foreach ( NewLineContainer line in linesToDelete )
		{
			copyLines.Remove( line.GenerateUniqueID() );
			//Debug.Log( "Removed " + line.GenerateUniqueID() );
			volumeLines.Remove( line );
		}
	#endregion NewLines

	#region AddPaste
		EditorGUILayout.BeginHorizontal();
		GUILayout.Label( "", GUILayout.MinWidth( minIndentWidth ), GUILayout.MaxWidth( maxIndentWidth ) );
		GUILayout.Space( 0 );

		bool add = GUILayout.Button( "", plusStyle, GUILayout.MinWidth( 18 ), GUILayout.MaxWidth( 18 ), GUILayout.Height( 20 ) );
		if ( add || GUILayout.Button( "Add New", GUILayout.MinWidth( minColumnWidth ), GUILayout.MaxWidth( maxColumnWidth ), GUILayout.Height( 20 ) ) )
			volumeLines.Add( new NewLineContainer() );

		GUI.enabled = ( copyLines.Count > 0 );
		if ( GUILayout.Button( "Paste", GUILayout.MinWidth( minColumnWidth ), GUILayout.MaxWidth( maxColumnWidth ), GUILayout.Height( 20 ) ) )
		{
			foreach ( var pair in copyLines )
			{
				NewLineContainer line = pair.Value;
				Component c = ( line.camera == null ) ? null : line.camera.GetComponent( line.component );
				FieldInfo pi = ( c != null ) ? c.GetType().GetField( line.fieldName ) : null;

				if ( pi == null )
					volumeLines.Add( new NewLineContainer( line.camera, line.component, line.fieldName, line.fieldType, line.value ) );
				else
				{
					VolumeEffect effectVol = volume.EffectContainer.GetVolumeEffect( line.camera );
					if ( effectVol == null )
						effectVol = volume.EffectContainer.AddJustColorEffect( line.camera );

					VolumeEffectComponent comp = effectVol.GetEffectComponent( line.component );
					if ( comp == null )
						comp = effectVol.AddComponent( c, null );

					VolumeEffectField field = comp.GetEffectField( line.fieldName );
					if ( field == null )
						field = comp.AddField( pi, c );
					else
						Debug.LogWarning( "[AmplifyColor] Blend Effect field already added to Volume " + volume.name + "." );

					field.UpdateValue( line.value );
				}
			}

			dirtyVolumeFlags = true;
		}
		GUI.enabled = true;

		EditorGUILayout.EndHorizontal();
		GUILayout.Space( 5 );
	#endregion AddPaste
	}
	void DrawLut( AmplifyColorVolume volume )
	{
		GUILayout.Space( 0 );
		volume.LutTexture = ( Texture2D ) EditorGUILayout.ObjectField( volume.LutTexture, typeof( Texture2D ), false, GUILayout.Width( lutWidth ), GUILayout.Height( lutWidth ) );
		GUILayout.FlexibleSpace();
		GUILayout.Space( 5 );
	}
	void DrawVolumeEffects( AmplifyColorVolume volume )
	{
		GUIStyle layerTitleStyle = new GUIStyle( EditorStyles.miniBoldLabel );
		layerTitleStyle.alignment = TextAnchor.MiddleLeft;
		layerTitleStyle.margin = new RectOffset( 0, 0, 0, 0 );

		GUIStyle foldoutTitleStyle = new GUIStyle( EditorStyles.foldout );
		foldoutTitleStyle.fontSize = 10;

		GUILayout.BeginHorizontal();
		GUILayout.Space( 10 );
		GUILayout.Label( "", GUILayout.MinWidth( iconMinWidth ), GUILayout.MaxWidth( iconMaxWidth - 10 ) );
		GUILayout.Space( 2 );

		GUILayout.BeginVertical();
		GUILayout.Space( 0 );

		GUILayout.BeginHorizontal();
		bool foldout = SetFoldout( volume, EditorGUILayout.Foldout( GetFoldout( volume ), "Blend Effects", foldoutTitleStyle ) );
		GUILayout.EndHorizontal();

		GUILayout.Space( 3 );

		if ( foldout )
			DrawVolumeEffectFields( volume );

		GUILayout.EndVertical();

		GUILayout.Space( 0 );
		GUILayout.EndHorizontal();
	}
	void DrawVolumeProperties( AmplifyColorVolume volume )
	{
		GameObject obj = volume.gameObject;

		GUILayout.BeginHorizontal();
		GUILayout.Space( 10 );

		volumeIcon = ( volumeIcon == null ) ? Resources.Load( "volume-icon", typeof( Texture2D ) ) as Texture2D : volumeIcon;
		GUILayout.Label( volumeIcon, GUILayout.MinWidth( iconMinWidth ), GUILayout.MaxWidth( iconMaxWidth ) );

		GUILayout.Space( 0 );

	#if UNITY_3
		bool active = obj.active;
	#else
		bool active = obj.activeInHierarchy;
	#endif
		bool keep = EditorGUILayout.Toggle( active, GUILayout.MinWidth( activeMinWidth ), GUILayout.MaxWidth( activeMaxWidth ) );
		if ( keep != active )
		{
		#if UNITY_3
			obj.active = keep;
		#else
			obj.SetActive( keep );
		#endif
		}

		GUILayout.Space( 6 );

		volume.ShowInSceneView = EditorGUILayout.Toggle( volume.ShowInSceneView, GUILayout.MinWidth( visibleMinWidth ), GUILayout.MaxWidth( visibleMaxWidth ) );

		GUILayout.Space( 6 );

		GUI.skin.textField.fontSize = 10;
		GUI.skin.textField.alignment = TextAnchor.UpperCenter;
		if ( GUILayout.Button( ( Selection.activeObject == obj ) ? "●" : "", EditorStyles.textField, GUILayout.Width( 16 ), GUILayout.Height( 16 ) ) )
			Selection.activeObject = ( Selection.activeObject == obj ) ? null : obj;

		GUILayout.Space( 0 );

		GUI.skin.textField.fontSize = 11;
		GUI.skin.textField.alignment = TextAnchor.MiddleLeft;

		string instId = obj.GetInstanceID().ToString();
		GUI.SetNextControlName( instId );

		if ( editObject != obj )
			EditorGUILayout.TextField( obj.name, GUILayout.MinWidth( nameMinWidth ), GUILayout.MaxWidth( nameMaxWidth ) );
		else
			editName = EditorGUILayout.TextField( editName, GUILayout.MinWidth( nameMinWidth ), GUILayout.MaxWidth( nameMaxWidth ) );

		if ( GUI.GetNameOfFocusedControl() == instId )
		{
			if ( editObject != obj )
			{
				editName = obj.name;
				editObject = obj;
			}
		}
		if ( Event.current.type == EventType.KeyUp && Event.current.keyCode == KeyCode.Return && editObject == obj )
		{
			obj.name = editName;
			editName = "";
			editObject = null;
			Repaint();
		}

		GUILayout.Space( 3 );

	#if UNITY_3
		EditorGUIUtility.LookLikeControls( 5 );
	#else
		EditorGUIUtility.labelWidth = 5;
	#endif
		volume.EnterBlendTime = EditorGUILayout.FloatField( " ", volume.EnterBlendTime, GUILayout.MinWidth( blendMinWidth ), GUILayout.MaxWidth( blendMaxWidth ) );

		GUILayout.Space( 3 );

		volume.Priority = EditorGUILayout.IntField( " ", volume.Priority, GUILayout.MinWidth( priorityMinWidth ), GUILayout.MaxWidth( priorityMaxWidth ) );

		GUILayout.EndHorizontal();
	}
	bool GetFoldout( AmplifyColorVolume volume )
	{
		string key = GetEditorPrefsKey( volume );
		if ( !EditorPrefs.HasKey( key ) )
			EditorPrefs.SetBool( key, false );
		return EditorPrefs.GetBool( key );
	}
	bool SetFoldout( AmplifyColorVolume volume, bool state )
	{
		EditorPrefs.SetBool( GetEditorPrefsKey( volume ), state );
		return state;
	}
	static string GetEditorPrefsKey( AmplifyColorVolume volume )
	{
		return "AmplifyColor.VolumeEditor.Foldout." + volume.GetHashCode();
	}