1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
use crate::trigram::{
    self,
    Trigram,
    trigram_name_pair_as_symbol,
    TrigramNamePair,
};

#[derive(Clone, Copy)]
pub enum HexagramOrdering {
    KingWen,
    // a.k.a Fu Xi sequence, , Shao Yong sequence
    Binary,
    Mawangdui,
    EightPalaces,
}

pub struct Hexagram {
    _above: Trigram,
    _below: Trigram,
}

impl Hexagram {
    pub fn new() -> Self {
        Self::default()
    }

    pub fn symbol(&self, with_changes: bool) -> &str {
        trigram_name_pair_as_symbol(&self.as_trigram_name_pair(with_changes))
    }

    pub fn as_number(&self, with_changes: bool, sequence: HexagramOrdering) -> usize {
        use self::HexagramOrdering::*;
        let trigram_name_pair: TrigramNamePair = self.as_trigram_name_pair(with_changes);

        match sequence {
            KingWen => trigram::king_wen_sequence_number(&trigram_name_pair),
            Binary => trigram::binary_sequence_number(&trigram_name_pair),
            Mawangdui => trigram::mawangdui_sequence_number(&trigram_name_pair),
            EightPalaces => trigram::eight_palaces_sequence_number(&trigram_name_pair),
        }
    }

    pub fn as_trigram_name_pair(&self, with_changes: bool) -> TrigramNamePair {
        (self._above.get_name(with_changes), self._below.get_name(with_changes))
    }
}

impl Default for Hexagram {
    fn default() -> Self {
        Hexagram {
            _above: Trigram::default(),
            _below: Trigram::default(),
        }
    }
}