/*
 * libptouch — layout tables and profile resolution (Brother raster PDFs)
 *
 * Author: knb
 * Email: knb@artif.org
 */

#include "libptouch_layout.h"

/* --- cv_ptp900_jpn_raster_102.pdf: TZe / その他（HS 以外で共通レイアウトを使う帯） --- */
static const ptouch_layout_row_t layout_tze_560[] = {
	{ 0x04, 248, 48, 264 },
	{ 0x06, 240, 64, 256 },
	{ 0x09, 219, 106, 235 },
	{ 0x0C, 197, 150, 213 },
	{ 0x12, 155, 234, 171 },
	{ 0x18, 112, 320, 128 },
	{ 0x24, 45, 454, 61 },
};

static const ptouch_layout_row_t layout_hs_560[] = {
	{ 0x06, 244, 56, 260 },
	{ 0x09, 224, 96, 240 },
	{ 0x0C, 206, 132, 222 },
	{ 0x12, 166, 212, 182 },
	{ 0x18, 144, 256, 160 },
};

/* --- cv_ptp750w_710bt_jpn_raster_102.pdf --- */
static const ptouch_layout_row_t layout_tze_128[] = {
	{ 0x04, 52, 24, 52 },
	{ 0x06, 48, 32, 48 },
	{ 0x09, 39, 50, 39 },
	{ 0x0C, 29, 70, 29 },
	{ 0x12, 8, 112, 8 },
	{ 0x18, 0, 128, 0 },
};

static const ptouch_layout_row_t layout_hs_128[] = {
	{ 0x06, 50, 28, 50 },
	{ 0x09, 40, 48, 40 },
	{ 0x0C, 31, 66, 31 },
	{ 0x12, 11, 106, 11 },
	{ 0x18, 0, 128, 0 },
};

static const uint16_t pids_128pin[] = {
	LIBPTOUCH_USB_PID_PTP750W,
	LIBPTOUCH_USB_PID_PTP710BT,
	0,
};

static const uint8_t models_128pin[] = {
	0x68, /* PT-P750W */
	0x76, /* PT-P710BT */
	0,
};

static const ptouch_printer_profile_t ptouch_layout_profiles[] = {
	{
		.usb_pids = pids_128pin,
		.model_codes = models_128pin,
		.is_default = 0,
		.head_width_dots = 128u,
		.margin_feed_dpi = 180.0,
		.margin_feed_max_dots = 900u,
		.tze = layout_tze_128,
		.tze_count = sizeof(layout_tze_128) / sizeof(layout_tze_128[0]),
		.hs = layout_hs_128,
		.hs_count = sizeof(layout_hs_128) / sizeof(layout_hs_128[0]),
		.doc_ref = "cv_ptp750w_710bt_jpn_raster_102.pdf",
	},
	{
		.usb_pids = NULL,
		.model_codes = NULL,
		.is_default = 1,
		.head_width_dots = 560u,
		.margin_feed_dpi = 360.0,
		.margin_feed_max_dots = 1800u,
		.tze = layout_tze_560,
		.tze_count = sizeof(layout_tze_560) / sizeof(layout_tze_560[0]),
		.hs = layout_hs_560,
		.hs_count = sizeof(layout_hs_560) / sizeof(layout_hs_560[0]),
		.doc_ref = "cv_ptp900_jpn_raster_102.pdf (560-dot family)",
	},
};

static int pid_in_list(const uint16_t *list, uint16_t pid)
{
	if (!list)
		return 0;
	for (; *list; list++) {
		if (*list == pid)
			return 1;
	}
	return 0;
}

static int model_in_list(const uint8_t *list, uint8_t code)
{
	if (!list)
		return 0;
	for (; *list; list++) {
		if (*list == code)
			return 1;
	}
	return 0;
}

const ptouch_printer_profile_t *ptouch_layout_resolve_profile(uint16_t usb_pid,
							      uint8_t status_model_byte)
{
	const ptouch_printer_profile_t *fallback = NULL;

	for (size_t i = 0;
	     i < sizeof(ptouch_layout_profiles) / sizeof(ptouch_layout_profiles[0]);
	     i++) {
		const ptouch_printer_profile_t *p = &ptouch_layout_profiles[i];
		if (p->is_default) {
			fallback = p;
			continue;
		}
		if (pid_in_list(p->usb_pids, usb_pid) ||
		    model_in_list(p->model_codes, status_model_byte))
			return p;
	}
	return fallback;
}

static libptouch_err_t layout_lookup_table(const ptouch_layout_row_t *table, size_t n,
					   uint8_t media_wbyte, uint16_t *left,
					   uint16_t *print_dots, uint16_t *right)
{
	for (size_t i = 0; i < n; i++) {
		if (table[i].media_wbyte != media_wbyte)
			continue;
		*left = table[i].left_dots;
		*print_dots = table[i].print_dots;
		*right = table[i].right_dots;
		return LIBPTOUCH_OK;
	}
	return LIBPTOUCH_ERR_UNSUPPORTED;
}

libptouch_err_t ptouch_layout_from_status(const ptouch_printer_profile_t *prof,
					  uint8_t media_kind, uint8_t media_wbyte,
					  uint16_t *left_dots, uint16_t *print_dots,
					  uint16_t *right_dots)
{
	if (!prof || !left_dots || !print_dots || !right_dots)
		return LIBPTOUCH_ERR_ARG;

	int is_hs = (media_kind == 0x11u || media_kind == 0x17u);
	const ptouch_layout_row_t *table = is_hs ? prof->hs : prof->tze;
	size_t n = is_hs ? prof->hs_count : prof->tze_count;

	return layout_lookup_table(table, n, media_wbyte, left_dots, print_dots,
				   right_dots);
}
