/*
Hurry Curry! - a game about cooking
Copyright (C) 2025 Hurry Curry! Contributors
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 anyhow::Result;
use hurrycurry_protocol::{
Gamedata, Message,
book::{Diagram, NodeStyle},
};
use std::fmt::Write;
pub fn diagram_dot(data: &Gamedata, diagram: &Diagram) -> Result {
let mut out = String::new();
writeln!(out, "digraph {{")?;
for (i, n) in diagram.nodes.iter().enumerate() {
let mut attrs = Vec::new();
node_style(&mut attrs, &n.style);
match &n.label {
Message::Text(text) => {
attrs.push(format!("label=\"{text}\""));
}
Message::Item(item_index) => {
attrs.push(format!(
"image=\"/tmp/items/{}.png\"",
data.item_name(*item_index)
));
attrs.push("imagescale=true".to_owned());
attrs.push("width=1".to_owned());
attrs.push("height=1".to_owned());
attrs.push("fixedsize=true".to_owned());
attrs.push("label=\"\"".to_owned());
}
Message::Tile(tile_index) => {
attrs.push(format!(
"image=\"/tmp/tiles/{}.png\"",
data.tile_name(*tile_index)
));
attrs.push("imagescale=true".to_owned());
attrs.push("width=1".to_owned());
attrs.push("height=1".to_owned());
attrs.push("fixedsize=true".to_owned());
attrs.push("label=\"\"".to_owned());
}
_ => unimplemented!(),
}
writeln!(out, "k{i} [{}]", attrs.join(" "))?;
}
for edge in &diagram.edges {
writeln!(out, "k{} -> k{}", edge.src, edge.dst)?;
}
writeln!(out, "}}")?;
Ok(out)
}
fn node_style(attrs: &mut Vec, style: &NodeStyle) {
let (shape, color) = match style {
NodeStyle::FinalProduct => ("circle", "#555"),
NodeStyle::IntermediateProduct => ("circle", "#333"),
NodeStyle::ProcessActive => ("box", "#47c42b"),
NodeStyle::ProcessPassive => ("box", "#c4a32b"),
NodeStyle::ProcessInstant => ("box", "#5452d8"),
};
attrs.push(format!("shape={shape}"));
attrs.push("style=filled".to_owned());
attrs.push(format!("fillcolor=\"{color}\""));
attrs.push(format!("color=\"{color}\""));
}