1    /*
2    Copyright 2000 by Ralph Hartley
3    This software is licenced under the terms of the
4    Gnu Public Licence
5    */
6    
7    import java.io.*;
8    import java.awt.*;
9    import javax.swing.*;
10   
11   public class Unit implements java.io.Serializable,Cloneable {
12   
13     private static final long serialVersionUID = Version.getSUID();
14   
15     public static String GENERIC = "";
16   
17     public static Unit meter = new Unit("meter","meters",false);
18     public static Unit cm = new Unit("cm","cm",0.01,meter,false);
19   
20     public static Unit foot = new Unit("foot","feet",0.3048,meter,false);
21     public static Unit inch = new Unit("inch","inches",0.0254,meter,false);
22     public static Unit pixel = new Unit("pixel","pixels",false);
23   
24   //  public static Unit[] maps = new Unit[] {meter,foot};
25   //  public static Unit[] screens = new Unit[] {cm,inch,pixel};
26   //  public static Unit[] images = new Unit[] {cm,inch,pixel};
27   //  public static Unit[] printers = new Unit[] {cm,inch};
28   
29     static Unit[] predefined = new Unit[] {meter,foot,cm,inch,pixel};
30   
31     public static boolean warncalibration=false;
32   
33     public double size;
34     public Unit base;
35     public String name = null;
36     public String plural = null;
37   
38     public boolean editable;
39   
40     public Unit(String name,String plural,double size,Unit base,boolean editable) {
41       this.editable = editable;
42       this.base = base;
43       this.name = name;
44       this.size = size;
45       this.plural = plural;
46     }
47   
48     public Unit(double size,Unit base,boolean editable) {
49       this.editable = editable;
50       this.base = base;
51       this.size = size;
52     }
53   
54     public Unit(double size,Unit base) {
55       this.editable = true;
56       this.base = base;
57       this.size = size;
58     }
59   
60     public Unit(Unit base) {
61       this.base = base;
62       this.size = 1;
63       editable = true;
64     }
65   
66     public Unit(String name,String plural,boolean editable) {
67       this.name = name;
68       this.plural = plural;
69       size = 1;
70       base = null;
71       this.editable = editable;
72     }
73   
74     public Unit(String name,String plural) {
75       this.name = name;
76       this.plural = plural;
77       size = 1;
78       base = null;
79       editable = true;
80     }
81   
82     public Object clone() {
83       return((Object)new Unit(size,base,editable));
84     }
85   
86     Object readResolve() throws ObjectStreamException {
87       if (name==null) return(this);
88       for (int i=0;i<predefined.length;i++)
89         if (name.compareTo(predefined[i].name)==0) return(predefined[i]);
90       return(this);
91     }
92   
93     public Unit getRoot() {
94       if (base==null) return(this);
95       return(base.getRoot());
96     }
97   
98     public double getRootSize() {
99       if (base==null) return(1.0);
100      else return(size*base.getRootSize());
101    }
102  
103    public double toUnit(Unit that) {
104      if (this.getRoot()!=that.getRoot()) {
105        if (warncalibration)
106          ErrorLog.exception(new Throwable("Conversion between incompatable units (Carto bug) this = "+this+" that = "+that));
107        warncalibration=false;
108        return(that.getRootSize());
109      }
110      return(that.getRootSize()/getRootSize());
111    }
112  
113    public double toUnit(Unit that,double calib) {
114      Unit root0 = getRoot();
115      Unit root1 = that.getRoot();
116      if (root0==root1) return(that.getRootSize()/getRootSize());
117      if (calib<0) {
118        if (warncalibration) {
119          ErrorLog.exception(new CalibrationException("Conversion between pixels & distance with no calibration this = "
120          					    +this+" that = "+that+"\n"+
121          					    "Calibrate and try again."));
122          warncalibration=false;
123        }
124        return(that.getRootSize()/getRootSize());
125      }
126  //    System.out.println("root0 = "+root0+" size = "+getRootSize()+" root1 = "+root1+" size = "+that.getRootSize());
127      if (root0==Unit.meter) return(that.getRootSize()*calib/getRootSize());
128      return(that.getRootSize()/(calib*getRootSize()));
129    }
130  
131    public String toString() {
132      if (plural!=null && plural.compareTo(GENERIC)!=0) return(plural);
133      if (name!=null && name.compareTo(GENERIC)!=0) return(name+"s");
134      return(""+size+base);
135    }
136  
137    transient JTextField valuefield;
138    transient JComboBox basefield;
139  
140    public JPanel getEditor(String lab) {
141      JPanel subpanel = new JPanel(); 
142      valuefield = PrefEditor.addDouble(subpanel,size,lab);
143      basefield = PrefEditor.addUnit(subpanel,base,Unit.predefined,"");
144      return(subpanel);
145    }
146  
147    public void applyEdit() {
148      size = PrefEditor.readDouble(valuefield);
149      base = (Unit)basefield.getSelectedItem();
150      clearEdit();
151    }
152  
153    public void clearEdit() {
154      basefield = null;
155      valuefield = null;
156    }
157  }
158  
159