add various graphical elements
[lp74.git] / src / data.rs
blob758a038ce6d981193593ba032ec29abbb29c285b
1 use std::usize;
3 const SPACE_SIZE: usize = 11;
4 const NOF_DIM: usize = 3;
5 const DEFAULT_FACE_SIZE: usize = 64;
7 #[derive(Clone, Copy, PartialEq, Debug)]
8 pub enum Axis {
9     X,
10     Y,
11     Z,
14 #[derive(Clone, Copy, PartialEq, Debug)]
15 pub enum Ori {
16     Top,
17     Back,
18     Side,
21 #[derive(Clone, Copy, PartialEq, Debug)]
22 pub enum Pos {
23     E(Edge),
24     F(Face),
27 #[derive(Clone, Copy, PartialEq, Debug)]
28 pub enum Change {
29     None,
30     Current,
31     Size(Edge, usize),
32     Space,
35 #[derive(Clone, Copy, PartialEq, Debug)]
36 pub enum PosKind {
37     Edge,
38     Face,
41 pub type Coord = (usize, usize, usize);
42 pub type Edge = (Coord, Axis);
43 pub type Face = (Coord, Ori);
44 pub type FaceColor = (f32, f32, f32);
45 pub type Surface = [Option<FaceColor>; NOF_DIM];
47 pub struct Space {
48     pub size: [[usize; SPACE_SIZE]; NOF_DIM],
49     pub faces: [[[Option<Surface>; SPACE_SIZE]; SPACE_SIZE]; SPACE_SIZE],
50     pub current: Pos,
51     pub change: Change,
54 //macro_rules! tuple_array {
55 //    ($a:expr, $(($x:expr, $y:expr, $z:expr),)+) => [$((($x, $y, $z), $a),)+],
56 //}
58 impl Space {
59     fn new() -> Space {
60         let mid = SPACE_SIZE / 2;
61         let current_node = (mid, mid, mid);
62         let mut tmp = Space {
63             size: [[DEFAULT_FACE_SIZE; SPACE_SIZE]; NOF_DIM],
64             faces: [[[None; SPACE_SIZE]; SPACE_SIZE]; SPACE_SIZE],
65             current: Pos::E((current_node, Axis::X)),
66             change: Change::None,
67         };
68         tmp.add_empty_node(current_node);
69         tmp.add_face((current_node, Ori::Top));
70         tmp
71     }
73     pub fn axis_idx(a: Axis) -> usize {
74         match a {
75             Axis::X => 0,
76             Axis::Y => 1,
77             Axis::Z => 2,
78         }
79     }
81     pub fn ori_idx(o: Ori) -> usize {
82         match o {
83             Ori::Top => 0,
84             Ori::Side => 1,
85             Ori::Back => 2,
86         }
87     }
89     fn adj_faces(((x, y, z), a): Edge) -> Vec<Face> {
90         let mut faces = Vec::new();
91         match a {
92             Axis::X => {
93                 faces.push(((x, y, z), Ori::Top));
94                 faces.push(((x, y, z), Ori::Back));
95                 if y < (SPACE_SIZE - 1) {
96                     faces.push(((x, y+1, z), Ori::Top));
97                 }
98                 if z > 0 {
99                    faces.push(((x, y, z-1), Ori::Back));
100                 }
101             },
102             Axis::Y => {
103                 faces.push(((x, y, z), Ori::Top));
104                 faces.push(((x, y, z), Ori::Side));
105                 if x > 0 {
106                     faces.push(((x-1, y, z), Ori::Top));
107                 }
108                 if z > 0 {
109                     faces.push(((x, y, z-1), Ori::Side));
110                 }
111             },
112             Axis::Z => {
113                 faces.push(((x, y, z), Ori::Back));
114                 faces.push(((x, y, z), Ori::Side));
115                 if x > 0 {
116                     faces.push(((x-1, y, z), Ori::Back));
117                 }
118                 if y < (SPACE_SIZE - 1) {
119                     faces.push(((x, y+1, z), Ori::Side));
120                 }
121             },
122         }
123         faces
124     }
126     fn is_node(&self, (x, y, z): Coord) -> bool {
127         if x < SPACE_SIZE
128             && y < SPACE_SIZE
129             && z < SPACE_SIZE {
130             if let Some(_) = self.faces[x][y][z] {
131                 true
132             } else {
133                 false
134             }
135         } else {
136             false
137         }
138     }
140     fn is_edge(&self, (c, a): Edge) -> bool {
141         assert!(self.is_node(c));
142         self.is_adj_existing_faces((c, a))
143     }
145     fn is_face(&self, ((x, y, z), o): Face) -> bool {
146         self.is_node((x, y, z))
147             && match self.faces[x][y][z] {
148             Some(faces) => faces[Space::ori_idx(o)] != None,
149             None => false,
150         }
151     }
153     pub fn current_node_coord(&self) -> Coord {
154         match self.current {
155             Pos::E((n, _)) => n,
156             Pos::F((n, _)) => n,
157         }
158     }
160     pub fn row_size_before_current(&self, a: Axis) -> usize {
161         let (xcur, ycur, zcur) = self.current_node_coord();
162         let mut res = 0;
163         match a {
164             Axis::X => {
165                 for x in 0..xcur {
166                     res += self.size[Space::axis_idx(Axis::X)][x];
167                 }
168             },
169             Axis::Y => {
170                 for y in 0..ycur {
171                     res += self.size[Space::axis_idx(Axis::Y)][y];
172                 }
173             },
174             Axis::Z => {
175                 for z in 0..zcur {
176                     res += self.size[Space::axis_idx(Axis::Z)][z];
177                 }
178             },
179         }
180         res
181     }
183     pub fn row_size_after_current(&self, a: Axis) -> usize {
184         let (xcur, ycur, zcur) = self.current_node_coord();
185         let mut res = 0;
186         match a {
187             Axis::X => {
188                 let xidx = Space::axis_idx(Axis::X);
189                 for x in xcur..self.size[xidx].len() {
190                     res += self.size[xidx][x];
191                 }
192             },
193             Axis::Y => {
194                 let yidx = Space::axis_idx(Axis::Y);
195                 for y in ycur..self.size[yidx].len() {
196                     res += self.size[yidx][y];
197                 }
198             },
199             Axis::Z => {
200                 let zidx = Space::axis_idx(Axis::Z);
201                 for z in zcur..self.size[zidx].len() {
202                     res += self.size[zidx][z];
203                 }
204             },
205         }
206         res
207     }
209     pub fn row_size(&self, a: Axis) -> usize {
210         self.size[Space::axis_idx(a)].iter()
211             .fold(0, |row, &s| row + s)
212     }
214     pub fn get_edge_size(&self, ((x, y, z), a): Edge) -> usize {
215         //assert!(self.is_edge(((x, y, z), a)));
216         self.size[Space::axis_idx(a)][match a {
217             Axis::X => x,
218             Axis::Y => y,
219             Axis::Z => z,
220         }]
221     }
223     pub fn get_current_face_color_if_any(&self) -> Option<FaceColor> {
224         match self.current {
225             Pos::E(_) => None,
226             Pos::F(((x, y, z), o)) => match self.faces[x][y][z] {
227                 Some(ref f) => f[Space::ori_idx(o)],
228                 None => None,
229             },
230         }
231     }
233     pub fn set_current_face_color_if_any(&mut self, c: FaceColor) {
234         match self.current {
235             Pos::E(_) => panic!("current is not a face"),
236             Pos::F(((x, y, z), o)) => match self.faces[x][y][z] {
237                 Some(ref mut f) => f[Space::ori_idx(o)] = Some(c),
238                 None => panic!("no face here"),
239             },
240         }
241     }
243     fn edge_size_no_change(&mut self, ((x, y, z), a): Edge, new_size: usize) {
244         //assert!(self.is_edge(((x, y, z), a)));
245         let size = &mut self.size[Space::axis_idx(a)][match a {
246             Axis::X => x,
247             Axis::Y => y,
248             Axis::Z => z,
249         }];
250         if *size != new_size {
251             *size = new_size;
252         }
253     }
255     pub fn edge_size(&mut self, e: Edge, new_size: usize) {
256         self.edge_size_no_change(e, new_size);
257         self.change = Change::Size(e, new_size);
258     }
260     pub fn inc_size(&mut self) {
261         match self.current {
262             Pos::E(e) => {
263                 let size = self.get_edge_size(e);
264                 if size < usize::MAX {
265                     self.edge_size(e, size + 1);
266                 }
267             },
268             Pos::F(_) => panic!("resize on a face"),
269         }
270     }
272     pub fn dec_size(&mut self) {
273         match self.current {
274             Pos::E(e) => {
275                 let size = self.get_edge_size(e);
276                 if size > 0 {
277                     self.edge_size(e, size - 1);
278                 }
279             },
280             Pos::F(_) => panic!("resize on a face"),
281         }
282     }
284     fn face_edges(&self, ((x, y, z), o): Face) -> Vec<Edge> {
285         let mut edges = Vec::new();
286         match o {
287             Ori::Top => {
288                 edges.push(((x, y, z), Axis::X));
289                 edges.push(((x, y, z), Axis::Y));
290                 if x < SPACE_SIZE-1 {
291                     edges.push(((x+1, y, z), Axis::Y));
292                 }
293                 if y > 0 {
294                     edges.push(((x, y-1, z), Axis::X));
295                 }
296             },
297             Ori::Back => {
298                 edges.push(((x, y, z), Axis::X));
299                 edges.push(((x, y, z), Axis::Z));
300                 if x < SPACE_SIZE-1 {
301                     edges.push(((x+1, y, z), Axis::Z));
302                 }
303                 if z < SPACE_SIZE-1 {
304                     edges.push(((x, y, z+1), Axis::X));
305                 }
306             },
307             Ori::Side => {
308                 edges.push(((x, y, z), Axis::Y));
309                 edges.push(((x, y, z), Axis::Z));
310                 if y > 0 {
311                     edges.push(((x, y-1, z), Axis::Z));
312                 }
313                 if z < SPACE_SIZE-1 {
314                     edges.push(((x, y, z+1), Axis::Y));
315                 }
316             },
317         }
318         edges
319     }
321     fn add_empty_node(&mut self, (x, y, z): Coord) {
322         assert!(!self.is_node((x, y, z)));
323         self.faces[x][y][z] = Some([None; NOF_DIM]);
324         println!("empty node change");
325         self.change = Change::Space;
326     }
328     fn adj_available_faces(&self, e: Edge) -> Vec<Face> {
329         Space::adj_faces(e).iter()
330             .filter_map(|&adj_f| if self.is_face(adj_f) {
331                 None
332             } else {
333                 Some(adj_f)
334             }).collect::<Vec<_>>()
335     }
337     fn adj_existing_faces(&self, e: Edge) -> Vec<Face> {
338         Space::adj_faces(e).iter()
339             .filter_map(|&adj_f| if self.is_face(adj_f) {
340                 Some(adj_f)
341             } else {
342                 None
343             }).collect::<Vec<_>>()
344     }
346     fn is_adj_existing_faces(&self, e: Edge) -> bool {
347         for f in Space::adj_faces(e).iter() {
348             if self.is_face(*f) {
349                 return true;
350             }
351         }
352         false
353     }
355     pub fn dec_pos(&mut self) {
356         let tmp = match self.current {
357             Pos::E(((mut x, mut y, mut z), a)) => {
358                 match a {
359                     Axis::X => x -= 1,
360                     Axis::Y => y -= 1,
361                     Axis::Z => z -= 1,
362                 };
363                 (x, y, z)
364             },
365             Pos::F(((mut x, mut y, mut z), o)) => {
366                 match o {
367                     Ori::Top => z -= 1,
368                     Ori::Back => y -= 1,
369                     Ori::Side => x -= 1,
370                 };
371                 (x, y, z)
372             },
373         };
374         if self.is_node(tmp) {
375             println!("pos change");
376             self.change = Change::Current;
377             match self.current {
378                 Pos::E((ref mut n, _)) => *n = tmp,
379                 Pos::F((ref mut n, _)) => *n = tmp,
380             }
381         };
382     }
384     pub fn inc_pos(&mut self) {
385         let tmp = match self.current {
386             Pos::E(((mut x, mut y, mut z), a)) => {
387                 match a {
388                     Axis::X => x += 1,
389                     Axis::Y => y += 1,
390                     Axis::Z => z += 1,
391                 };
392                 (x, y, z)
393             },
394             Pos::F(((mut x, mut y, mut z), o)) => {
395                 match o {
396                     Ori::Top => z += 1,
397                     Ori::Back => y += 1,
398                     Ori::Side => x += 1,
399                 };
400                 (x, y, z)
401             },
402         };
403         if self.is_node(tmp) {
404             println!("pos change");
405             self.change = Change::Current;
406             match self.current {
407                 Pos::E((ref mut n, _)) => *n = tmp,
408                 Pos::F((ref mut n, _)) => *n = tmp,
409             }
410         };
411     }
413     pub fn rotate(&mut self) {
414         println!("rotate change");
415         self.change = Change::Current;
416         match self.current {
417             Pos::E((_, ref mut a)) => match *a {
418                 Axis::X => *a = Axis::Y,
419                 Axis::Y => *a = Axis::Z,
420                 Axis::Z => *a = Axis::X,
421             },
422             Pos::F((_, ref mut o)) => match *o {
423                 Ori::Top => *o = Ori::Back,
424                 Ori::Back => *o = Ori::Side,
425                 Ori::Side => *o = Ori::Top,
426             },
427         }
428     }
430     pub fn set_pos_kind(&mut self, pk: PosKind) {
431         match pk {
432             PosKind::Face => if let Pos::E((c, a)) = self.current {
433                 self.change = Change::Current;
434                 self.current = Pos::F((c, match a {
435                     Axis::X => Ori::Side,
436                     Axis::Y => Ori::Back,
437                     Axis::Z => Ori::Top,
438                 }));
439             },
440             PosKind::Edge => if let Pos::F((c, o)) = self.current {
441                 self.change = Change::Current;
442                 self.current = Pos::E((c, match o {
443                     Ori::Side => Axis::X,
444                     Ori::Back => Axis::Y,
445                     Ori::Top => Axis::Z,
446                 }));
447             },
448         };
449     }
451     pub fn switch_pos_type(&mut self) {
452         println!("switch change");
453         match self.current {
454             Pos::E(_) => self.set_pos_kind(PosKind::Face),
455             Pos::F(_) => self.set_pos_kind(PosKind::Edge),
456         }
457     }
459     fn all_nodes_coord(&self) -> Vec<Coord> {
460         let mut nodes = Vec::new();
461         for x in 0..self.faces.len() {
462             for y in 0..self.faces[x].len() {
463                 for z in 0..self.faces[x][y].len() {
464                     if self.is_node((x, y, z)) {
465                         nodes.push((x, y, z));
466                     }
467                 }
468             }
469         }
470         nodes
471     }
473     fn connecting_edge(&self, f1: Face, f2: Face) -> Option<Edge> {
474         for e1 in self.face_edges(f1) {
475             for e2 in self.face_edges(f2) {
476                 if e1 == e2 {
477                     return Some(e1);
478                 }
479             }
480         }
481         None
482     }
484     fn all_faces(&self) -> Vec<Face> {
485         let mut faces = Vec::new();
486         for n in self.all_nodes_coord() {
487             for &o in [Ori::Top, Ori::Side, Ori::Back].iter() {
488                 if self.is_face((n, o)) {
489                     faces.push((n, o));
490                 }
491             }
492         }
493         faces
494     }
496     fn are_same_face(((ax, ay, az), ao): Face,
497                      ((bx, by, bz), bo): Face) -> bool {
498         ax == bx
499             && ay == by
500             && az == bz
501             && ao == bo
503     }
505     fn faces_map(&self) -> Vec<(Face, Vec<Face>)> {
506         let mut map = Vec::new();
507         for f in self.all_faces() {
508             let mut adj_faces = Vec::new();
509             for &e in self.face_edges(f).iter() {
510                 for &adj_f in self.adj_existing_faces(e).iter() {
511                     if f != adj_f {
512                         adj_faces.push(adj_f);
513                     }
514                 }
515             }
516             map.push((f, adj_faces));
517         }
518         map
519     }
521     fn face_dot_label_fmt(((x, y, z), o): Face, s: &str) -> String {
522         format!("f{0}_{1}_{2}_{3} [label=\"{0} {1} {2} {3}\" {4}]",
523                 x, y, z, Space::ori_idx(o), s)
524     }
526     fn face_dot_fmt(((x, y, z), o): Face) -> String {
527         format!("f{}_{}_{}_{}", x, y, z, Space::ori_idx(o))
528     }
530     pub fn dot_graph_code(&self) -> String {
531         let mut code = String::from("graph {\n");
532         let mut pairs = Vec::new();
533         for (f, adj_fs) in self.faces_map() {
534             code.push_str(&format!("    {};\n", Space::face_dot_label_fmt(f,
535                 if Pos::F(f) == self.current { "color=red" } else { "" })));
536             for adj_f in adj_fs {
537                 pairs.push((f, adj_f));
538             }
539         }
540         let mut i = 0;
541         let pairs_clean = pairs.iter().filter(|&&(a1, b1)| {
542             i += 1;
543             !pairs.iter().take(i-1)
544                   .any(|&(b2, a2)| a1 == a2 && b1 == b2)
545         }).collect::<Vec<_>>();
546         for &(a, b) in pairs_clean {
547             code.push_str(&format!("    {} -- {} {};\n",
548                                    Space::face_dot_fmt(a),
549                                    Space::face_dot_fmt(b),
550                                    if let Some(e) = self.connecting_edge(a, b) {
551                                        if Pos::E(e) == self.current {
552                                            "[color=red]"
553                                        } else { "" }
554                                    } else { "" }));
555         }
556         code.push_str("}");
557         println!("{}", code);
558         code
559     }
561     fn add_empty_node_if_none(&mut self, n: Coord) {
562         if !self.is_node(n) {
563             self.add_empty_node(n);
564         }
565     }
567     fn remove_node(&mut self, (x, y, z): Coord) {
568         assert!(self.is_node((x, y, z)));
569         panic!("nothing here");
570     }
572     fn remove_node_if_any(&mut self, n: Coord) {
573         if self.is_node(n) {
574             self.remove_node(n);
575         }
576     }
578     fn set_face(&mut self, ((x, y, z), o): Face, v: Option<FaceColor>) {
579         match self.faces[x][y][z] {
580             Some(ref mut f) => {
581                 if f[Space::ori_idx(o)] != v {
582                     println!("face change");
583                     self.change = Change::Space;
584                 }
585                 f[Space::ori_idx(o)] = v;
586             },
587             None => panic!("there is no node here"),
588         }
589     }
591     fn face_adj_available_faces(&self, f: Face) -> Vec<Face> {
592         let mut faces = Vec::new();
593         for e in self.face_edges(f) {
594             for adj_f in self.adj_available_faces(e) {
595                 if f != adj_f {
596                     faces.push(adj_f);
597                 }
598             }
599         }
600         faces
601     }
603     fn face_adj_existing_faces(&self, f: Face) -> Vec<Face> {
604         let mut faces = Vec::new();
605         for e in self.face_edges(f) {
606             for adj_f in self.adj_existing_faces(e) {
607                 if f != adj_f {
608                     faces.push(adj_f);
609                 }
610             }
611         }
612         faces
613     }
615     fn suround_with_nodes(&mut self, (n, o): Face) {
616         assert!(self.is_node(n));
617         for (nf, _) in self.face_adj_available_faces((n, o)) {
618             self.add_empty_node_if_none(nf);
619         }
620     }
622     pub fn add_face(&mut self, f: Face) {
623         self.suround_with_nodes(f);
624         self.set_face(f, Some((1.0, 1.0, 1.0)));
625     }
627     pub fn remove_face(&mut self, f: Face) {
628         assert!(self.is_face(f));
629         //panic!("not yet implemented");
630         self.set_face(f, None);
631     }
633     pub fn set_current_face_if_none(&mut self) {
634         match self.current {
635             Pos::F(f) => if !self.is_face(f) { self.add_face(f) },
636             Pos::E(_) => {},
637         }
638     }
641 impl Clone for Space {
642     fn clone(&self) -> Space {
643         Space {
644             size: self.size,
645             faces: self.faces,
646             current: self.current,
647             change: self.change,
648         }
649     }
652 #[derive(Clone)]
653 enum Save {
654     Space(Space),
655     Current(Pos),
656     Size(Edge, usize),
659 pub struct History {
660     saves: Vec<Save>,
661     id: usize,
662     pub change: bool,
665 impl History {
666     fn new() -> History {
667         History {
668             saves: Vec::new(),
669             id: 0,
670             change: false,
671         }
672     }
674     fn add(&mut self, s: Save) {
675         if self.saves.len() > self.id {
676             println!("clear next saves");
677             while self.saves.len() > self.id {
678                 self.saves.pop();
679             }
680         }
681         self.saves.push(s);
682         self.id += 1;
683     }
685     pub fn has_prev(&self) -> bool {
686         self.id > 1
687     }
689     pub fn has_next(&self) -> bool {
690         self.saves.len() > self.id
691     }
693     fn prev(&mut self) -> Save {
694         assert!(self.has_prev());
695         self.id -= 1;
696         self.change = true;
697         self.saves[self.id-1].clone()
698     }
700     fn next(&mut self) -> Save {
701         assert!(self.has_next());
702         self.id += 1;
703         self.change = true;
704         self.saves[self.id-1].clone()
705     }
707     fn current(&self) -> Option<&Save> {
708         if self.id == 0 {
709             None
710         } else {
711             Some(&self.saves[self.id-1])
712         }
713     }
715     fn replace_current(&mut self, s: Save) {
716         assert!(self.id != 0);
717         self.saves[self.id-1] = s;
718     }
721 pub struct Data {
722     pub space: Space,
723     pub history: History,
726 impl Data {
727     pub fn new() -> Data {
728         Data { space: Space::new(), history: History::new() }
729     }
731     fn save_to_add(&self) -> Option<Save> {
732         match self.space.change {
733             Change::Space => {
734                 let mut space = self.space.clone();
735                 space.change = Change::None;
736                 Some(Save::Space(space))
737             }
738             Change::Current => Some(Save::Current(self.space.current)),
739             Change::Size(e, s) => Some(Save::Size(e, s)),
740             Change::None => None,
741         }
742     }
744     pub fn save_if_changed(&mut self) {
745         match self.save_to_add() {
746             Some(Save::Size(e, s)) =>
747                 match self.history.current() {
748                     Some(&Save::Size(e, _)) =>
749                         self.history.replace_current(Save::Size(e, s)),
750                     _ => self.history.add(Save::Size(e, s)),
751                 },
752             Some(s) => self.history.add(s),
753             None => {},
754         }
755         self.space.change = Change::None;
756     }
758     pub fn load_prev(&mut self) {
759         println!("load prev");
760         match self.history.prev() {
761             Save::Current(c) => self.space.current = c,
762             Save::Space(s) => self.space = s,
763             Save::Size(e, s) => self.space.edge_size_no_change(e, s),
764         }
765     }
767     pub fn load_next(&mut self) {
768         println!("load next");
769         match self.history.next() {
770             Save::Current(c) => self.space.current = c,
771             Save::Space(s) => self.space = s,
772             Save::Size(e, s) => self.space.edge_size_no_change(e, s),
773         }
774     }
776     pub fn load_prev_if_any(&mut self) {
777         if self.history.has_prev() {
778             self.load_prev();
779         }
780     }
782     pub fn load_next_if_any(&mut self) {
783         if self.history.has_next() {
784             self.load_next();
785         }
786     }