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
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
use im::HashMap;
use logisheets_base::{BlockRange, NormalRange, Range, RangeId, SheetId};

#[derive(Debug, Clone, Default)]
pub struct RangeManager {
    data: HashMap<SheetId, SheetRangeManager>,
}

impl RangeManager {
    pub fn new() -> Self {
        RangeManager {
            data: HashMap::new(),
        }
    }

    pub fn get_range(&self, sheet_id: &SheetId, range_id: &RangeId) -> Option<Range> {
        self.data.get(sheet_id)?.get_range(range_id)
    }

    pub fn get_range_id_assert(&self, sheet_id: &SheetId, range: &Range) -> Option<RangeId> {
        self.data.get(&sheet_id)?.get_range_id_assert(range)
    }

    pub fn get_range_id(&mut self, sheet_id: &SheetId, range: &Range) -> RangeId {
        if let Some(sheet_manager) = self.data.get_mut(sheet_id) {
            sheet_manager.get_range_id(range)
        } else {
            let mut manager = SheetRangeManager::new();
            let result = manager.get_range_id(range);
            self.data.insert(*sheet_id, manager);
            result
        }
    }

    pub fn remove_range_id(&mut self, sheet_id: &SheetId, range_id: &RangeId) {
        if let Some(sheet_manager) = self.data.get_mut(sheet_id) {
            sheet_manager.remove_range_id(range_id)
        }
    }

    pub fn get_sheet_range_manager(&mut self, sheet_id: &SheetId) -> &mut SheetRangeManager {
        if !self.data.contains_key(sheet_id) {
            self.data.insert(*sheet_id, SheetRangeManager::new());
        }
        self.data.get_mut(sheet_id).unwrap()
    }

    pub fn add_sheet_range_manager(
        &mut self,
        sheet_id: &SheetId,
        sheet_manager: SheetRangeManager,
    ) {
        self.data.insert(*sheet_id, sheet_manager);
    }
}

#[derive(Debug, Clone)]
pub struct SheetRangeManager {
    pub id_to_normal_range: HashMap<RangeId, NormalRange>,
    pub normal_range_to_id: HashMap<NormalRange, RangeId>,
    pub id_to_block_range: HashMap<RangeId, BlockRange>,
    pub block_range_to_id: HashMap<BlockRange, RangeId>,
    pub next_id: RangeId,
}

impl SheetRangeManager {
    pub fn new() -> Self {
        SheetRangeManager {
            id_to_normal_range: HashMap::new(),
            normal_range_to_id: HashMap::new(),
            id_to_block_range: HashMap::new(),
            block_range_to_id: HashMap::new(),
            next_id: 0,
        }
    }

    pub fn get_range_id_assert(&self, range: &Range) -> Option<RangeId> {
        match range {
            Range::Normal(normal) => Some(self.normal_range_to_id.get(normal)?.clone()),
            Range::Block(b) => Some(self.block_range_to_id.get(b)?.clone()),
        }
    }

    pub fn get_range(&self, range_id: &RangeId) -> Option<Range> {
        if let Some(normal_range) = self.id_to_normal_range.get(range_id) {
            return Some(Range::Normal(normal_range.clone()));
        }
        match self.id_to_block_range.get(range_id) {
            Some(block_range) => Some(Range::Block(block_range.clone())),
            None => None,
        }
    }

    pub fn remove_range_id(&mut self, range_id: &RangeId) {
        if let Some(range) = self.id_to_normal_range.remove(range_id) {
            self.normal_range_to_id.remove(&range);
        }
        if let Some(range) = self.id_to_block_range.remove(range_id) {
            self.block_range_to_id.remove(&range);
        }
    }

    pub fn get_range_id(&mut self, range: &Range) -> RangeId {
        match range {
            Range::Normal(normal_range) => match self.normal_range_to_id.get(normal_range) {
                Some(id) => *id,
                None => {
                    let r = normal_range.clone();
                    let id = self.next_id;
                    self.normal_range_to_id.insert(r.clone(), id);
                    self.id_to_normal_range.insert(id, r);
                    self.next_id += 1;
                    id
                }
            },
            Range::Block(block_range) => match self.block_range_to_id.get(block_range) {
                Some(id) => *id,
                None => {
                    let r = block_range.clone();
                    let id = self.next_id;
                    self.block_range_to_id.insert(r.clone(), id);
                    self.id_to_block_range.insert(id, r);
                    self.next_id += 1;
                    id
                }
            },
        }
    }
}