1use super::{ColorScheme, RenderOptions, Structure};
6use bevy::prelude::*;
7use ferritin_core::load_model;
8use std::path::Path;
9use std::path::PathBuf;
10
11#[derive(Clone)]
12pub struct StructureSettings {
13 pub render_type: RenderOptions,
14 pub color_scheme: ColorScheme,
15 pub material: StandardMaterial,
16}
17impl Default for StructureSettings {
18 fn default() -> Self {
19 Self {
20 render_type: RenderOptions::Solid,
21 color_scheme: ColorScheme::Solid(Color::WHITE),
22 material: StandardMaterial::default(),
23 }
24 }
25}
26
27pub struct StructurePlugin {
29 initial_files: Vec<(PathBuf, StructureSettings)>,
30}
31
32impl Default for StructurePlugin {
33 fn default() -> Self {
34 Self::new()
35 }
36}
37
38impl StructurePlugin {
39 pub fn new() -> Self {
40 Self {
41 initial_files: Vec::new(),
42 }
43 }
44 pub fn with_file<P: Into<PathBuf>>(
45 mut self,
46 path: P,
47 settings: Option<StructureSettings>,
48 ) -> Self {
49 self.initial_files
50 .push((path.into(), settings.unwrap_or_default()));
51 self
52 }
53}
54
55impl Plugin for StructurePlugin {
57 fn build(&self, app: &mut App) {
58 app.insert_resource(StructureFiles(self.initial_files.clone()))
59 .add_systems(Startup, load_initial_proteins)
60 .add_message::<LoadProteinEvent>();
61 }
62}
63
64#[derive(Resource)]
65struct StructureFiles(Vec<(PathBuf, StructureSettings)>);
66
67#[derive(Message)]
68pub struct LoadProteinEvent(pub PathBuf);
69
70fn load_initial_proteins(
71 structure_files: Res<StructureFiles>,
72 mut commands: Commands,
73 mut meshes: ResMut<Assets<Mesh>>,
74 mut materials: ResMut<Assets<StandardMaterial>>,
75) {
76 for (file_path, settings) in &structure_files.0 {
77 if !Path::new(file_path).exists() {
79 eprintln!("Error: File not found: {:?}", file_path);
80 continue;
81 }
82
83 let model = load_model(file_path).unwrap();
84
85 let structure = Structure::builder()
86 .pdb(model)
87 .rendertype(settings.render_type.clone())
88 .color_scheme(settings.color_scheme.clone())
89 .material(settings.material.clone())
90 .build();
91
92 let mesh = structure.to_mesh();
93 let material = structure.get_material();
94
95 commands.spawn((
96 Mesh3d(meshes.add(mesh)),
97 MeshMaterial3d(materials.add(material)),
98 ));
99 }
100}