using System;

#if UNITY_EDITOR
using NodeCanvas.Editor;
#endif

using NodeCanvas.Framework;
using ParadoxNotion.Design;
using UnityEditor;
using UnityEngine;

namespace Reset.Core{
	// Individual bool setting for each ring. Three of these will be used. 
	public struct OrbitalFollowValueGroup{
		public string label;
		
		public ValueChangeAction changeHeight;
		public float height;
		
		public ValueChangeAction changeRadius;
		public float radius;

		public OrbitalFollowValueGroup(string newLabel){
			label = newLabel;
			changeHeight = ValueChangeAction.NoChange;
			height = 0f;
			changeRadius = ValueChangeAction.NoChange;
			radius = 0f;
		}
	}

	// Enum options for individual camera settings
	public enum ValueChangeAction{
		NoChange,
		NewValue,
		ResetValue,
		RelativeValue, // Placeholder for using as altering existing value
	}

	public struct CurveValueGroup{
		public string label;
		public AnimationCurve newValue;

		public ValueChangeAction changeValue;

		public CurveValueGroup(string newLabel){
			changeValue = ValueChangeAction.NoChange;

			newValue = new AnimationCurve();
			label = newLabel;
		}
	}

	public struct EnumValueGroup{
		public string label;
		public Enum newValue;

		public ValueChangeAction changeValue;

		public EnumValueGroup(string newLabel, Enum enumType){
			changeValue = ValueChangeAction.NoChange;

			newValue = enumType;
			label = newLabel;


		}
	}

	public struct Vector3ValueGroup{
		public string label;
		public Vector3 newValue;
		
		public ValueChangeAction changeX;
		public ValueChangeAction changeY;
		public ValueChangeAction changeZ;
		
		public Vector3ValueGroup(string newLabel){
			changeX = ValueChangeAction.NoChange;
			changeY = ValueChangeAction.NoChange;
			changeZ = ValueChangeAction.NoChange;

			newValue = Vector3.zero;
			label = newLabel;
		}
	}

	public struct Vector2ValueGroup{
		public string label;
		public Vector2 newValue;
		
		public ValueChangeAction changeX;
		public ValueChangeAction changeY;
		
		public Vector2ValueGroup(string newLabel){
			changeX = ValueChangeAction.NoChange;
			changeY = ValueChangeAction.NoChange;

			newValue = Vector2.zero;
			label = newLabel;
		}
	}

	public struct FloatValueGroup{
		public string label;
		// public float value;
		public BBParameter<float> value;

		public ValueChangeAction changeValue;

		public FloatValueGroup(string newLabel){
			label = newLabel;
			value = new BBParameter<float>().value = 0f;
			changeValue = ValueChangeAction.NoChange;
		}
	}

	public struct BoolValueGroup{
		public string label;
		public bool value;

		public ValueChangeAction changeValue;

		public BoolValueGroup(string newLabel){
			label = newLabel;
			value = true;
			changeValue = ValueChangeAction.NoChange;
		}
	}

#if UNITY_EDITOR
	public class BoolValueGroupDrawer : ObjectDrawer<BoolValueGroup>  {
		public override BoolValueGroup OnGUI(GUIContent _content, BoolValueGroup _instance){
			// Remove label for floats
			EditorGUIUtility.labelWidth = 50;
			
			// Set layout options for the label and the float fields
			GUILayoutOption[] floatOptions = new GUILayoutOption[] {
				GUILayout.Width(80.0f), 
				GUILayout.MinWidth(20.0f), 
				GUILayout.ExpandWidth(true), 
			};

			GUILayoutOption[] labelOptions = new GUILayoutOption[]{
				GUILayout.Width(200.0f),
			};
			
			// Start the Vertical layout then add the label before adding a horizontal so the label will be on top of side-by-side options
			GUILayout.BeginVertical();
			GUILayout.Label(_instance.label, labelOptions);
			GUILayout.BeginHorizontal();
			
			// Create the x settings enum
			_instance.changeValue = (ValueChangeAction)EditorGUILayout.EnumPopup("", instance.changeValue);
			
			// Create the value/disabled information field
			if (_instance.changeValue == ValueChangeAction.NewValue){
				_instance.value = EditorGUILayout.Toggle(_instance.value, floatOptions);
			} else {
				EditorGUI.BeginDisabledGroup(true);
				EditorGUILayout.TextField(_instance.changeValue == ValueChangeAction.NoChange ? "Unchanged" : "Reset", floatOptions);
				EditorGUI.EndDisabledGroup();
			}
			
			// Close this line up
			GUILayout.EndHorizontal();
			GUILayout.EndVertical();
			
			// Reset to default so the rest of things don't get messed up
			EditorGUIUtility.labelWidth = 0;
			return _instance;
		}
	}
	
	public class CurveVlueGroupDrawer : ObjectDrawer<CurveValueGroup>  {
		public override CurveValueGroup OnGUI(GUIContent _content, CurveValueGroup _instance){
			// Remove label for floats
			EditorGUIUtility.labelWidth = 50;
			
			// Set layout options for the label and the float fields
			GUILayoutOption[] floatOptions = new GUILayoutOption[] {
				GUILayout.Width(80.0f), 
				GUILayout.MinWidth(20.0f), 
				GUILayout.ExpandWidth(true), 
			};

			GUILayoutOption[] labelOptions = new GUILayoutOption[]{
				GUILayout.Width(200.0f),
			};
			
			// Start the Vertical layout then add the label before adding a horizontal so the label will be on top of side-by-side options
			GUILayout.BeginVertical();
			GUILayout.Label(_instance.label, labelOptions);
			GUILayout.BeginHorizontal();
			
			// Create the x settings enum
			_instance.changeValue = (ValueChangeAction)EditorGUILayout.EnumPopup("", instance.changeValue);
			
			// Create the value/disabled information field
			if (_instance.changeValue == ValueChangeAction.NewValue){
				_instance.newValue = EditorGUILayout.CurveField(_instance.newValue, floatOptions);
			} else {
				EditorGUI.BeginDisabledGroup(true);
				EditorGUILayout.TextField(_instance.changeValue == ValueChangeAction.NoChange ? "Unchanged" : "Reset", floatOptions);
				EditorGUI.EndDisabledGroup();
			}
			
			// Close this line up
			GUILayout.EndHorizontal();
			GUILayout.EndVertical();
			
			// Reset to default so the rest of things don't get messed up
			EditorGUIUtility.labelWidth = 0;
			return _instance;
		}
	}

	public class EnumValueGroupDrawer : ObjectDrawer<EnumValueGroup>{
		public override EnumValueGroup OnGUI(GUIContent _content, EnumValueGroup _instance){
			// Set layout options for the label and the float fields
			GUILayoutOption[] floatOptions = new GUILayoutOption[] {
				GUILayout.Width(200.0f), 
				GUILayout.MinWidth(100.0f), 
				GUILayout.ExpandWidth(true), 
			};

			GUILayoutOption[] labelOptions = new GUILayoutOption[]{
				GUILayout.Width(200.0f),
			};
			
			// Start the Vertical layout then add the label before adding a horizontal so the label will be on top of side-by-side options
			GUILayout.BeginVertical();
			GUILayout.Label(_instance.label, labelOptions);
			GUILayout.BeginHorizontal();
			
			// Create the x settings enum
			_instance.changeValue = (ValueChangeAction)EditorGUILayout.EnumPopup("", instance.changeValue);
			
			// Create the value/disabled information field
			if (_instance.changeValue == ValueChangeAction.NewValue){
				_instance.newValue = EditorGUILayout.EnumPopup("", instance.newValue, floatOptions);
			} else {
				EditorGUI.BeginDisabledGroup(true);
				EditorGUILayout.TextField(_instance.changeValue == ValueChangeAction.NoChange ? "Unchanged" : "Reset", floatOptions);
				EditorGUI.EndDisabledGroup();
			}
			
			// Close this line up
			GUILayout.EndHorizontal();
			GUILayout.EndVertical();
			
			// Reset to default so the rest of things don't get messed up
			EditorGUIUtility.labelWidth = 0;
			return _instance;
		}

		
	}

	public class FloatValueGroupDrawer : ObjectDrawer<FloatValueGroup>  {
		public override FloatValueGroup OnGUI(GUIContent _content, FloatValueGroup _instance){
			// Remove label for floats
			EditorGUIUtility.labelWidth = 50;
			
			// Set layout options for the label and the float fields
			GUILayoutOption[] floatOptions = new GUILayoutOption[] {
				GUILayout.Width(80.0f), 
				GUILayout.MinWidth(20.0f), 
				GUILayout.ExpandWidth(true), 
			};

			GUILayoutOption[] labelOptions = new GUILayoutOption[]{
				GUILayout.Width(200.0f),
			};
			
			// Start the Vertical layout then add the label before adding a horizontal so the label will be on top of side-by-side options
			GUILayout.BeginVertical();
			GUILayout.Label(_instance.label, labelOptions);
			GUILayout.BeginHorizontal();
			
			// Create the x settings enum
			_instance.changeValue = (ValueChangeAction)EditorGUILayout.EnumPopup("", instance.changeValue);
			
			
			// Create the value/disabled information field
			if (_instance.changeValue == ValueChangeAction.NewValue){
				// _instance.value = EditorGUILayout.FloatField(_instance.value, floatOptions);
				BBParameterEditor.ParameterField("", _instance.value);
			} else {
				EditorGUI.BeginDisabledGroup(true);
				EditorGUILayout.TextField(_instance.changeValue == ValueChangeAction.NoChange ? "Unchanged" : "Reset", floatOptions);
				EditorGUI.EndDisabledGroup();
			}
			
			// Close this line up
			GUILayout.EndHorizontal();
			GUILayout.EndVertical();
			
			// Reset to default so the rest of things don't get messed up
			EditorGUIUtility.labelWidth = 0;
			return _instance;
		}
	}

	public class Vector3ValueGroupDrawer : ObjectDrawer<Vector3ValueGroup>  {
		public override Vector3ValueGroup OnGUI(GUIContent _content, Vector3ValueGroup _instance){
			// Remove label for floats
			EditorGUIUtility.labelWidth = 20;
			
			// Set layout options for the label and the float fields
			GUILayoutOption[] floatOptions = new GUILayoutOption[] {
				GUILayout.Width(300.0f), 
				GUILayout.MinWidth(20.0f), 
				GUILayout.ExpandWidth(true), 
			};

			GUILayoutOption[] labelOptions = new GUILayoutOption[]{
				GUILayout.Width(200.0f),
			};
			
			// Start the Vertical layout then add the label before adding a horizontal so the label will be on top of side-by-side options
			GUILayout.BeginVertical();
			GUILayout.Label(_instance.label, labelOptions);
			GUILayout.BeginHorizontal();
			
			// Create the x settings enum
			_instance.changeX = (ValueChangeAction)EditorGUILayout.EnumPopup("", instance.changeX);
			
			// Create the value/disabled information field
			if (_instance.changeX == ValueChangeAction.NewValue){
				_instance.newValue.x = EditorGUILayout.FloatField(_instance.newValue.x, floatOptions);
			} else {
				EditorGUI.BeginDisabledGroup(true);
				EditorGUILayout.TextField(_instance.changeX == ValueChangeAction.NoChange ? "Unchanged" : "Reset", floatOptions);
				EditorGUI.EndDisabledGroup();
			}
			  
			// It do what it do.
			GUILayout.Space(5);
			
			// Create the y settings enum
			_instance.changeY = (ValueChangeAction)EditorGUILayout.EnumPopup("", _instance.changeY);
			
			// Create the value/disabled information field
			if (_instance.changeY == ValueChangeAction.NewValue){
				_instance.newValue.y = EditorGUILayout.FloatField(_instance.newValue.y, floatOptions);
			} else {
				EditorGUI.BeginDisabledGroup(true);
				EditorGUILayout.TextField(_instance.changeY == ValueChangeAction.NoChange ? "Unchanged" : "Reset", floatOptions);
				EditorGUI.EndDisabledGroup();
			}
			
			// It do what it do.
			GUILayout.Space(5);
			
			// Create the y settings enum
			_instance.changeZ = (ValueChangeAction)EditorGUILayout.EnumPopup("", _instance.changeZ);
			
			// Create the value/disabled information field
			if (_instance.changeZ == ValueChangeAction.NewValue){
				_instance.newValue.z = EditorGUILayout.FloatField(_instance.newValue.z, floatOptions);
			} else {
				EditorGUI.BeginDisabledGroup(true);
				EditorGUILayout.TextField(_instance.changeZ == ValueChangeAction.NoChange ? "Unchanged" : "Reset", floatOptions);
				EditorGUI.EndDisabledGroup();
			}
			
			// Close this line up
			GUILayout.EndHorizontal();
			GUILayout.EndVertical();
			
			// Reset to default so the rest of things don't get messed up
			EditorGUIUtility.labelWidth = 0;
			return _instance;
		}
	}

	public class Vector2ValueGroupDrawer : ObjectDrawer<Vector2ValueGroup>  {
		public override Vector2ValueGroup OnGUI(GUIContent _content, Vector2ValueGroup _instance){
			// Remove label for floats
			EditorGUIUtility.labelWidth = 50;
			
			// Set layout options for the label and the float fields
			GUILayoutOption[] floatOptions = new GUILayoutOption[] {
				GUILayout.Width(300.0f), 
				GUILayout.MinWidth(20.0f), 
				GUILayout.ExpandWidth(true), 
			};

			GUILayoutOption[] labelOptions = new GUILayoutOption[]{
				GUILayout.Width(200.0f),
			};
			
			// Start the Vertical layout then add the label before adding a horizontal so the label will be on top of side-by-side options
			GUILayout.BeginVertical();
			GUILayout.Label(_instance.label, labelOptions);
			GUILayout.BeginHorizontal();
			
			// Create the x settings enum
			_instance.changeX = (ValueChangeAction)EditorGUILayout.EnumPopup("", instance.changeX);
			
			// Create the value/disabled information field
			if (_instance.changeX == ValueChangeAction.NewValue){
				_instance.newValue.x = EditorGUILayout.FloatField(_instance.newValue.x, floatOptions);
			} else {
				EditorGUI.BeginDisabledGroup(true);
				EditorGUILayout.TextField(_instance.changeX == ValueChangeAction.NoChange ? "Unchanged" : "Reset", floatOptions);
				EditorGUI.EndDisabledGroup();
			}
			  
			// It do what it do.
			GUILayout.Space(5);
			
			// Create the y settings enum
			_instance.changeY = (ValueChangeAction)EditorGUILayout.EnumPopup("", _instance.changeY);
			
			// Create the value/disabled information field
			if (_instance.changeY == ValueChangeAction.NewValue){
				_instance.newValue.y = EditorGUILayout.FloatField(_instance.newValue.y, floatOptions);
			} else {
				EditorGUI.BeginDisabledGroup(true);
				EditorGUILayout.TextField(_instance.changeY == ValueChangeAction.NoChange ? "Unchanged" : "Reset", floatOptions);
				EditorGUI.EndDisabledGroup();
			}
			
			// Close this line up
			GUILayout.EndHorizontal();
			GUILayout.EndVertical();
			
			// Reset to default so the rest of things don't get messed up
			EditorGUIUtility.labelWidth = 0;
			return _instance;
		}
	}

	// Custom editor for each orbital follow ring setting
	public class OrbitalFollowValueGroupDrawer : ObjectDrawer<OrbitalFollowValueGroup>{
		public override OrbitalFollowValueGroup OnGUI(GUIContent _content, OrbitalFollowValueGroup _instance){
			// Remove label for floats
			EditorGUIUtility.labelWidth = 1;
			
			// Set layout options for the label and the float fields
			GUILayoutOption[] floatOptions = new GUILayoutOption[] {
				GUILayout.Width(300.0f), 
				GUILayout.MinWidth(20.0f), 
				GUILayout.ExpandWidth(true), 
			};

			GUILayoutOption[] labelOptions = new GUILayoutOption[]{
				GUILayout.Width(60.0f),
			};
			
			// Start a Horiztonal Section
			GUILayout.BeginHorizontal();
			
			// Add the left side label
			GUILayout.Label(_instance.label, labelOptions);
			
			// Create the height settings enum
			_instance.changeHeight = (ValueChangeAction)EditorGUILayout.EnumPopup("", _instance.changeHeight);
			
			// Create the value/disabled information field
			if (_instance.changeHeight == ValueChangeAction.NewValue){
				_instance.height = EditorGUILayout.FloatField(_instance.height, floatOptions);
			} else {
				EditorGUI.BeginDisabledGroup(true);
				EditorGUILayout.TextField(_instance.changeHeight == ValueChangeAction.NoChange ? "Unchanged" : "Reset", floatOptions);
				EditorGUI.EndDisabledGroup();
			}
			  
			// It do what it do.
			GUILayout.Space(5);
			
			// Create the radius settings enum
			_instance.changeRadius = (ValueChangeAction)EditorGUILayout.EnumPopup("", _instance.changeRadius);
			
			// Create the value/disabled information field
			if (_instance.changeRadius == ValueChangeAction.NewValue){
				_instance.radius = EditorGUILayout.FloatField(_instance.radius, floatOptions);
			} else {
				EditorGUI.BeginDisabledGroup(true);
				EditorGUILayout.TextField(_instance.changeRadius == ValueChangeAction.NoChange ? "Unchanged" : "Reset", floatOptions);
				EditorGUI.EndDisabledGroup();
			}
			
			// Close this line up
			GUILayout.EndHorizontal();
			
			// Reset to default so the rest of things don't get messed up
			EditorGUIUtility.labelWidth = 0;
			return _instance;
		}
	}
#endif

}
