use std::path::PathBuf;
use navig18xx::prelude::{image_size, Game, Hex, ImageFormat, Map};
pub struct Settings {
pub format: ImageFormat,
pub hex_size: f64,
pub input_file: Option<PathBuf>,
pub output_file: Option<PathBuf>,
}
impl Default for Settings {
fn default() -> Self {
Settings {
hex_size: 125.0,
format: ImageFormat::Png,
input_file: None,
output_file: None,
}
}
}
impl Settings {
pub fn try_from_args() -> Option<Self> {
let mut settings = Settings::default();
let mut parse_options = true;
for arg in std::env::args().skip(1) {
if parse_options {
if !arg.starts_with('-') {
parse_options = false;
} else if arg == "--" {
parse_options = false;
continue;
} else {
match arg.as_str() {
"--pdf" => settings.format = ImageFormat::Pdf,
"--png" => settings.format = ImageFormat::Png,
"--svg" => settings.format = ImageFormat::Svg,
_ => return None,
}
continue;
}
};
if settings.input_file.is_none() {
settings.input_file = Some(PathBuf::from(arg));
} else if settings.output_file.is_none() {
settings.output_file = Some(PathBuf::from(arg));
} else {
return None;
}
}
if let Some(ref input_file) = settings.input_file {
if settings.output_file.is_none() {
let ext = settings.format.extension();
settings.output_file = Some(input_file.with_extension(ext))
}
} else {
return None;
}
Some(settings)
}
}
pub fn draw(map: &Map, hex: &Hex, ctx: &cairo::Context) {
let mut hex_iter = map.hex_iter(hex, ctx);
navig18xx::brush::draw_map(hex, ctx, &mut hex_iter);
}
pub fn main() {
let settings = Settings::try_from_args().expect("Invalid arguments");
let hex = Hex::new(settings.hex_size);
let input = settings.input_file.unwrap();
let output = settings.output_file.unwrap();
let mut games: std::collections::BTreeMap<String, Box<dyn Game>> =
vec![Box::new(navig18xx::game::new_1867()) as Box<dyn Game>]
.into_iter()
.map(|game| (game.name().to_string(), game))
.collect();
println!("Reading {} ...", input.to_str().unwrap());
let game_state = navig18xx::io::read_game_state(&input)
.expect("Could not read game file");
let game = games
.get_mut(&game_state.game)
.expect("No matching game for game file");
let map = game.load(&hex, game_state).expect("Could not load map");
let (width, height) = image_size(|ctx| draw(&map, &hex, ctx))
.expect("Could not determine image size");
println!("Writing {} ...", output.to_str().unwrap());
settings
.format
.save_image(width, height, |ctx| draw(&map, &hex, ctx), &output)
.expect("Could not write output image")
}