#include "pingpong_game.h"
#include "pingpong_ball.h"

#include <godot_cpp/core/class_db.hpp>
#include <godot_cpp/variant/utility_functions.hpp>
#include <godot_cpp/classes/engine.hpp>
#include <godot_cpp/classes/scene_tree.hpp>

using namespace godot;

void PingPongGame::_bind_methods() {
    // 属性
    ClassDB::bind_method(D_METHOD("get_left_score"), &PingPongGame::get_left_score);
    ClassDB::bind_method(D_METHOD("set_left_score", "value"), &PingPongGame::set_left_score);
    ClassDB::add_property("PingPongGame", PropertyInfo(Variant::INT, "left_score"), "set_left_score", "get_left_score");

    ClassDB::bind_method(D_METHOD("get_right_score"), &PingPongGame::get_right_score);
    ClassDB::bind_method(D_METHOD("set_right_score", "value"), &PingPongGame::set_right_score);
    ClassDB::add_property("PingPongGame", PropertyInfo(Variant::INT, "right_score"), "set_right_score", "get_right_score");

    ClassDB::bind_method(D_METHOD("get_max_score"), &PingPongGame::get_max_score);
    ClassDB::bind_method(D_METHOD("set_max_score", "value"), &PingPongGame::set_max_score);
    ClassDB::add_property("PingPongGame", PropertyInfo(Variant::INT, "max_score"), "set_max_score", "get_max_score");

    // 方法
    ClassDB::bind_method(D_METHOD("reset_game"), &PingPongGame::reset_game);
    ClassDB::bind_method(D_METHOD("_on_ball_scored", "which"), &PingPongGame::_on_ball_scored);

    // 信号
    ADD_SIGNAL(MethodInfo("game_over", PropertyInfo(Variant::INT, "winner")));
}

PingPongGame::PingPongGame() {
    left_score = 0;
    right_score = 0;
    max_score = 5;
}

PingPongGame::~PingPongGame() {
}

void PingPongGame::_ready() {
    // 查找比分 Label
    left_score_label = Object::cast_to<Label>(get_node_or_null("UI/LeftScore"));
    right_score_label = Object::cast_to<Label>(get_node_or_null("UI/RightScore"));

    // 连接球的得分信号
    PingPongBall *ball = Object::cast_to<PingPongBall>(get_node_or_null("Ball"));
    if (ball) {
        ball->connect("scored", Callable(this, "_on_ball_scored"));
    }

    update_score_display();
}

void PingPongGame::_on_ball_scored(int which) {
    if (which == 0) {
        // 左边得分
        right_score++;
    } else {
        // 右边得分
        left_score++;
    }

    update_score_display();

    // 检查是否有人获胜
    if (left_score >= max_score) {
        emit_signal("game_over", 0);
    } else if (right_score >= max_score) {
        emit_signal("game_over", 1);
    }
}

void PingPongGame::reset_game() {
    left_score = 0;
    right_score = 0;
    update_score_display();
}

void PingPongGame::update_score_display() {
    if (left_score_label) {
        left_score_label->set_text(String::num_int64(left_score));
    }
    if (right_score_label) {
        right_score_label->set_text(String::num_int64(right_score));
    }
}

void PingPongGame::set_left_score(int p_score) {
    left_score = p_score;
    update_score_display();
}

int PingPongGame::get_left_score() const {
    return left_score;
}

void PingPongGame::set_right_score(int p_score) {
    right_score = p_score;
    update_score_display();
}

int PingPongGame::get_right_score() const {
    return right_score;
}

void PingPongGame::set_max_score(int p_score) {
    max_score = p_score;
}

int PingPongGame::get_max_score() const {
    return max_score;
}
