/*
 * pop_kid.h — движок анимации/движения Kid (Фаза K1): интерпретатор
 * seqtbl (play_seq) + frame_table.  Порт SDLPoP seg006.c.  Данные —
 * kid_data.h (pop_extract_kid_data.py).
 *
 * K1: только проигрывание последовательностей кадров с авторскими
 * смещениями (движение = SEQ_DX/DY + frame.dx/dy).  Управление (K2) и
 * коллизия карты (K3) — отдельно.
 */
#ifndef POP_KID_H
#define POP_KID_H

#include <stdint.h>
#include "pop_char.h"
#include "kid_data.h"    /* kframe — тип кадра для pop_sword_draw */

/* Состояние персонажа — общий тип для Кида, стража и Char (pop_char.h). */
extern pop_char_t Kid;

/* Флаг сотрясения (seg006 knock): +1 = KNOCK_UP (ряд выше), -1 = KNOCK_DOWN
 * (свой ряд).  Ставит play_seq, читает/сбрасывает pop_check_knock. */
extern int8_t knock;

/* Порт next_level (seg000): END_LEVEL в play_seq инкрементит — «уровень
 * пройден».  Читает и обнуляет главный цикл.  Пока уровень один, поэтому
 * там рестарт того же уровня; загрузка следующего — levels_plan.md. */
extern uint8_t pop_next_level;

/* Загрузить npages атласов Kid (kid0..kid{npages-1}.atl).  ДО initgraph.
 * 0 — OK, -1 — ошибка. */
int  pop_kid_load(uint8_t npages);

/* Данные анимации (таблица кадров + seqtbl) — отдельная EMM-страница
 * (kid_data.bin): в _CODE окна W1/W2 они занимали 3.5 КБ.  Грузить ДО
 * первого kid_init/play_seq.  0 — OK, -1 — ошибка (без них Kid не оживёт).
 * Страница маппится в W0 внутри play_seq, раз за тик. */
int  pop_kid_data_load(const char *path);

/* Прочитать кадр из таблицы страницы данных: tbl_off — KID_BIN_FRAMES_OFF
 * (Kid) или KID_BIN_GFRAMES_OFF (страж, своя таблица frame_tbl_guard).
 * Маппит страницу сама; для горячего цикла есть cur_frame. */
void pop_kid_data_frame(uint16_t tbl_off, uint8_t idx, uint8_t *out5);
void pop_kid_data_free(void);

/* Атлас chtab_0 «меч в руке» (sword.atl) — спрайт клинка поверх Kid в кадрах
 * подъёма меча/убирания в ножны (add_sword_to_objtable, seg006:1798).
 * Грузить ДО initgraph, как и страницы Kid.  0 — OK, -1 — ошибка (тогда
 * кадры рисуются без клинка). */
int  pop_sword_load(void);
void pop_kid_free(void);

/* Нарисовать клинок chtab_0 поверх персонажа (порт add_sword_to_objtable,
 * seg006:1798) — общая точка для Кида и стража: меч в оригинале ОДИН на
 * всех.  obj_x/obj_y — та же опорная точка, что у спрайта персонажа.
 * Возвращает 1 и прямоугольник клинка (для heal), 0 — клинка нет.
 * Страницу W0 оставляет замапленной: вызывающий делает gfx_w0_unmap. */
uint8_t pop_sword_draw(const pop_char_t *ch, const kframe *fr,
                       int obj_x, int obj_y,
                       int *rx, int *ry, uint16_t *rw, uint16_t *rh);

/* Инициализировать Kid: последовательность seq_id, клетка col/row,
 * направление dir (-1/0).  Ставит x/y по x_bump/y_land. */
void kid_init(uint8_t seq_id, int8_t col, int8_t row, int8_t dir);

/* Один логический тик: play_seq() — продвинуть последовательность до
 * следующего кадра (применить SEQ_DX/DY/ACTION/...). */
void kid_tick(void);

/* play_seq напрямую (для pop_map start_fall — переход в fall-seq в тот же
 * physics-шаг, как оригинал). */
void play_seq(void);          /* работает с Char — см. pop_kid_play ниже */

/* Активный персонаж (порт Char, seg006) и его загрузка/выгрузка.
 * Интерпретатор последовательностей общий для Kid и стража: у них общая
 * seqtbl, но РАЗНЫЕ таблицы кадров (load_frame выбирает по Char.charid). */
extern pop_char_t Char;
/* Соперник активного персонажа (порт Opp): ставится вместе с Char через
 * pop_loadshad_and_opp.  Читают ИИ стража и боёвка (char_opp_dist). */
extern pop_char_t Opp;
void pop_loadkid(void);
void pop_savekid(void);
void pop_savekid_state(void);   /* Kid = Char, кадр не трогаем */
void pop_loadshad(void);
void pop_saveshad(void);
void pop_loadshad_and_opp(void);   /* Char = Guard, Opp = Kid (seg006:841) */
void pop_saveshad_and_opp(void);   /* Guard = Char, Kid = Opp              */
void pop_loadkid_and_opp(void);    /* Char = Kid,   Opp = Guard            */
void pop_savekid_and_opp(void);    /* Kid = Char,   Guard = Opp            */

/* Дистанция до соперника в системе Char: >0 впереди, <0 за спиной,
 * 999 — разные комнаты (порт char_opp_dist, seg006:2135). */
int16_t pop_char_opp_dist(void);

/* Прокрутить последовательность персонажа целиком (load + play_seq +
 * save).  Звать вместо голого play_seq. */
void pop_char_set_seq(uint8_t seq_id);   /* seq активного персонажа */
void pop_kid_play(void);
void pop_guard_play(void);

/* Поля текущего кадра kid_frames[Kid.frame] (pop_map, без дублирования
 * таблицы во втором TU). */
int8_t  kid_cur_dx(void);
int8_t  kid_cur_dy(void);
uint8_t kid_cur_flags(void);

/* Сменить последовательность (Kid.curr_seq = kid_seq_off[seq_id]) — единая
 * точка для pop_ctrl/pop_map (иначе каждый дублировал бы kid_seqtbl ~2.3КБ). */
void kid_set_seq(uint8_t seq_id);

/* Рендер-смещение Kid по ЛОГИЧЕСКОЙ X (порт xpos_in_drawn_room, seg004):
 * когда комната Kid ≠ отрисованной (straddle у шва), спрайт рисуется со
 * сдвигом ∓140 (левый сосед −140 / правый +140), при этом Kid.x/коллизия
 * остаются в кадре комнаты Kid.  0 — комнаты совпадают (обычный случай).
 * Влияет на kid_draw и метрики футпринта (fore) — heal берёт запомненный
 * прямоугольник, поэтому согласован автоматически. */
void pop_kid_set_render_dx(int dx);

/* Нарисовать текущий кадр Kid (банк GFX_BANK_SPRITE — видео-ОЗУ, без
 * теневой копии; запоминает прямоугольник для kid_heal). */
void kid_draw(void);

/* Вернуть окно fore-клипа на прямоугольник последнего кадра Kid.  Звать
 * ПЕРЕД pop_fore_over_kid, если между ним и kid_draw кто-то ещё рисовал
 * персонажа (pop_guard_draw ставит окно по стражу). */
void kid_fore_clip_restore(void);

/* draw_hurt_splash (seg006:2003): «брызги» урона (image 218) поверх Kid —
 * звать СРАЗУ после kid_draw в кадре, когда HP убавилось (pop_kid_hurt). */
void kid_draw_splash(void);

/* Блит спрайта chtab_2 по id, левым верхним углом в (x,y) — для полосы HP
 * (id 216 полное деление / 217 пустое). */
void pop_kid_img_blit(uint8_t image, int x, int y);

/* Восстановить фон (из теневой копии) на месте ПРЕДЫДУЩЕГО кадра Kid —
 * вместо перерисовки всего экрана.  Звать ПЕРЕД kid_tick/kid_draw. */
void kid_heal(void);

/* Метрики последнего kid_draw для футпринта fore-over-Kid (pop_bg
 * pop_fore_over_kid): obj_x — ЛОГИЧЕСКАЯ X кадра (до ×8/7), obj_y — низ
 * спрайта, w/h — размер кадра. */
int      kid_fp_obj_x(void);
int      kid_fp_obj_y(void);
uint16_t kid_fp_width(void);
uint16_t kid_fp_height(void);

#endif
