/*
    Hurry Curry! - a game about cooking
    Copyright 2024 metamuffin
    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU Affero General Public License as published by
    the Free Software Foundation, version 3 of the License only.
    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU Affero General Public License for more details.
    You should have received a copy of the GNU Affero General Public License
    along with this program.  If not, see .
*/
use clap::Parser;
use std::{
    collections::HashMap,
    fs::{read_to_string, File},
    io::{BufRead, BufReader, BufWriter, Write},
    path::PathBuf,
};
#[derive(Parser)]
struct Args {
    catalogue: PathBuf,
    texture_dir: PathBuf,
    output_dir: PathBuf,
}
fn main() {
    let Args {
        catalogue,
        texture_dir,
        output_dir,
    } = Args::parse();
    for line in read_to_string(catalogue).unwrap().lines() {
        let (line, _) = line.split_once(";").unwrap_or((line, ""));
        let line = line.trim();
        if line.is_empty() {
            continue;
        }
        let (name, rest) = line.split_once("=").unwrap();
        let (connects, rest) = rest.split_once(":").unwrap_or(("a", rest));
        eprintln!("  compose {name:?} ({connects})");
        let mut texels = HashMap::new();
        for part in rest.split(",") {
            let mut mods = part.split("~");
            let texname = mods.next().unwrap();
            let mut hflip = false;
            let mut vflip = true;
            let mut xoff = 0;
            let mut yoff = 0;
            for m in mods {
                if m == "hflip" {
                    hflip = !hflip
                }
                if m == "vflip" {
                    vflip = !vflip
                }
                if let Some(m) = m.strip_prefix("x") {
                    xoff += m.parse::().unwrap();
                }
                if let Some(m) = m.strip_prefix("y") {
                    yoff += m.parse::().unwrap();
                }
            }
            let texpath = texture_dir.join(texname).with_extension("ta");
            eprintln!("    + {texpath:?}");
            let file = BufReader::new(File::open(&texpath).unwrap());
            let tex = file.lines().map(Result::unwrap).collect::>();
            let (width, height) = (tex[0].chars().count(), tex.len());
            for (mut y, line) in tex.iter().enumerate() {
                if line.is_empty() {
                    continue;
                }
                if vflip {
                    y = height - y - 1
                }
                for (mut x, char) in line.chars().enumerate() {
                    if hflip {
                        x = width - x - 1
                    }
                    let e = texels
                        .entry((x as i32 + xoff, y as i32 + yoff))
                        .or_insert(' ');
                    if char != ' ' {
                        *e = char
                    }
                }
            }
        }
        let mut min_x = 0;
        let mut min_y = 0;
        let mut max_x = 0;
        let mut max_y = 0;
        for (x, y) in texels.keys() {
            min_x = min_x.min(*x);
            min_y = min_y.min(*y);
            max_x = max_x.max(*x + 1);
            max_y = max_y.max(*y + 1);
        }
        let width = max_x - min_x;
        let height = max_y - min_y;
        let outpath = output_dir
            .join(format!("{name}+{connects}"))
            .with_extension("ta");
        let mut output = BufWriter::new(File::create(outpath).unwrap());
        for y in 0..height {
            for x in 0..width {
                write!(
                    output,
                    "{}",
                    texels.get(&(x + min_x, max_y - y - 1)).unwrap_or(&' ')
                )
                .unwrap();
            }
            writeln!(output).unwrap();
        }
    }
}