001package jmri.jmrix.openlcb.swing.tie;
002
003import java.awt.Font;
004import java.io.IOException;
005import java.util.ResourceBundle;
006import javax.swing.table.AbstractTableModel;
007import jmri.util.davidflanagan.HardcopyWriter;
008import org.slf4j.Logger;
009import org.slf4j.LoggerFactory;
010
011/**
012 * Table Model for access to producer info
013 *
014 * @author Bob Jacobsen 2008
015  * @since 2.3.7
016 */
017public class ProducerTableModel extends AbstractTableModel {
018
019    static ResourceBundle rb = ResourceBundle.getBundle("jmri.jmrix.openlcb.swing.tie.TieBundle");
020
021    public static final int USERNAME_COLUMN = 0;
022    public static final int NODE_COLUMN = 1;
023    public static final int NUMBER_COLUMN = 2;
024    final String[] columnName = new String[]{"User Name", "Node", "Event"};
025
026    @Override
027    public String getColumnName(int c) {
028        return columnName[c];
029    }
030
031    @Override
032    public Class<?> getColumnClass(int c) {
033        return String.class;
034    }
035
036    @Override
037    public boolean isCellEditable(int r, int c) {
038        return false;
039    }
040
041    @Override
042    public int getColumnCount() {
043        return columnName.length;
044    }
045
046    @Override
047    public int getRowCount() {
048        return dummy.length;
049    }
050
051    @Override
052    public Object getValueAt(int r, int c) {
053        return dummy[r][c];  // for testing
054    }
055
056    @Override
057    public void setValueAt(Object type, int r, int c) {
058        // nothing is stored here
059    }
060
061    final String[][] dummy = {{"East Lower Yard Button 1", "12", "1"}, // row then column
062    {"East Lower Yard Button 2", "12", "2"},
063    {"East Lower Yard Button 3", "12", "3"},
064    {"East Lower Yard Button 4", "12", "4"},
065    {"East Lower Yard Button 5", "12", "5"},
066    {"West Lower Yard Button 1", "14", "5"},
067    {"West Lower Yard Button 2", "14", "4"},
068    {"West Lower Yard Button 3", "14", "3"},
069    {"West Lower Yard Button 4", "14", "2"},
070    {"West Lower Yard Button 5", "14", "1"},};
071
072    /**
073     * Method to print or print preview the assignment table. Printed in
074     * proportionately sized columns across the page with headings and vertical
075     * lines between each column. Data is word wrapped within a column. Can only
076     * handle 4 columns of data as strings. Adapted from routines in
077     * BeanTableDataModel.java by Bob Jacobsen and Dennis Miller
078     * @param w hard copy writer connection
079     * @param colWidth array of column widths
080     */
081    public void printTable(HardcopyWriter w, int[] colWidth) {
082        // determine the column sizes - proportionately sized, with space between for lines
083        int[] columnSize = new int[4];
084        int charPerLine = w.getCharactersPerLine();
085        int tableLineWidth = 0;  // table line width in characters
086        int totalColWidth = 0;
087        for (int j = 0; j < 4; j++) {
088            totalColWidth += colWidth[j];
089        }
090        float ratio = ((float) charPerLine) / ((float) totalColWidth);
091        for (int j = 0; j < 4; j++) {
092            columnSize[j] = (int) Math.round(colWidth[j] * ratio - 1.);
093            tableLineWidth += (columnSize[j] + 1);
094        }
095
096        // Draw horizontal dividing line
097        w.write(w.getCurrentLineNumber(), 0, w.getCurrentLineNumber(),
098                tableLineWidth);
099
100        // print the column header labels
101        String[] columnStrings = new String[4];
102        // Put each column header in the array
103        for (int i = 0; i < 4; i++) {
104            columnStrings[i] = this.getColumnName(i);
105        }
106        w.setFontStyle(Font.BOLD);
107        printColumns(w, columnStrings, columnSize);
108        w.setFontStyle(0);
109        // draw horizontal line
110        w.write(w.getCurrentLineNumber(), 0, w.getCurrentLineNumber(),
111                tableLineWidth);
112
113        // now print each row of data
114        String[] spaces = new String[4];
115        // create base strings the width of each of the columns
116        for (int k = 0; k < 4; k++) {
117            spaces[k] = "";
118            for (int i = 0; i < columnSize[k]; i++) {
119                spaces[k] = spaces[k] + " ";
120            }
121        }
122        for (int i = 0; i < this.getRowCount(); i++) {
123            for (int j = 0; j < 4; j++) {
124                //check for special, null contents
125                if (this.getValueAt(i, j) == null) {
126                    columnStrings[j] = spaces[j];
127                } else {
128                    columnStrings[j] = (String) this.getValueAt(i, j);
129                }
130            }
131            printColumns(w, columnStrings, columnSize);
132            // draw horizontal line
133            w.write(w.getCurrentLineNumber(), 0, w.getCurrentLineNumber(),
134                    tableLineWidth);
135        }
136        w.close();
137    }
138
139    protected void printColumns(HardcopyWriter w, String[] columnStrings, int[] columnSize) {
140        StringBuilder columnString = new StringBuilder();
141        StringBuilder lineString = new StringBuilder();
142        String[] spaces = new String[4];
143        // create base strings the width of each of the columns
144        for (int k = 0; k < 4; k++) {
145            spaces[k] = "";
146            for (int i = 0; i < columnSize[k]; i++) {
147                spaces[k] = spaces[k] + " ";
148            }
149        }
150        // loop through each column
151        boolean complete = false;
152        while (!complete) {
153            complete = true;
154            for (int i = 0; i < 4; i++) {
155                // if the column string is too wide cut it at word boundary (valid delimiters are space, - and _)
156                // use the initial part of the text,pad it with spaces and place the remainder back in the array
157                // for further processing on next line
158                // if column string isn't too wide, pad it to column width with spaces if needed
159                if (columnStrings[i].length() > columnSize[i]) {
160                    // this column string will not fit on one line
161                    boolean noWord = true;
162                    for (int k = columnSize[i]; k >= 1; k--) {
163                        if (columnStrings[i].startsWith(" ", k - 1)
164                                || columnStrings[i].startsWith("-", k - 1)
165                                || columnStrings[i].startsWith("_", k - 1)) {
166                            columnString = new StringBuilder(columnStrings[i].substring(0, k));
167                            columnString.append(spaces[i].substring(columnStrings[i].substring(0, k).length()));
168                            columnStrings[i] = columnStrings[i].substring(k);
169                            noWord = false;
170                            complete = false;
171                            break;
172                        }
173                    }
174                    if (noWord) {
175                        columnString = new StringBuilder(columnStrings[i].substring(0, columnSize[i]));
176                        columnStrings[i] = columnStrings[i].substring(columnSize[i]);
177                        complete = false;
178                    }
179                } else {
180                    // this column string will fit on one line
181                    columnString = new StringBuilder(columnStrings[i]);
182                    columnString.append(spaces[i].substring(columnStrings[i].length()));
183                    columnStrings[i] = "";
184                }
185                lineString.append(columnString);
186                lineString.append(" ");
187            }
188            try {
189                w.write(lineString.toString());
190                //write vertical dividing lines
191                int iLine = w.getCurrentLineNumber();
192                for (int i = 0, k = 0; i < w.getCharactersPerLine(); k++) {
193                    w.write(iLine, i, iLine + 1, i);
194                    if (k < 4) {
195                        i = i + columnSize[k] + 1;
196                    } else {
197                        i = w.getCharactersPerLine();
198                    }
199                }
200                w.write("\n");
201                lineString = new StringBuilder();
202            } catch (IOException e) {
203                log.warn("error during printing", e);
204            }
205        }
206    }
207
208    private final static Logger log = LoggerFactory.getLogger(ProducerTableModel.class);
209
210}