001package jmri.jmrit.operations.routes.tools;
002
003import java.awt.Frame;
004import java.io.IOException;
005import java.util.List;
006
007import org.slf4j.Logger;
008import org.slf4j.LoggerFactory;
009
010import jmri.InstanceManager;
011import jmri.jmrit.operations.routes.*;
012import jmri.jmrit.operations.setup.Control;
013import jmri.jmrit.operations.setup.Setup;
014import jmri.jmrit.operations.trains.trainbuilder.TrainCommon;
015import jmri.util.davidflanagan.HardcopyWriter;
016
017/**
018 * Prints a summary of a route or all routes.
019 * <p>
020 * This uses the older style printing, for compatibility with Java 1.1.8 in
021 * Macintosh MRJ
022 *
023 * @author Bob Jacobsen Copyright (C) 2003
024 * @author Dennis Miller Copyright (C) 2005
025 * @author Daniel Boudreau Copyright (C) 2009, 2012, 2023
026 */
027public class PrintRoutes {
028
029    static final String NEW_LINE = "\n"; // NOI18N
030    static final String TAB = "\t"; // NOI18N
031    static final String SPACE = " ";
032    private static final char FORM_FEED = '\f';
033
034    private static final int MAX_NAME_LENGTH = Control.max_len_string_location_name;
035
036    boolean _isPreview;
037
038    /**
039     * Prints or previews a summary of all routes
040     * 
041     * @param isPreview true if print preview
042     */
043    public PrintRoutes(boolean isPreview) {
044        _isPreview = isPreview;
045        printRoutes();
046    }
047
048    /**
049     * Prints or previews a summary of a route
050     * 
051     * @param isPreview true if print preview
052     * @param route     The route to be printed
053     */
054    public PrintRoutes(boolean isPreview, Route route) {
055        _isPreview = isPreview;
056        printRoute(route);
057    }
058
059    private void printRoutes() {
060        // obtain a HardcopyWriter to do this
061        try (HardcopyWriter writer = new HardcopyWriter(new Frame(), Bundle.getMessage("TitleRoutesTable"),
062                Control.reportFontSize, .5, .5, .5, .5, _isPreview)) {
063
064            writer.write(SPACE); // prevents exception when using Preview and no routes
065            List<Route> routes = InstanceManager.getDefault(RouteManager.class).getRoutesByNameList();
066            for (int i = 0; i < routes.size(); i++) {
067                Route route = routes.get(i);
068                writer.write(route.getName() + NEW_LINE);
069                printRoute(writer, route);
070                if (i != routes.size() - 1) {
071                    writer.write(FORM_FEED);
072                }
073            }
074        } catch (HardcopyWriter.PrintCanceledException ex) {
075            log.debug("Print cancelled");
076        } catch (IOException e1) {
077            log.error("Exception in print routes: {}", e1.getLocalizedMessage());
078        }
079    }
080
081    private void printRoute(Route route) {
082        if (route == null) {
083            return;
084        }
085        // obtain a HardcopyWriter to do this
086        try (HardcopyWriter writer = new HardcopyWriter(new Frame(), Bundle.getMessage("TitleRoute", route.getName()),
087                Control.reportFontSize, .5, .5, .5, .5, _isPreview)) {
088
089            printRoute(writer, route);
090        } catch (HardcopyWriter.PrintCanceledException ex) {
091            log.debug("Print cancelled");
092        } catch (IOException e1) {
093            log.error("Exception in print routes: {}", e1.getLocalizedMessage());
094        }
095    }
096
097    private void printRoute(HardcopyWriter writer, Route route) throws IOException {
098        writer.write(route.getComment() + NEW_LINE);
099        if (!route.getComment().isBlank()) {
100            writer.write(NEW_LINE);
101        }
102
103        writer.write(getPrintHeader1());
104
105        List<RouteLocation> routeList = route.getLocationsBySequenceList();
106        for (RouteLocation rl : routeList) {
107            String s = padAndTruncate(rl.getName(), MAX_NAME_LENGTH) +
108                    rl.getTrainDirectionString() +
109                    TAB +
110                    padAndTruncate(Integer.toString(rl.getMaxCarMoves()), 4) +
111                    padAndTruncate(rl.isPickUpAllowed() ? Bundle.getMessage("yes") : Bundle.getMessage("no"), 6) +
112                    padAndTruncate(rl.isDropAllowed() ? Bundle.getMessage("yes") : Bundle.getMessage("no"), 6) +
113                    (rl.isLocalMovesAllowed() ? Bundle.getMessage("yes") : Bundle.getMessage("no")) +
114                    TAB +
115                    (rl.getWait() + Setup.getTravelTime()) +
116                    TAB +
117                    rl.getMaxTrainLength() +
118                    TAB +
119                    rl.getGrade() +
120                    TAB +
121                    padAndTruncate(Integer.toString(rl.getTrainIconX()), 5) +
122                    rl.getTrainIconY() +
123                    NEW_LINE;
124            writer.write(s);
125        }
126
127        writer.write(getPrintHeader2());
128
129        for (RouteLocation rl : routeList) {
130            String s = padAndTruncate(rl.getName(),
131                    MAX_NAME_LENGTH) + rl.getDepartureTime() + TAB + rl.getComment() + NEW_LINE;
132            writer.write(s);
133        }
134    }
135
136    private String getPrintHeader1() {
137        String s = Bundle.getMessage("Location") +
138                TAB +
139                "    " +
140                Bundle.getMessage("Direction") +
141                SPACE +
142                Bundle.getMessage("MaxMoves") +
143                SPACE +
144                Bundle.getMessage("Pull?") +
145                SPACE +
146                Bundle.getMessage("Drop?") +
147                SPACE +
148                Bundle.getMessage("Local?") +
149                SPACE +
150                Bundle.getMessage("Travel") +
151                TAB +
152                Bundle.getMessage("Length") +
153                TAB +
154                Bundle.getMessage("Grade") +
155                TAB +
156                Bundle.getMessage("X") +
157                "    " +
158                Bundle.getMessage("Y") +
159                NEW_LINE;
160        return s;
161    }
162
163    private String getPrintHeader2() {
164        String s = NEW_LINE +
165                Bundle.getMessage("Location") +
166                TAB +
167                Bundle.getMessage("DepartTime") +
168                TAB +
169                Bundle.getMessage("Comment") +
170                NEW_LINE;
171        return s;
172    }
173
174    private String padAndTruncate(String string, int fieldSize) {
175        return TrainCommon.padAndTruncate(string, fieldSize);
176    }
177
178    private final static Logger log = LoggerFactory.getLogger(PrintRoutes.class);
179}