#include "kyara.h"
#include <godot_cpp/core/class_db.hpp>

//INVALID USE OF INCOMPLETE TYPE STRIKES AGAIN, BUT DIFFERENT
#include "game.h"

using namespace godot;

void Character::_bind_methods()
{
	ClassDB::bind_method(D_METHOD("get_balance_radius"), &Character::get_balance_radius);
	ClassDB::bind_method(D_METHOD("set_balance_radius","p_balance_radius"), &Character::set_balance_radius);
	ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "balance_radius"), "set_balance_radius", "get_balance_radius");
	
	ClassDB::bind_method(D_METHOD("get_speed"), &Character::get_speed);
	ClassDB::bind_method(D_METHOD("set_speed","p_speed"), &Character::set_speed);
	ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "speed", PROPERTY_HINT_RANGE,"0,20,0.01"), "set_speed", "get_speed");
	
	ClassDB::bind_method(D_METHOD("get_texture"), &Character::get_texture);
	ClassDB::bind_method(D_METHOD("set_texture","p_texture"), &Character::set_texture);
	ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "texture", PROPERTY_HINT_RESOURCE_TYPE, "Texture2D"), "set_texture", "get_texture");
}

Character::Character()
{
	set_motion_mode(MOTION_MODE_FLOATING);
	speed=1.0;
	balance_radius=64.0;
	balance_radius_cur=8.0;
	face=memnew(Sprite2D);
	face->set_name("_face");
	face->set_draw_behind_parent(true);
	add_child(face,false,INTERNAL_MODE_BACK);
	input=memnew(Controller);
	input->set_name("_input");
	input->parent=this;
	add_child(input,false,INTERNAL_MODE_BACK);
	sync=memnew(MultiplayerSynchronizer);
	sync->set_name("_sync");
	add_child(sync,false,INTERNAL_MODE_BACK);
	shape=memnew(CollisionShape2D);
	shape->set_name("_shape");
	add_child(shape,false,INTERNAL_MODE_BACK);
	br_col=memnew(Color);
	br_col->r=1.0;
}
Character::~Character(){}

void Character::_process(double delta)
{
	balance_radius_cur-=3.0;
	balance_radius_cur=godot::Math::max(balance_radius_cur,8.0);
	move(input->flags);
	look_at(input->target);
	queue_redraw();
	// Not sure if I should do this. Issues could occur if I'm wrong either side.
	//CharacterBody2D::_process(delta);
}

void Character::_ready()
{
	set_motion_mode(MOTION_MODE_FLOATING);
}

void Character::_enter_tree()
{
	Ref<SceneReplicationConfig> conf=memnew(SceneReplicationConfig);
	conf->add_property(":rotation");
	conf->add_property(":position");
	sync->set_replication_config(conf);
	input->set_multiplayer_authority(multiplayerowner);
}

void Character::_draw()
{
	// これ嫌い: *obj
	if (!(mummy->multiplayer_type&2)) return;
	if (multiplayerowner!=get_multiplayer()->get_unique_id()) return;
	draw_circle(Vector2(0,0),balance_radius_cur,*br_col,false);
}

void Character::move(int flags)
{
	if (!flags) return;
	// Collision detection needs to go in here, buncha shit
	balance_radius_cur+=6.0;
	balance_radius_cur=godot::Math::min(balance_radius_cur,balance_radius);
	double x=speed*(((flags&8)>>3)-((flags&4)>>2));
	double y=speed*(((flags&2)>>1)-((flags&1)>>0));
	// Very C
	set_position(get_position()+Vector2(x,y));
}

void Character::set_balance_radius(const double p_balance_radius) { balance_radius=p_balance_radius; }
double Character::get_balance_radius() const { return balance_radius; }

void Character::set_speed(const double p_speed) { speed=p_speed; }
double Character::get_speed() const { return speed; }

void Character::set_texture(const Ref<Texture2D> &p_texture) { face->set_texture(p_texture); }
Ref<Texture2D> Character::get_texture() const { return face->get_texture(); }