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, null, null, Control.reportFontSize, .5 * 72, .5 * 72, .5 * 72,
051                        .5 * 72, _isPreview, "", false, true, null, null)) {
052
053            printTrains(writer);
054
055        } catch (HardcopyWriter.PrintCanceledException ex) {
056            log.debug("Print canceled");
057        } catch (IOException we) {
058            log.error("Error printing PrintLocationAction: {}", we.getLocalizedMessage());
059        }
060    }
061
062    private void printTrains(HardcopyWriter writer) throws IOException {
063        // show track name if selected
064        if (_track != null) {
065            writer.write(Bundle.getMessage("Track") + TAB + _track.getName() + NEW_LINE);
066        }
067        // show car type if selected
068        if (!_carType.isEmpty()) {
069            writer.write(Bundle.getMessage("Type") + TAB + _carType + NEW_LINE);
070        }
071        writer.write(getHeader());
072        for (Train train : InstanceManager.getDefault(TrainManager.class).getTrainsByNameList()) {
073            Route route = train.getRoute();
074            if (route == null) {
075                continue;
076            }
077            // determine if the car type is accepted by train
078            if (!_carType.isEmpty() && !train.isTypeNameAccepted(_carType)) {
079                continue;
080            }
081            for (RouteLocation rl : route.getLocationsBySequenceList()) {
082                if (_location != null && rl.getName().equals(_location.getName())) {
083                    boolean pickup = false;
084                    boolean setout = false;
085                    if (rl.isPickUpAllowed() &&
086                            rl.getMaxCarMoves() > 0 &&
087                            !train.isLocationSkipped(rl) &&
088                            (train.isLocalSwitcher() ||
089                                    (rl.getTrainDirection() & _location.getTrainDirections()) != 0) &&
090                            (train.isLocalSwitcher() ||
091                                    _track == null ||
092                                    ((rl.getTrainDirection() & _track.getTrainDirections()) != 0)) &&
093                            (_track == null || _track.isPickupTrainAccepted(train))) {
094                        pickup = true;
095                    }
096                    if (rl.isDropAllowed() &&
097                            rl.getMaxCarMoves() > 0 &&
098                            !train.isLocationSkipped(rl) &&
099                            (train.isLocalSwitcher() ||
100                                    (rl.getTrainDirection() & _location.getTrainDirections()) != 0) &&
101                            (train.isLocalSwitcher() ||
102                                    _track == null ||
103                                    ((rl.getTrainDirection() & _track.getTrainDirections()) != 0)) &&
104                            (_track == null || _track.isDropTrainAccepted(train)) &&
105                            (_track == null ||
106                                    _carType.isEmpty() ||
107                                    _track.checkScheduleAttribute(Track.TYPE, _carType, null))) {
108                        setout = true;
109                    }
110                    // now display results
111                    if (pickup || setout) {
112                        // Train name, direction, pick ups? set outs?
113                        StringBuffer sb =
114                                new StringBuffer(padOutString(train.getName(), Control.max_len_string_train_name));
115
116                        // train direction when servicing this location
117                        sb.append(rl.getTrainDirectionString() + TAB);
118                        if (pickup) {
119                            sb.append(Bundle.getMessage("OkayPickUp") + TAB);
120                        } else {
121                            sb.append(Bundle.getMessage("NoPickUp") + TAB);
122                        }
123                        if (setout) {
124                            sb.append(Bundle.getMessage("OkaySetOut"));
125                        } else {
126                            sb.append(Bundle.getMessage("NoSetOut"));
127                        }
128                        writer.write(sb.toString() + NEW_LINE);
129                    }
130                }
131            }
132        }
133    }
134
135    private String getHeader() {
136        String s = padOutString(Bundle.getMessage("Trains"), Control.max_len_string_train_name) +
137                Bundle.getMessage("AbbrevationDirection") +
138                TAB +
139                Bundle.getMessage("Pickups") +
140                TAB +
141                Bundle.getMessage("Drop") +
142                NEW_LINE;
143        return s;
144    }
145
146    private String padOutString(String s, int length) {
147        return TrainCommon.padAndTruncate(s, length);
148    }
149
150    private final static Logger log = LoggerFactory.getLogger(PrintTrainsServingLocation.class);
151}