use rosc::OscType;
use std::collections::HashMap;
use std::net::{SocketAddr, UdpSocket};
use std::time::Instant;
use crate::input::osc::OscStateSnapshot;
use crate::storage::asset::project::GridHighlight;
use super::scene::send_scene_instance_feedback;
use super::{osc_int, send_feedback};
pub(super) fn broadcast_snapshot(
socket: &UdpSocket,
subscribers: &HashMap<SocketAddr, Instant>,
snapshot: &OscStateSnapshot,
) {
for subscriber in subscribers.keys().copied() {
send_feedback(
socket,
subscriber,
"/project/main_dimmer",
vec![OscType::Float(
snapshot.project.as_ref().map_or(1.0, |p| p.main_dimmer),
)],
);
send_feedback(
socket,
subscriber,
"/project/blackout",
vec![OscType::Bool(snapshot.blackout)],
);
send_feedback(
socket,
subscriber,
"/timing/bpm",
vec![OscType::Float(snapshot.beats_per_minute)],
);
send_feedback(
socket,
subscriber,
"/timing/beat_progression",
vec![OscType::Float(snapshot.beat_progression)],
);
if let Some(project) = snapshot.project.as_ref() {
send_feedback(
socket,
subscriber,
"/project/palette/enabled",
vec![OscType::Bool(project.palette.is_some())],
);
if let Some(palette) = &project.palette {
let [r, g, b] = palette.primary.rgb();
send_feedback(
socket,
subscriber,
"/project/palette/primary",
vec![OscType::Float(r), OscType::Float(g), OscType::Float(b)],
);
let [r, g, b] = palette.secondary.rgb();
send_feedback(
socket,
subscriber,
"/project/palette/secondary",
vec![OscType::Float(r), OscType::Float(g), OscType::Float(b)],
);
for (n, color) in palette.gradient.iter().enumerate() {
let [r, g, b] = color.rgb();
send_feedback(
socket,
subscriber,
&format!("/project/palette/gradient/{n}"),
vec![OscType::Float(r), OscType::Float(g), OscType::Float(b)],
);
}
}
let layout_refs = project.patch.layout_refs();
send_feedback(
socket,
subscriber,
"/project/layouts/count",
vec![osc_int(layout_refs.len())],
);
for layout_ref in layout_refs {
if let Some(layout) = project.patch.layout(layout_ref) {
send_feedback(
socket,
subscriber,
&format!("/project/layouts/{}", layout_ref.stack_index()),
vec![OscType::String(layout.name.clone())],
);
}
}
for (location, scene_instance) in &project.scenes_instances_grid {
let (col, row) = (location.col, location.row);
send_scene_instance_feedback(
socket,
subscriber,
&format!("/scene/grid/{col}/{row}"),
scene_instance,
);
match project.grid_highlight {
GridHighlight::Row if row == project.quick_row_index() => {
send_scene_instance_feedback(
socket,
subscriber,
&format!("/scene/quick/{col}"),
scene_instance,
);
}
GridHighlight::Column if col == project.grid_width().saturating_sub(1) => {
send_scene_instance_feedback(
socket,
subscriber,
&format!("/scene/quick/{row}"),
scene_instance,
);
}
GridHighlight::None | GridHighlight::Row | GridHighlight::Column => {}
}
}
if let Some(scene_instance) = project
.scenes_instances_grid
.get(&snapshot.selected_scene_instance)
{
send_scene_instance_feedback(socket, subscriber, "/scene/selected", scene_instance);
}
}
}
}