001package jmri.jmrit.operations.rollingstock.cars.tools;
002
003import java.awt.Frame;
004import java.awt.event.ActionEvent;
005import java.io.IOException;
006import java.util.Hashtable;
007import java.util.List;
008
009import javax.swing.AbstractAction;
010
011import org.slf4j.Logger;
012import org.slf4j.LoggerFactory;
013
014import jmri.InstanceManager;
015import jmri.jmrit.operations.rollingstock.cars.*;
016import jmri.jmrit.operations.setup.Control;
017import jmri.jmrit.operations.trains.trainbuilder.TrainCommon;
018import jmri.util.davidflanagan.HardcopyWriter;
019
020/**
021 * Action to print a summary of car loads ordered by car type.
022 * <p>
023 * This uses the older style printing, for compatibility with Java 1.1.8 in
024 * Macintosh MRJ
025 *
026 * @author Bob Jacobsen Copyright (C) 2003
027 * @author Dennis Miller Copyright (C) 2005
028 * @author Daniel Boudreau Copyright (C) 2011, 2025
029 */
030public class PrintCarLoadsAction extends AbstractAction {
031
032    public PrintCarLoadsAction(boolean isPreview) {
033        super(isPreview ? Bundle.getMessage("MenuItemCarLoadsPreview") : Bundle.getMessage("MenuItemCarLoadsPrint"));
034        _isPreview = isPreview;
035    }
036
037    /**
038     * Frame hosting the printing
039     */
040    /**
041     * Variable to set whether this is to be printed or previewed
042     */
043    boolean _isPreview;
044
045    @Override
046    public void actionPerformed(ActionEvent e) {
047        new CarLoadPrintOption();
048    }
049
050    public class CarLoadPrintOption {
051
052        static final String TAB = "\t"; // NOI18N
053        static final String NEW_LINE = "\n"; // NOI18N
054
055        // no frame needed for now
056        public CarLoadPrintOption() {
057            super();
058            printCars();
059        }
060
061        private void printCars() {
062
063            // obtain a HardcopyWriter to do this
064            try (HardcopyWriter writer =
065                    new HardcopyWriter(new Frame(), Bundle.getMessage("TitleCarLoads"), Control.reportFontSize, .5,
066                            .5, .5, .5, _isPreview);) {
067
068                writer.write(getHeader());
069
070                // Loop through the Roster, printing as needed
071                String[] carTypes = InstanceManager.getDefault(CarTypes.class).getNames();
072                Hashtable<String, List<CarLoad>> list = InstanceManager.getDefault(CarLoads.class).getList();
073
074                for (String carType : carTypes) {
075                    List<CarLoad> carLoads = list.get(carType);
076                    if (carLoads == null) {
077                        continue;
078                    }
079                    boolean printType = true;
080                    for (CarLoad carLoad : carLoads) {
081                        // don't print out default load or empty
082                        if ((carLoad.getName()
083                                .equals(InstanceManager.getDefault(CarLoads.class).getDefaultEmptyName()) ||
084                                carLoad.getName()
085                                        .equals(InstanceManager.getDefault(CarLoads.class).getDefaultLoadName())) &&
086                                carLoad.getPickupComment().equals(CarLoad.NONE) &&
087                                carLoad.getDropComment().equals(CarLoad.NONE) &&
088                                carLoad.getPriority().equals(CarLoad.PRIORITY_LOW) &&
089                                !carLoad.isHazardous()) {
090                            continue;
091                        }
092                        // print the car type once
093                        if (printType) {
094                            writer.write(carType + NEW_LINE);
095                            printType = false;
096                        }
097                        StringBuffer buf = new StringBuffer(TAB);
098                        buf.append(tabString(carLoad.getName(),
099                                InstanceManager.getDefault(CarLoads.class).getMaxNameLength()));
100                        // load type: load or empty
101                        buf.append(tabString(carLoad.getLoadType(), 5));
102                        // priority low, medium, or high
103                        buf.append(tabString(carLoad.getPriority(), 4));
104                        buf.append(tabString(
105                                carLoad.isHazardous() ? Bundle.getMessage("ButtonYes") : Bundle.getMessage("ButtonNo"),
106                                3));
107                        buf.append(tabString(carLoad.getPickupComment(), 26));
108                        buf.append(tabString(carLoad.getDropComment(), 27).trim());
109                        writer.write(buf.toString() + NEW_LINE);
110                    }
111                }
112            } catch (HardcopyWriter.PrintCanceledException ex) {
113                log.debug("Print canceled");
114            } catch (IOException ex) {
115                log.error("Error printing car roster: {}", ex.getLocalizedMessage());
116            }
117        }
118
119        private String getHeader() {
120            return Bundle.getMessage("Type") +
121                    TAB +
122                    tabString(Bundle.getMessage("Load"),
123                            InstanceManager.getDefault(CarLoads.class).getMaxNameLength()) +
124                    tabString(Bundle.getMessage("Type"), 5) +
125                    tabString(Bundle.getMessage("Priority"), 4) +
126                    tabString(Bundle.getMessage("Hazardous"), 3) +
127                    tabString(Bundle.getMessage("LoadPickupMessage"), 26) +
128                    Bundle.getMessage("LoadDropMessage") +
129                    NEW_LINE;
130        }
131    }
132
133    private static String tabString(String s, int fieldSize) {
134        return TrainCommon.padAndTruncate(s, fieldSize) + " ";
135    }
136
137    private final static Logger log = LoggerFactory.getLogger(PrintCarLoadsAction.class);
138}