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