001/*
002 *   DirEntry  -- Represents an IGES directory entry.
003 *
004 *   Copyright (C) 2010-2016, Joseph A. Huwaldt.
005 *   All rights reserved.
006 *   
007 *   This library is free software; you can redistribute it and/or
008 *   modify it under the terms of the GNU Lesser General Public
009 *   License as published by the Free Software Foundation; either
010 *   version 2.1 of the License, or (at your option) any later version.
011 *   
012 *   This library is distributed in the hope that it will be useful,
013 *   but WITHOUT ANY WARRANTY; without even the implied warranty of
014 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
015 *   Lesser General Public License for more details.
016 *
017 *   You should have received a copy of the GNU Lesser General Public License
018 *   along with this program; if not, write to the Free Software
019 *   Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
020 *   Or visit:  http://www.gnu.org/licenses/lgpl.html
021 *
022 *   Based on, but heavily modified from, IGESView ( http://ts.nist.gov/Standards/IGES/igesTools.cfm )
023 */
024package geomss.geom.reader.iges;
025
026import java.io.IOException;
027import java.io.PrintWriter;
028import java.io.RandomAccessFile;
029
030/**
031 * The DirEntry class represents the IGES Directory Entry. This structure contains general
032 * attributes for an entity, such as type, form, color, level, etc. The DirEntry is read
033 * from the file, and then a new Entity is instantiated and read depending on the type and
034 * form in the DirEntry.
035 *
036 * <p> Modified by: Joseph A. Huwaldt </p>
037 *
038 * @author JDN, Version 1.0
039 * @version September 13, 2016
040 */
041public class DirEntry {
042
043    private int Type;               // Identifies the entity type
044    private int PDNum;              // First line of parameter data record for the entity
045    private int Font = 0;           // Line font pattern or negated pointer to Entity304
046    private int Level = 0;          // Number of the level for this entity, or negated pointer to Entity406_1
047    private int View = 0;           // Pointer to Entity410 or Entity402_3/4 or 0
048    private int Matrix = 0;         // Pointer to Entity124 or 0
049    private int LblDsp = 0;         // Pointer to Entity402_5 or 0
050    private String Status = "00000000"; // Status values: aabbccdd where
051    //                                      aa = Blank Status
052    //                                      bb = Subordinate Entity Switch
053    //                                      cc = Entity Use Flag
054    //                                      dd = Hierarchy
055    // See IGES spec for values
056    private int DENum;              // Line count from start of Directory Entry Section (odd)
057    private int Weight = 0;         // System display thickness 0->GlobalSection.LineWeights
058    private int Color = 0;          // Color number or negated pointer to Entity314
059    private int PDCnt;              // Number of lines in parameter data record for this entity
060    private int Form;               // Form number
061    private String Label = "";      // Up to eight alphanumeric characters (right justified)
062    private int Subscr = 0;         // 1 to 8 digit unsigned number associated with the label
063
064    /**
065     * Default constructor.
066     */
067    public DirEntry() { }
068
069    /**
070     * Create a DirEntry from the specified information. Make sure and call "setPDNumber"
071     * before writing an IGES file with this directory entry.
072     *
073     * @param type   The entity type code.
074     * @param form   The entity type form code or 0 for the default.
075     * @param DEnum  The line count from the start of the Directory Entry Section for this
076     *               entry (odd number).
077     * @param matrix An Entity124 DE number or 0.
078     * @param label  A label for this parameter or <code>null</code> or "" for none.
079     */
080    public DirEntry(int type, int form, int DEnum, int matrix, String label) {
081        Type = type;
082        Form = form;
083        DENum = DEnum;
084        Matrix = matrix;
085
086        if (label == null)
087            label = "";
088        else if (label.length() > 8)
089            label = label.substring(0, 8);
090        Label = label;
091    }
092
093    /**
094     * Copy constructor.
095     *
096     * @param de input Directory Entry
097     */
098    public DirEntry(DirEntry de) {
099        Type = de.Type;
100        PDNum = de.PDNum;
101        Font = de.Font;
102        Level = de.Level;
103        View = de.View;
104        Matrix = de.Matrix;
105        LblDsp = de.LblDsp;
106        Status = de.Status;
107        DENum = de.DENum;
108        Weight = de.Weight;
109        Color = de.Color;
110        PDCnt = de.PDCnt;
111        Form = de.Form;
112        Label = de.Label;
113        Subscr = de.Subscr;
114    }
115
116    /**
117     * Read the Directory Entry from a file. This method can handle blank or non-existent
118     * fields.
119     *
120     * @param in input file
121     * @return true if the read was successful, false if the Directory Entry was
122     *         incomplete
123     * @throws IOException if there is any problem reading the directory entry file.
124     */
125    public boolean read(RandomAccessFile in) throws IOException {
126
127        long curloc = in.getFilePointer();
128        String line1 = Constants.myReadLine(in);
129
130        if (line1.charAt(72) != 'D') {
131            in.seek(curloc);
132            return false;
133        }
134
135        String line2 = Constants.myReadLine(in);
136
137        for (int i = 0; i < 10; i++) {
138            String field = (line1.substring(i * 8, (i + 1) * 8)).trim();
139
140                        switch(i) {
141                                case 0: Type   = Constants.toInt(field);                       break;
142                                case 1: PDNum  = Constants.toInt(field);                       break;
143                                case 2:                                                        break; /* Structure */
144                                case 3: Font   = Constants.toInt(field);                       break;
145                                case 4: Level  = Constants.toInt(field);                       break;
146                                case 5: View   = Constants.toInt(field);                       break;
147                                case 6: Matrix = Constants.toInt(field);                       break;
148                                case 7: LblDsp = Constants.toInt(field);                       break;
149                                case 8: Status = field;                                        break;
150                                case 9: DENum  = Constants.toInt((field.substring(1)).trim()); break;
151            }
152        }
153
154        for (int i = 0; i < 10; i++) {
155            String field = (line2.substring(i * 8, (i + 1) * 8)).trim();
156
157                        switch(i) {
158                                case 0:                                  break; /* Type */
159                                case 1: Weight = Constants.toInt(field); break;
160                                case 2: Color  = Constants.toInt(field); break;
161                                case 3: PDCnt  = Constants.toInt(field); break;
162                                case 4: Form   = Constants.toInt(field); break;
163                                case 5:                                  break; /* Reserved */
164                                case 6:                                  break; /* Reserved */
165                                case 7: Label  = field;                  break;
166                                case 8: Subscr = Constants.toInt(field); break;
167                                case 9:                                  break; /* DENUM + 1 */
168            }
169        }
170
171        return true;
172    }
173
174    /**
175     * Write this directory entry out to the exchanged file. Make sure that this directory
176     * entry has the correct parameter data index number (PDNum) and line count (PDCnt)
177     * before calling this method. This typically means that the parameter data for all
178     * the entities must be written first to a temporary buffer so that the PDNum & PDCnt
179     * values can be determined for each, then the directory entries are written and
180     * finally the buffered parameter data is written.
181     *
182     * @param writer The PrintWriter to write the directory entry to.
183     * @throws IOException if there is any problem writing the entry.
184     */
185    public void write(PrintWriter writer) throws IOException {
186
187        //  Write out the 1st line.
188        writer.printf(Constants.US, "%8d", Type);
189        writer.printf(Constants.US, "%8d", PDNum);
190        writer.printf(Constants.US, "%8d", 0);       //  Structure
191        writer.printf(Constants.US, "%8d", Font);
192        writer.printf(Constants.US, "%8d", Level);
193        writer.printf(Constants.US, "%8d", View);
194        writer.printf(Constants.US, "%8d", Matrix);
195        writer.printf(Constants.US, "%8d", LblDsp);
196        writer.print(Status);
197        writer.print("D");
198        writer.println(Constants.makeSequenceNumber(DENum));
199
200        //  Write out the 2nd line.
201        writer.printf(Constants.US, "%8d", Type);
202        writer.printf(Constants.US, "%8d", Weight);
203        writer.printf(Constants.US, "%8d", Color);
204        writer.printf(Constants.US, "%8d", PDCnt);
205        writer.printf(Constants.US, "%8d", Form);
206        writer.print("        ");       //  Reserved
207        writer.print("        ");       //  Reserved
208        writer.print(Constants.padLeft(Label, ' ', 8));
209        writer.printf(Constants.US, "%8d", Subscr);
210        writer.print("D");
211        writer.println(Constants.makeSequenceNumber(DENum + 1));
212
213    }
214
215    /**
216     * Return entity type.
217     *
218     * @return entity type
219     */
220    public int getType() {
221        return Type;
222    }
223
224    /**
225     * Return entity form.
226     *
227     * @return entity form
228     */
229    public int getForm() {
230        return Form;
231    }
232
233    /**
234     * Return Parameter Data line count for this entity.
235     *
236     * @return Parameter Data line count for this entity
237     */
238    public int getPDCnt() {
239        return PDCnt;
240    }
241
242    /**
243     * Return Directory Entry number for this entity.
244     *
245     * @return DE number
246     */
247    public int getDENum() {
248        return DENum;
249    }
250
251    /**
252     * Return Parameter Data number for this entity.
253     *
254     * @return PD number
255     */
256    public int getPDNum() {
257        return PDNum;
258    }
259
260    /**
261     * Return color of this entity.
262     *
263     * @return color of this entity
264     */
265    public int getColor() {
266        return Color;
267    }
268
269    /**
270     * Return line font of this entity.
271     *
272     * @return line font of this entity
273     */
274    public int getFont() {
275        return Font;
276    }
277
278    /**
279     * Return line weight of this entity.
280     *
281     * @return line weight of this entity
282     */
283    public int getWeight() {
284        return Weight;
285    }
286
287    /**
288     * Return level of this entity.
289     *
290     * @return level of this entity
291     */
292    public int getLevel() {
293        return Level;
294    }
295
296    /**
297     * Return view pointer of this entity.
298     *
299     * @return view pointer of this entity
300     */
301    public int getView() {
302        return View;
303    }
304
305    /**
306     * Return matrix pointer of this entity.
307     *
308     * @return matrix pointer of this entity
309     */
310    public int getMatrix() {
311        return Matrix;
312    }
313
314    /**
315     * Return status field of this entity. If the field is less than eight characters, the
316     * string will be padded on the left with zeros.
317     *
318     * @return status field of this entity
319     */
320    public String getStatus() {
321        String outStr = Status;
322        int i;
323
324        if (Status.length() < 8) {
325            for (i = 0; i < (8 - Status.length()); i++)
326                outStr = "0" + outStr;
327        }
328
329        return outStr;
330    }
331
332    /**
333     * Return label display pointer of this entity.
334     *
335     * @return label display pointer of this entity
336     */
337    public int getLblDsp() {
338        return LblDsp;
339    }
340
341    /**
342     * Return the label for this entity. Will return an empty String if there is no label.
343     *
344     * @return The label for this entity.
345     */
346    public String getLabel() {
347        return Label;
348    }
349
350    /**
351     * Set the first line of parameter data record for the entity as well as number of
352     * lines in parameter data record for this entity.
353     *
354     * @param PDnum The first line of parameter data record for the entity.
355     * @param PDcnt The number of lines in the parameter data for this entity.
356     */
357    public void setPDNumber(int PDnum, int PDcnt) {
358        PDNum = PDnum;
359        PDCnt = PDcnt;
360    }
361
362    /**
363     * Dump to String.
364     *
365     * @return String containing the resulting text.
366     */
367    @Override
368    public String toString() {
369        StringBuilder outStr = new StringBuilder("Directory Entry:\n");
370
371                outStr.append("Type =        ");        outStr.append(Type  );  outStr.append("\n");
372                outStr.append("PDNum =       ");        outStr.append(PDNum );  outStr.append("\n");
373                outStr.append("Font =        ");        outStr.append(Font  );  outStr.append("\n");
374                outStr.append("Level =       ");        outStr.append(Level );  outStr.append("\n");
375                outStr.append("View =        ");        outStr.append(View  );  outStr.append("\n");
376                outStr.append("Matrix =      ");        outStr.append(Matrix);  outStr.append("\n");
377                outStr.append("LblDsp =      ");        outStr.append(LblDsp);  outStr.append("\n");
378                outStr.append("Status =      \"");      outStr.append(Status);  outStr.append("\"\n");
379                outStr.append("DENum =       ");        outStr.append(DENum );  outStr.append("\n");
380                outStr.append("Weight =      ");        outStr.append(Weight);  outStr.append("\n");
381                outStr.append("Color =       ");        outStr.append(Color );  outStr.append("\n");
382                outStr.append("PDCnt =       ");        outStr.append(PDCnt );  outStr.append("\n");
383                outStr.append("Form =        ");        outStr.append(Form  );  outStr.append("\n");
384                outStr.append("Label =       \"");      outStr.append(Label );  outStr.append("\"\n");
385                outStr.append("Subscr =      ");        outStr.append(Subscr);
386
387        return outStr.toString();
388    }
389}