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