001package jmri.jmrit.timetable;
002
003import java.io.File;
004import java.io.BufferedReader;
005import java.io.FileReader;
006import java.io.IOException;
007import java.util.ArrayList;
008import java.util.HashMap;
009import java.util.List;
010
011public class TimeTableImport {
012    BufferedReader bufferedReader;
013    FileReader fileReader;
014    String line;
015    TimeTableDataManager _dm;
016    int _layoutId = 0;
017    int _segmentId = 0;
018    int _scheduleId = 0;
019    int _trainId = 0;
020    int _routeFirst = 0;
021    int _routeLast = 0;
022    List<Integer> _stationIds = new ArrayList<>();
023    HashMap<String, Integer> _typeIds = new HashMap<>();
024
025    public void importSgn(TimeTableDataManager dm, File file) throws IOException {
026        _dm = dm;
027        _dm.setLockCalculate(true);
028        try {
029            fileReader = new FileReader(file);
030            bufferedReader = new BufferedReader(fileReader);
031
032            int row = 1;
033            String currType = "";
034            int stationCount = 0;
035            int typeCount = 0;
036            int trainCount = 0;
037            int stopCount = 0;
038            int stopSeq = 0;
039
040            while ((line = bufferedReader.readLine()) != null) {
041                // Split line and remove double quotes
042                String[] lineStrings = line.split(",(?=([^\"]*\"[^\"]*\")*[^\"]*$)");  // NOI18N
043                for (int i = 0; i < lineStrings.length; i++) {
044                    lineStrings[i] = lineStrings[i].replace("\"", "");
045                }
046
047                switch (row) {
048                    case 1:
049                        log.info("SchedGen Import, version: {}", lineStrings[0]);  // NOI18N
050                        break;
051
052                    case 2:
053                        createLayout(lineStrings);
054                        createSegment(lineStrings);
055                        createSchedule(lineStrings);
056                        break;
057
058                    case 3:
059                        stationCount = Integer.parseInt(lineStrings[0]);
060                        currType = "Station";  // NOI18N
061                        break;
062
063                    default:
064                        if (stationCount > 0) {
065                            createStation(lineStrings);
066                            stationCount--;
067                            break;
068                        }
069
070                        if (currType.equals("Station")) {  // NOI18N
071                            currType = "Type";  // NOI18N
072                            typeCount = Integer.parseInt(lineStrings[0]) + 1;
073                            break;
074                        }
075                        if (typeCount > 0) {
076                            createTrainType(lineStrings);
077                            typeCount--;
078                            break;
079                        }
080
081                        if (currType.equals("Type")) {  // NOI18N
082                            currType = "Train";  // NOI18N
083                            trainCount = Integer.parseInt(lineStrings[0]) + 1;
084                            stopCount = 0;
085                            break;
086                        }
087                        if (trainCount > 0) {
088                            if (stopCount == 0) {
089                                // Create train record
090                                createTrain(lineStrings);
091
092                                stopCount = -1;
093                                break;
094                            }
095                            if (stopCount == -1) {
096                                stopCount = Integer.parseInt(lineStrings[0]);
097                                stopSeq = 1;
098                                _routeFirst = 0;
099                                _routeLast = 0;
100                                break;
101
102                            }
103                            if (stopCount > 0) {
104                                // create stop record
105                                createStop(lineStrings, stopSeq);
106
107                                stopCount--;
108                                stopSeq++;
109                                if (stopCount == 0) {
110                                    int routeDur;
111                                    if (_routeLast > _routeFirst) {
112                                        routeDur = _routeLast - _routeFirst;
113                                    } else {
114                                        routeDur = 1440 - _routeFirst + _routeLast;
115                                    }
116                                    _dm.getTrain(_trainId).setRouteDuration(routeDur);
117
118                                    trainCount--;
119                                }
120                                break;
121                            }
122                        }
123                }
124                row++;
125            }
126        } catch (IOException e) {
127            log.error("Error reading file", e);  // NOI18N
128        } finally {
129            if(bufferedReader != null) {
130               bufferedReader.close();
131            }
132            if(fileReader != null) {
133               fileReader.close();
134            }
135        }
136        _dm.setLockCalculate(false);
137    }
138
139    void createLayout(String[] lineStrings) {
140// "Sierra Western","Default","08/01/11",0,24,"5:1","HO",5
141//         _layoutId = layoutId;
142//         _layoutName = layoutName;
143//         _scale = scale;
144//         _fastClock = fastClock;
145//         _throttles = throttles;
146//         _metric = metric;
147//         String clockString = lineStrings[5].replace("\"", "");
148        String[] clockComp = lineStrings[5].split(":");  // NOI18N
149        int clock = Integer.parseInt(clockComp[0]);
150        int throttles = Integer.parseInt(lineStrings[7]);
151        _layoutId = _dm.getNextId("Layout");  // NOI18N
152        Layout layout = new Layout(_layoutId,
153                lineStrings[0],
154                jmri.ScaleManager.getScale(lineStrings[6]),
155                clock,
156                throttles,
157                false);
158        _dm.addLayout(_layoutId, layout);
159    }
160
161    void createTrainType(String[] lineStrings) {
162// for (int i = 0; i < lineStrings.length; i++) {
163//     log.info("@@ type: {}", lineStrings[i]);
164// }
165// "Freight, general",32768
166//         _typeId = typeId;
167//         _layoutId = layoutId;
168//         _typeName = typeName;
169//          typeColor
170
171        int colorInt = Integer.parseInt(lineStrings[lineStrings.length - 1]);
172        String colorStr = String.format("#%06X", colorInt);  // NOI18N
173        String typeName = lineStrings[0];
174        int typeId = _dm.getNextId("TrainType");  // NOI18N
175        TrainType trainType = new TrainType(typeId,
176                _layoutId,
177                typeName,
178                colorStr);
179        _dm.addTrainType(typeId, trainType);
180        _typeIds.put(typeName, typeId);
181    }
182
183    void createSegment(String[] lineStrings) {
184//         _segmentId = segmentId;
185//         _layoutId = layoutId;
186//         _segmentName = segmentName;
187        _segmentId = _dm.getNextId("Segment");  // NOI18N
188        Segment segment = new Segment(_segmentId,
189                _layoutId,
190                "Mainline");  // NOI18N
191        _dm.addSegment(_segmentId, segment);
192    }
193
194    void createStation(String[] lineStrings) {
195// "Butte",0,0,9,"N"
196//         D S St Dbl
197//         _stationId = stationId;
198//         _segmentId = segmentId;
199//         _stationName = stationName;
200//         _distance = distance;
201//         _doubleTrack = doubleTrack;
202//         _sidings = sidings;
203//         _staging = staging;
204        int stationId = _dm.getNextId("Station");  // NOI18N
205        Station station = new Station(stationId,
206                _segmentId,
207                lineStrings[0],
208                Double.parseDouble(lineStrings[1]),
209                (lineStrings[4].equals("N")) ? false : true,
210                Integer.parseInt(lineStrings[2]),
211                Integer.parseInt(lineStrings[3]));
212        _dm.addStation(stationId, station);
213        _stationIds.add(stationId);
214    }
215
216    void createSchedule(String[] lineStrings) {
217 // "Sierra Western","Default","08/01/11",0,24,"5:1","HO",5
218
219//          _scheduleId = scheduleId;
220//         _layoutId = layoutId;
221//         _scheduleName = scheduleName;
222//         _effDate = effDate;
223//         _startHour = startHour;
224//         _duration = duration;
225        _scheduleId = _dm.getNextId("Schedule");  // NOI18N
226        Schedule schedule = new Schedule(_scheduleId,
227                _layoutId,
228                lineStrings[1],
229                lineStrings[2],
230                Integer.parseInt(lineStrings[3]),
231                Integer.parseInt(lineStrings[4]));
232        _dm.addSchedule(_scheduleId, schedule);
233    }
234
235    void createTrain(String[] lineStrings) {
236// "201","Expediter","Freight,priority",0,740,0,""
237//  name  desc        type              speed start throttle notes
238//         _trainId = trainId;
239//         _scheduleId = scheduleId;
240//         _typeId = typeId;
241//         _trainName = trainName;
242//         _trainDesc = trainDesc;
243//         _defaultSpeed = defaultSpeed;
244//         _startTime = startTime;
245//         _throttle = throttle;
246//         _routeDuration = routeDuration;
247//         _trainNotes = trainNotes;
248        String notes = lineStrings[6];
249
250        int typeId = _typeIds.get(lineStrings[2]);
251        _trainId = _dm.getNextId("Train");  // NOI18N
252        Train train = new Train(_trainId,
253                _scheduleId,
254                typeId,
255                lineStrings[0],
256                lineStrings[1],
257                Integer.parseInt(lineStrings[3]),
258                Integer.parseInt(lineStrings[4]),
259                Integer.parseInt(lineStrings[5]),
260                0,
261                notes);
262        _dm.addTrain(_trainId, train);
263    }
264
265    void createStop(String[] lineStrings, int seq) {
266// 13,0,30,555,555,0,""
267// ST D NX  A   D  T  N
268//         _trainId = trainId;
269//         _stationId = stationId;
270//         _seq = seq;
271//         _duration = duration;
272//         _nextSpeed = nextSpeed;
273//         _arriveTime = arriveTime;
274//         _departTime = departTime;
275//         _stagingTrack = stagingTrack;
276//         _stopNotes = stopNotes;
277
278
279        int _stopId = _dm.getNextId("Stop");  // NOI18N
280        Stop stop = new Stop(_stopId,
281                _trainId,
282                _stationIds.get(Integer.parseInt(lineStrings[0]) - 1),
283                seq,
284                Integer.parseInt(lineStrings[1]),
285                Integer.parseInt(lineStrings[2]),
286                Integer.parseInt(lineStrings[3]),
287                Integer.parseInt(lineStrings[4]),
288                Integer.parseInt(lineStrings[5]),
289                lineStrings[6]);
290        _dm.addStop(_stopId, stop);
291
292        if (seq == 1) {
293            _routeFirst = Integer.parseInt(lineStrings[3]);
294        }
295        _routeLast = Integer.parseInt(lineStrings[4]);
296    }
297
298    private final static org.slf4j.Logger log = org.slf4j.LoggerFactory.getLogger(TimeTableImport.class);
299}