extends KinematicBody

const MOTION_INTERPOLATE_SPEED = 10

var orientation = Transform()
var fixup = Transform()
var root_motion = Transform()
var motion = Vector2()
var motion_target = Vector2()
var velocity = Vector3()
var disable_gravity = false
const p1 = "parameters/main/playback"
const p2 = "parameters/main/Motion/playback"


func _ready():
#	var ap = $AnimationTree.get_node($AnimationTree.get_animation_player())
	orientation = global_transform
	orientation.origin = Vector3()
	add_to_group("characters")
	do_ungrab()

func _physics_process(delta):
#	motion = motion.linear_interpolate(motion_target, MOTION_INTERPOLATE_SPEED * delta)
	assert(has_meta("grabbed"))
	var in_smart_obj = get_meta("smart_object")
	if get_meta("grabbed"):
		orientation.basis = get_parent().global_transform.basis
	root_motion = $AnimationTree.get_root_motion_transform()
	orientation *= root_motion
	var h_velocity = orientation.origin / delta
	velocity.x = h_velocity.x
	velocity.z = h_velocity.z
	velocity.y = h_velocity.y
	if !get_meta("grabbed") && !in_smart_obj && !disable_gravity:
		velocity.y += -9.8
	velocity = move_and_slide(velocity,Vector3(0,1,0))
	orientation.origin = Vector3()
	fixup.origin = Vector3()
	orientation *= Transform().interpolate_with(fixup, delta)
	orientation = orientation.orthonormalized()
	global_transform.basis = orientation.basis
	if get_meta("grabbed"):
		global_transform.origin = get_parent().global_transform.origin
#		global_transform = get_parent().global_transform
	if attacking >= 0.0:
		attacking -= delta
	rpg.update_stats(self)
	rpg.update_needs(self)
var skel
func get_skeleton():
	if skel:
		return get_node(skel)
	var queue = [self]
	while queue.size() > 0:
		var item = queue.pop_front()
		if item is Skeleton:
			skel = get_path_to(item)
			return get_node(skel)
		for k in item.get_children():
			queue.push_back(k)
func get_anim_player():
	return $female_2018/female_2018/AnimationPlayer
var attachment_start
var attachment_end
var mod_p = false
func get_front_neck_target():
	if !mod_p:
		$female_2018/female_2018/neck02BoneAttachment/front_neck_target.transform.basis = Basis()
		mod_p = true
	return $female_2018/female_2018/neck02BoneAttachment/front_neck_target
func add_attachment(bname, xform):
	var ba: BoneAttachment = BoneAttachment.new()
	ba.bone_name = bname
	var sk = get_skeleton()
	sk.add_child(ba)
	var on1 = Spatial.new()
	ba.add_child(on1)
	var on2 = Spatial.new()
	ba.add_child(on2)
	on1.transform = Transform()
#	on1.global_transform.basis = Basis()
	on2.transform = xform
#	on2.rotate_y(PI)
	attachment_start = ba
	attachment_end = on2
	return on2

static func calc_offset(c2, bone2):
	var skel2 = c2.get_skeleton()
	var id2 = skel2.find_bone(bone2)
	assert(skel2 != null)
	assert(id2 >= 0)
	var offt2 = skel2.get_bone_global_pose(id2).origin
	var offset = Vector3(-offt2.x, -offt2.y, -offt2.z)
#	print("offset: ", offset)
	return offset

var act = {
	"stop":[
		["travel", p1, "Motion"],
		["travel", p2, "stand"],
	],
	"walk":[
		["travel", p1, "Motion"],
		["travel", p2, "walk"],
	],
	"grabbed":[
		["set", "parameters/free_grabbed/current", 1],
		["set", "parameters/grabbed_seek/seek_position", 0.0]
	],
	"ungrabbed":[
		["set", "parameters/free_grabbed/current", 0]
	],
	"grab":[
		["set", "parameters/grab/blend_amount", 1.0],
		["set", "parameters/grab_seek/seek_position", 0.0]
	],
	"grab_attack1_on":[
		["set", "parameters/grab_attack/active", true],
	],
	"grabbed_attacked1_on":[
		["set", "parameters/grabbed_attacked/active", true],
	],
	"ungrab":[
		["set", "parameters/grab/blend_amount", 0.0]
	],
	"throw_projectile":[
		["set", "parameters/throw/active", true]
	]
}
#func skirt_simulation(enable):
#	if enable:
#		var skel: Skeleton = get_skeleton()
#		for k in range(skel.get_bone_count()):
#			var bone = skel.get_bone_name(k)
#			if bone.begins_with("skirt"):
#				var pb: = PhysicalBone.new()
#				pb.bone_name = bone
#				pb.joint_type = pb.JOINT_TYPE_HINGE
#				pb.body_offset = skel.get_bone_global_pose(k)
#				pb.joint_offset = skel.get_bone_global_pose(k)
#				skel.add_child(pb)
#				var cs = CollisionShape.new()
#				var sshape: = BoxShape.new()
#				sshape.extents = Vector3(0.05, 0.05, 0.05)
#				cs.shape = sshape
#				pb.add_child(cs)
#			skel.physical_bones_add_collision_exception(self.get_rid())
#			skel.physical_bones_start_simulation()
#	else:
#		var skel: Skeleton = get_skeleton()
#		skel.physical_bones_stop_simulation()
#		skel.physical_bones_remove_collision_exception(self.get_rid())
#		for k in skel.get_children():
#			if k is PhysicalBone:
#				k.queue_free()
func smart_obj(sm):
	for k in sm:
		if k[0] == "travel":
			$AnimationTree[k[1]].travel(k[2])
		if k[0] == "set":
			$AnimationTree[k[1]] = k[2]
func do_stop():
#	if name != "player":
#		print(name, " stop")
	smart_obj(act.stop)
func do_walk():
#	if name != "player":
#		print(name, "walk")
	smart_obj(act.walk)
func set_walk_speed(x):
	var s = [["set", "parameters/main/Motion/walk/walk_speed/scale", x]]
	smart_obj(s)
var grab_bone = "grabber_L"
func do_grab():
	smart_obj(act.grab)
var attacking = 0.0
func do_attack():
	if attacking > 0.0:
		return
	if get_meta("grabbing"):
		smart_obj(act.grab_attack1_on)
		var s = grabbing.get_grabbed(self)
		s.do_attacked()
		rpg.melee_attack(self, s)
		attacking += 1.0
	else:
		smart_obj(act.throw_projectile)
func do_attacked():
	if get_meta("grabbed"):
		smart_obj(act.grabbed_attacked1_on)
func do_ungrab():
	smart_obj(act.ungrab)
func do_grabbed():
	smart_obj(act.grabbed)
func do_ungrabbed():
	smart_obj(act.ungrabbed)
