001package myhw3.data;
002
003import java.util.Map;
004import myhw3.command.CommandHistory;
005import java.util.Comparator;
006import java.util.Collections;
007import java.util.Iterator;
008
009/**
010 * Implementation of Inventory interface.
011 * @see Data
012 */
013final class InventorySet implements Inventory {
014        private Map<Video,Record> data;
015        private final CommandHistory history;
016
017        InventorySet() {
018                // TODO
019                this.data = null;
020                this.history = null;
021                 
022        }
023
024        /**
025         * If <code>record</code> is null, then delete record for <code>video</code>;
026         * otherwise replace record for <code>video</code>.
027         */
028        void replaceEntry(Video video, Record record) {
029                data.remove(video);
030                if (record != null)
031                        data.put(video,record);
032        }
033
034        /**
035         * Overwrite the map.
036         */
037        void replaceMap(Map<Video,Record> data) {
038                this.data = data;
039        }
040
041        public int size() {
042                // TODO
043                return 0;
044        }
045
046        public Record get(Video v) {
047                // TODO
048                return null;
049        }
050
051        public Iterator<Record> iterator() {
052                return Collections.unmodifiableCollection(data.values()).iterator();
053        }
054
055        public boolean undo() {
056                return history.undo();
057        }
058
059        public boolean redo() {
060                return history.redo();
061        }
062
063        public Iterator<Record> iterator(Comparator<Record> comparator) {
064                // TODO
065                return null;
066        }
067
068        /**
069         * Add or remove copies of a video from the inventory.
070         * If a video record is not already present (and change is
071         * positive), a record is created.
072         * If a record is already present, <code>numOwned</code> is
073         * modified using <code>change</code>.
074         * If <code>change</code> brings the number of copies to be zero,
075         * the record is removed from the inventory.
076         * @param video the video to be added.
077         * @param change the number of copies to add (or remove if negative).
078         * @return A copy of the previous record for this video (if any)
079         * @throws IllegalArgumentException if video null, change is zero, if attempting to remove more copies than are owned, or if attempting to remove copies that are checked out.
080         */
081        Record addNumOwned(Video video, int change) {
082                // TODO
083                return null;
084        }
085
086        /**
087         * Check out a video.
088         * @param video the video to be checked out.
089         * @return A copy of the previous record for this video
090         * @throws IllegalArgumentException if video has no record or numOut
091         * equals numOwned.
092         */
093        Record checkOut(Video video) {
094                // TODO
095                return null;
096        }
097
098        /**
099         * Check in a video.
100         * @param video the video to be checked in.
101         * @return A copy of the previous record for this video
102         * @throws IllegalArgumentException if video has no record or numOut
103         * non-positive.
104         */
105        Record checkIn(Video video) {
106                Record r = data.get(video);
107                if (r == null || r.numOut() == 0)
108                        throw new IllegalArgumentException();
109                data.put(video, new RecordObj(video, r.numOwned(), r.numOut()-1, r.numRentals()));
110                return r;
111        }
112
113        /**
114         * Remove all records from the inventory.
115         * @return A copy of the previous inventory as a Map
116         */
117        Map<Video,Record> clear() {
118                // TODO
119                return null;
120        }
121
122        /**
123         * Return a reference to the history.
124         */
125        CommandHistory getHistory() {
126                // TODO
127                return null;
128        }
129
130        public String toString() {
131                StringBuilder buffer = new StringBuilder();
132                buffer.append("Database:\n");
133                Iterator<Record> i = data.values().iterator();
134                while (i.hasNext()) {
135                        buffer.append("  ");
136                        buffer.append(i.next());
137                        buffer.append("\n");
138                }
139                return buffer.toString();
140        }
141
142
143        /**
144         * Implementation of Record interface.
145         *
146         * <p>This is a utility class for Inventory.  Fields are immutable and
147         * package-private.</p>
148         *
149         * <p><b>Class Invariant:</b> No two instances may reference the same Video.</p>
150         *
151         * @see Record
152         */
153        private static final class RecordObj implements Record {
154                final Video video; // the video
155                final int numOwned;   // copies owned
156                final int numOut;     // copies currently rented
157                final int numRentals; // total times video has been rented
158
159                RecordObj(Video video, int numOwned, int numOut, int numRentals) {
160                        this.video = video;
161                        this.numOwned = numOwned;
162                        this.numOut = numOut;
163                        this.numRentals = numRentals;
164                }
165                public Video video() {
166                        return video;
167                }
168                public int numOwned() {
169                        return numOwned;
170                }
171                public int numOut() {
172                        return numOut;
173                }
174                public int numRentals() {
175                        return numRentals;
176                }
177                public String toString() {
178                        StringBuilder buffer = new StringBuilder();
179                        buffer.append(video);
180                        buffer.append(" [");
181                        buffer.append(numOwned);
182                        buffer.append(",");
183                        buffer.append(numOut);
184                        buffer.append(",");
185                        buffer.append(numRentals);
186                        buffer.append("]");
187                        return buffer.toString();
188                }
189        }
190}