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
pub struct Undo {
    pub undo_data           : String,
    pub redo_data           : String,
    pub redo_pos            : (usize, usize),

    pub time_stamp          : u128,
}

pub struct UndoStack {
    pub stack               : Vec<Undo>,

    pub index               : isize,
}

impl UndoStack {
    pub fn new() -> Self {
        Self {
            stack           : vec![],
            index           : -1,
        }
    }

    pub fn has_undo(&self) -> bool {
        self.index >= 0
    }

    pub fn has_redo(&self) -> bool {
        if self.index >= -1 && self.index < self.stack.len() as isize - 1 {
            return true;
        }
        false
    }

    pub fn undo(&mut self) -> String {
        let rc = self.stack[self.index as usize].undo_data.clone();
        self.index -= 1;
        rc
    }

    pub fn redo(&mut self) -> (String, (usize, usize)) {
        self.index += 1;
        let rc = (self.stack[self.index as usize].redo_data.clone(), self.stack[self.index as usize].redo_pos.clone());
        rc
    }

    pub fn add(&mut self, undo: String, redo: String, redo_pos: (usize, usize)) {

        if self.index >= 0 {

            let time = self.get_time();

            // If the last item is less than 2s old, replace it
            if time < self.stack[(self.index) as usize].time_stamp + 2000 {

                self.stack[(self.index) as usize].redo_data = redo;
                self.stack[(self.index) as usize].redo_pos = redo_pos;
                self.stack[(self.index) as usize].time_stamp = time;

                return;
            }
        }

        let to_remove = self.stack.len() as isize - self.index - 1;
        for _i in 0..to_remove {
            self.stack.pop();
        }

        self.stack.push(Undo {
            undo_data   : undo,
            redo_data   : redo,
            redo_pos    : redo_pos,
            time_stamp  : self.get_time(),
        });

        self.index += 1;
    }

    fn get_time(&self) -> u128 {
        let stop = std::time::SystemTime::now()
            .duration_since(std::time::UNIX_EPOCH)
            .expect("Time went backwards");
            stop.as_millis()
    }
}