summaryrefslogtreecommitdiff
path: root/src/main/java/design/model/holeplay/HolePlayContext.java
blob: 71fba323a8525f60d66a414a85041cc2013a95b4 (plain) (blame)
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
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
package design.model.holeplay;

import java.io.IOException;
import java.util.ArrayList;

import design.model.*;
import design.persistence.PersonalDatabase;

import design.model.undo.Memento;
import design.model.undo.Originator;

public class HolePlayContext implements Originator {
    private final Golfer golfer;
    private final Round round;
    private final PersonalDatabase pdb;

    private HoleState state;
    private Play currentPlay;
    private int strokes;

    public HolePlayContext(Golfer golfer, Round round, PersonalDatabase pdb) {
        this.golfer = golfer;
        this.round = round;
        this.pdb = pdb;
        setState(new SetupState());
    }

    public void setState(HoleState next) {
        this.state = next;
        next.enter(this);
    }

    // API the PTUI/Commands will call:
    public void startHole() {
        state.handleStart(this);
    }

    public void recordShot(Club club, Integer distanceYds) {
        state.handleShot(this, club, distanceYds);
    }

    public void holeOut() {
        state.handleHoleOut(this);
    }

    void beginNewPlay(int holeNumber) {
        this.currentPlay = new Play(holeNumber);
        this.strokes = 0;
    }

    void addSwing(Club club, Integer distanceYds) {
        // Checks golfer owns club maybe not necessary
        // if (golfer.hasClub(club)) {
        // throw new IllegalArgumentException("Club not in golfer's bag");
        // }
        int d = (distanceYds == null ? 0 : distanceYds);
        this.currentPlay.addSwing(new Swing(d, club));
        this.strokes++;

    }

    void finalizePlayAndPersist() {
        round.addPlay(currentPlay);
        round.nextHole();
        currentPlay = null;
        strokes = 0;
        // Not sure if try catch is necessary
        try {
            pdb.updateGolfer(golfer);
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }

    public void clearInProgressPlay() {
        this.setCurrentPlay(null);
        this.setStrokes(0);
    }

    public void endRoundNow() {
        try {
            pdb.updateGolfer(golfer); // persist whatever’s done so far
        } catch (IOException e) {
            e.printStackTrace();
        }
        setState(new SetupState());
    }

    // getters you’ll want:
    public Golfer getGolfer() {
        return golfer;
    }

    public Round getRound() {
        return round;
    }

    public Play getCurrentPlay() {
        return currentPlay;
    }

    public int getStrokes() {
        return strokes;
    }

    // setters used internally
    void setCurrentPlay(Play p) {
        this.currentPlay = p;
    }

    void setStrokes(int s) {
        this.strokes = s;
    }

    // Captures current State, current play (hole# + swings), and stroke counter
    private static class HolePlayMemento implements Memento {
        private final String stateName;
        private final Play currentPlayCopy;
        private final int strokesCopy;

        HolePlayMemento(HolePlayContext ctx) {
            this.stateName = ctx.state.name();

            // Copy currentPlay if it exists
            Play src = ctx.currentPlay;
            if (src != null) {
                var copySwings = new ArrayList<Swing>();
                for (Swing s : src.getSwings()) {
                    copySwings.add(new Swing(s.getDistance(), s.getClubUsed()));
                }
                this.currentPlayCopy = new Play(src.getHoleNumber(), copySwings);
            } else {
                this.currentPlayCopy = null;
            }

            this.strokesCopy = ctx.strokes;
        }
    }

    @Override
    public Memento createMemento() {
        return new HolePlayMemento(this);
    }

    @Override
    public void restore(Memento m) {
        HolePlayMemento hm = (HolePlayMemento) m;

        // restore strokes
        this.strokes = hm.strokesCopy;

        // restore currentPlay
        if (hm.currentPlayCopy == null) {
            this.currentPlay = null;
        } else {
            var copySwings = new ArrayList<Swing>();
            for (Swing s : hm.currentPlayCopy.getSwings()) {
                copySwings.add(new Swing(s.getDistance(), s.getClubUsed()));
            }
            this.currentPlay = new Play(hm.currentPlayCopy.getHoleNumber(), copySwings);
        }

        // restore state based on name
        switch (hm.stateName) {
            case "SetupState" -> this.state = new SetupState();
            case "PlayState" -> this.state = new PlayState();
            case "HoleCompleteState" -> this.state = new HoleCompleteState();
        }
    }
}