class_name StateModifierMovement
extends StateModifier

#export(float, -1.0, 1, 1.0) var applied_direction = 0

#export (Transform2D) var speed = Transform2D(Vector2(0,0),Vector2(0,0),Vector2(0,0))
#export(float, EXP, -1, 1, .1) var jerk_offset = 0
## Processing Directives (help determine how the merge function works)
enum APPLIED_DIRECTIONS {
	LEFT_OR_UP = -1,
	RELATIVE = 0,
	RIGHT_OR_DOWN = 1
}
export(APPLIED_DIRECTIONS) var direction :float = float(APPLIED_DIRECTIONS.RELATIVE) # -1, 0, 1

export(Vector2) var speed_start
export(Vector2) var speed_end
export(Vector2) var acceleration

## Movement Modifiers
#export var horizontal_speed: float = 0
#export var horizontal_acceleration: float = 0
### Movement Speed Offsets (Positive or Negative)
#export var horizontal_speed_offset: float = 0
### Applies only if offset applies
#export var horizontal_speed_offset_acceleration: float = 0
##export var jerk_factor: float = 0
#
#export var vertical_speed: float = 0
#export var vertical_acceleration: float = 0
### Movement Speed Offsets (Positive or Negative)
#export var vertical_speed_offset: float = 0
### Applies only if offset applies
#export var vertical_speed_offset_acceleration: float = 0

export var gravity: int = 0

export var only_grounded :bool = false

## Ways to determine how modifiers are applied to movement parameters
enum SUB_TYPE {
	NONE, 			# Basic physics modifier just adds numbers
	## Disallows ability to surpass zero when applied to state kinematic values
	NEGATIVE_CONSTRAINT,
	ONLY_ON_ZERO
}
export(SUB_TYPE) var processing_mode

func _to_string():
	return "StateModifierMovement"

func reset():
	.reset()
	modifier_type = SUB_TYPE.NONE
#	direction = 0.0
#	horizontal_speed = 0
#	horizontal_acceleration = 0
#	## Movement Speed Offsets (Positive or Negative)
#	horizontal_speed_offset = 0
#	## Applies only if offset applies
#	horizontal_speed_offset_acceleration = 0
	#jerk_factor = 0

func copy(_copy_state: StateModifier):
	.copy(_copy_state)
	modifier_type = _copy_state.modifier_type
	if _copy_state.to_string() == "StateModifierMovement":
		#_copy_state.horizontal_speed = horizontal_speed
		_copy_state.speed.start = speed_start
		_copy_state.speed_end = speed_end
		#_copy_state.horizontal_acceleration = horizontal_acceleration
		_copy_state.acceleration = acceleration

## Overrident to check whether this state is a grounded and this modifier 
## should only apply while in the air.
func status_check_1(condition :bool) -> bool:
	var is_grounded :bool = condition
	if only_grounded == true and is_grounded == false:
		return false
	else:
		return true 


func merge(_merge_from_modifier: StateModifier):
	.merge(_merge_from_modifier)
	is_active = _merge_from_modifier.is_active
	if modifier_type != SUB_TYPE.NONE and _merge_from_modifier.modifier_type != SUB_TYPE.NONE:
		push_warning( "Attempt to push modifier type over existing one. Wut du?" )
	if _merge_from_modifier.to_string() == "StateModifierMovement":
		if modifier_type == SUB_TYPE.NONE and _merge_from_modifier.modifier_type != SUB_TYPE.NONE:
			modifier_type = _merge_from_modifier.modifier_type

		##TODO: I don't really need merge functions here? 
		match _merge_from_modifier.modifier_type:
			_:
				speed_end += _merge_from_modifier.speed_end
				speed_start += _merge_from_modifier.speed_start
				acceleration += _merge_from_modifier.acceleration
				
#				horizontal_speed += _merge_from_modifier.horizontal_speed
#				horizontal_acceleration += _merge_from_modifier.horizontal_acceleration
#				horizontal_speed_offset += _merge_from_modifier.horizontal_speed_offset
#				horizontal_speed_offset_acceleration += _merge_from_modifier.horizontal_speed_offset_acceleration
#				vertical_speed += _merge_from_modifier.vertical_speed
#				vertical_acceleration += _merge_from_modifier.vertical_acceleration
#				vertical_speed_offset += _merge_from_modifier.vertical_speed_offset
#				vertical_speed_offset_acceleration += _merge_from_modifier.vertical_speed_offset_acceleration
				direction = _merge_from_modifier.direction
				only_grounded = _merge_from_modifier.only_grounded
