001package jmri.jmrit.operations.locations.tools;
002
003import java.awt.Frame;
004import java.io.IOException;
005
006import org.slf4j.Logger;
007import org.slf4j.LoggerFactory;
008
009import jmri.InstanceManager;
010import jmri.jmrit.operations.locations.Location;
011import jmri.jmrit.operations.locations.Track;
012import jmri.jmrit.operations.routes.Route;
013import jmri.jmrit.operations.routes.RouteLocation;
014import jmri.jmrit.operations.setup.Control;
015import jmri.jmrit.operations.trains.Train;
016import jmri.jmrit.operations.trains.TrainManager;
017import jmri.jmrit.operations.trains.trainbuilder.TrainCommon;
018import jmri.util.davidflanagan.HardcopyWriter;
019
020/**
021 * @author Daniel Boudreau Copyright (C) 2024
022 */
023public class PrintTrainsServingLocation {
024
025    public static final String NEW_LINE = "\n"; // NOI18N
026    static final String TAB = "\t"; // NOI18N
027
028    boolean _isPreview;
029    Location _location;
030    Track _track;
031    String _carType;
032
033    public PrintTrainsServingLocation(boolean isPreview, Location location, Track track, String carType) {
034        super();
035        _isPreview = isPreview;
036        _location = location;
037        _track = track;
038        _carType = carType;
039        printLocations();
040    }
041
042    private void printLocations() {
043
044        // obtain a HardcopyWriter
045        String title = Bundle.getMessage("TitleLocationsTable");
046        if (_location != null) {
047            title = _location.getName();
048        }
049        try (HardcopyWriter writer =
050                new HardcopyWriter(new Frame(), title, Control.reportFontSize, .5, .5, .5, .5, _isPreview)) {
051
052            printTrains(writer);
053
054        } catch (HardcopyWriter.PrintCanceledException ex) {
055            log.debug("Print canceled");
056        } catch (IOException we) {
057            log.error("Error printing PrintLocationAction: {}", we.getLocalizedMessage());
058        }
059    }
060
061    private void printTrains(HardcopyWriter writer) throws IOException {
062        // show track name if selected
063        if (_track != null) {
064            writer.write(Bundle.getMessage("Track") + TAB + _track.getName() + NEW_LINE);
065        }
066        // show car type if selected
067        if (!_carType.isEmpty()) {
068            writer.write(Bundle.getMessage("Type") + TAB + _carType + NEW_LINE);
069        }
070        writer.write(getHeader());
071        for (Train train : InstanceManager.getDefault(TrainManager.class).getTrainsByNameList()) {
072            Route route = train.getRoute();
073            if (route == null) {
074                continue;
075            }
076            // determine if the car type is accepted by train
077            if (!_carType.isEmpty() && !train.isTypeNameAccepted(_carType)) {
078                continue;
079            }
080            for (RouteLocation rl : route.getLocationsBySequenceList()) {
081                if (_location != null && rl.getName().equals(_location.getName())) {
082                    boolean pickup = false;
083                    boolean setout = false;
084                    if (rl.isPickUpAllowed() &&
085                            rl.getMaxCarMoves() > 0 &&
086                            !train.isLocationSkipped(rl) &&
087                            (train.isLocalSwitcher() ||
088                                    (rl.getTrainDirection() & _location.getTrainDirections()) != 0) &&
089                            (train.isLocalSwitcher() ||
090                                    _track == null ||
091                                    ((rl.getTrainDirection() & _track.getTrainDirections()) != 0)) &&
092                            (_track == null || _track.isPickupTrainAccepted(train))) {
093                        pickup = true;
094                    }
095                    if (rl.isDropAllowed() &&
096                            rl.getMaxCarMoves() > 0 &&
097                            !train.isLocationSkipped(rl) &&
098                            (train.isLocalSwitcher() ||
099                                    (rl.getTrainDirection() & _location.getTrainDirections()) != 0) &&
100                            (train.isLocalSwitcher() ||
101                                    _track == null ||
102                                    ((rl.getTrainDirection() & _track.getTrainDirections()) != 0)) &&
103                            (_track == null || _track.isDropTrainAccepted(train)) &&
104                            (_track == null ||
105                                    _carType.isEmpty() ||
106                                    _track.checkScheduleAttribute(Track.TYPE, _carType, null))) {
107                        setout = true;
108                    }
109                    // now display results
110                    if (pickup || setout) {
111                        // Train name, direction, pick ups? set outs?
112                        StringBuffer sb =
113                                new StringBuffer(padOutString(train.getName(), Control.max_len_string_train_name));
114
115                        // train direction when servicing this location
116                        sb.append(rl.getTrainDirectionString() + TAB);
117                        if (pickup) {
118                            sb.append(Bundle.getMessage("OkayPickUp") + TAB);
119                        } else {
120                            sb.append(Bundle.getMessage("NoPickUp") + TAB);
121                        }
122                        if (setout) {
123                            sb.append(Bundle.getMessage("OkaySetOut"));
124                        } else {
125                            sb.append(Bundle.getMessage("NoSetOut"));
126                        }
127                        writer.write(sb.toString() + NEW_LINE);
128                    }
129                }
130            }
131        }
132    }
133
134    private String getHeader() {
135        String s = padOutString(Bundle.getMessage("Trains"), Control.max_len_string_train_name) +
136                Bundle.getMessage("AbbrevationDirection") +
137                TAB +
138                Bundle.getMessage("Pickups") +
139                TAB +
140                Bundle.getMessage("Drop") +
141                NEW_LINE;
142        return s;
143    }
144
145    private String padOutString(String s, int length) {
146        return TrainCommon.padAndTruncate(s, length);
147    }
148
149    private final static Logger log = LoggerFactory.getLogger(PrintTrainsServingLocation.class);
150}