Begin versioning.
[fits.git] / src / nom / tam / fits / HeaderOrder.java
1 package nom.tam.fits;
2
3 /** This class implements a comparator which ensures
4  *  that FITS keywords are written out in a proper order.
5  */
6 public class HeaderOrder implements java.util.Comparator {
7
8     /** Can two cards be exchanged when being written out? */
9     public boolean equals(Object a, Object b) {
10         return compare(a, b) == 0;
11     }
12
13     /** Which order should the cards indexed by these keys
14      *  be written out?  This method assumes that the
15      *  arguments are either the FITS Header keywords as
16      *  strings, and some other type (or null) for comment
17      *  style keywords.
18      *
19      * @return -1 if the first argument should be written first <br>
20      *          1 if the second argument should be written first <br>
21      *          0 if either is legal.
22      */
23     public int compare(Object a, Object b) {
24
25         String c1, c2;
26
27         if (a != null && a instanceof String) {
28             c1 = (String) a;
29         } else {
30             c1 = " ";
31         }
32
33         if (b != null && b instanceof String) {
34             c2 = (String) b;
35         } else {
36             c2 = " ";
37         }
38
39
40         // Equals are equal
41         if (c1.equals(c2)) {
42             return 0;
43         }
44
45         // Now search in the order in which cards must appear
46         // in the header.
47
48         if (c1.equals("SIMPLE") || c1.equals("XTENSION")) {
49             return -1;
50         }
51         if (c2.equals("SIMPLE") || c2.equals("XTENSION")) {
52             return 1;
53         }
54
55         if (c1.equals("BITPIX")) {
56             return -1;
57         }
58         if (c2.equals("BITPIX")) {
59             return 1;
60         }
61
62         if (c1.equals("NAXIS")) {
63             return -1;
64         }
65         if (c2.equals("NAXIS")) {
66             return 1;
67         }
68
69         // Check the NAXISn cards.  These must
70         // be in axis order.
71
72         if (naxisN(c1) > 0) {
73             if (naxisN(c2) > 0) {
74                 if (naxisN(c1) < naxisN(c2)) {
75                     return -1;
76                 } else {
77                     return 1;
78                 }
79             }
80             return -1;
81         }
82
83         if (naxisN(c2) > 0) {
84             return 1;
85         }
86
87         if (c1.equals("PCOUNT")) {
88             return -1;
89         }
90         if (c2.equals("PCOUNT")) {
91             return 1;
92         }
93
94         if (c1.equals("GCOUNT")) {
95             return -1;
96         }
97         if (c2.equals("GCOUNT")) {
98             return 1;
99         }
100
101         if (c1.equals("TFIELDS")) {
102             return -1;
103         }
104         if (c2.equals("TFIELDS")) {
105             return 1;
106         }
107
108         // In principal this only needs to be in the first 36 cards,
109         // but we put it here since it's convenient.  BLOCKED is
110         // deprecated currently.
111         if (c1.equals("BLOCKED")) {
112             return -1;
113         }
114         if (c2.equals("BLOCKED")) {
115             return 1;
116         }
117
118         // Note that this must be at the end, so the
119         // values returned are inverted.
120         if (c1.equals("END")) {
121             return 1;
122         }
123         if (c2.equals("END")) {
124             return -1;
125         }
126
127         // All other cards can be in any order.
128         return 0;
129     }
130
131     /** Find the index for NAXISn keywords */
132     private int naxisN(String key) {
133
134         if (key.length() > 5 && key.substring(0, 5).equals("NAXIS")) {
135             for (int i = 5; i < key.length(); i += 1) {
136
137                 boolean number = true;
138                 char c = key.charAt(i);
139                 if ('0' > c || c > '9') {
140                     number = false;
141                     break;
142                 }
143                 if (number) {
144                     return Integer.parseInt(key.substring(5));
145                 }
146             }
147         }
148         return -1;
149     }
150 }