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