1    /*
2     * Copyright 2009 :torweg free software group
3     *
4     * This program is free software: you can redistribute it and/or modify
5     * it under the terms of the GNU General Public License as published by
6     * the Free Software Foundation, either version 3 of the License, or
7     * (at your option) any later version.
8     * 
9     * This program is distributed in the hope that it will be useful,
10    * but WITHOUT ANY WARRANTY; without even the implied warranty of
11    * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12    * GNU General Public License for more details.
13    * 
14    * You should have received a copy of the GNU General Public License
15    * along with this program.  If not, see <http://www.gnu.org/licenses/>.
16    *
17    */
18   package org.torweg.pulse.component.statistics.model;
19   
20   import javax.persistence.Basic;
21   import javax.persistence.Column;
22   import javax.persistence.EnumType;
23   import javax.persistence.Enumerated;
24   import javax.persistence.MappedSuperclass;
25   import javax.xml.bind.annotation.XmlAccessOrder;
26   import javax.xml.bind.annotation.XmlAccessType;
27   import javax.xml.bind.annotation.XmlAccessorOrder;
28   import javax.xml.bind.annotation.XmlAccessorType;
29   import javax.xml.bind.annotation.XmlAttribute;
30   
31   import org.torweg.pulse.util.entity.AbstractBasicEntity;
32   
33   /**
34    * A abstract base class to derive an "entity representing a resolution" from.
35    * <p>
36    * To be removed if no further sub-classes are to be derived from
37    * {@code AbstractResolution}.
38    * </p>
39    * 
40    * @author Thomas Weber
41    * @version $Revision: 1548 $
42    */
43   @XmlAccessorOrder(XmlAccessOrder.UNDEFINED)
44   @XmlAccessorType(XmlAccessType.FIELD)
45   @MappedSuperclass
46   public abstract class AbstractResolution extends AbstractBasicEntity {
47   
48       /**
49        * serialVersionUID.
50        */
51       private static final long serialVersionUID = -268176471990956789L;
52   
53       /**
54        * The available pixels in horizontal direction.
55        */
56       @Basic(optional = false)
57       @XmlAttribute(name = "x")
58       private Integer x;
59   
60       /**
61        * The available pixels in vertical direction.
62        */
63       @Basic(optional = false)
64       @XmlAttribute(name = "y")
65       private Integer y;
66   
67       /**
68        * The format.
69        */
70       @Enumerated(EnumType.STRING)
71       @Column(nullable = false)
72       @XmlAttribute(name = "format")
73       private ScreenResolution.Format format;
74   
75       /**
76        * Used by Hibernate<sup>TM</sup> and JAXB.
77        */
78       @Deprecated
79       protected AbstractResolution() {
80           super();
81       }
82   
83       /**
84        * Creates a new resolution.
85        * 
86        * @param xRes
87        *            pixels in horizontal direction
88        * @param yRes
89        *            pixels in vertical direction
90        */
91       public AbstractResolution(final int xRes, final int yRes) {
92           super();
93           this.x = Integer.valueOf(xRes);
94           this.y = Integer.valueOf(yRes);
95           this.format = Format.getFormat(xRes, yRes);
96       }
97   
98       /**
99        * Creates a default {@code ScreenResolution}.
100       * 
101       * @param f
102       *            the {@code ScreenResolution.Format}
103       */
104      protected AbstractResolution(final Format f) {
105          super();
106          this.format = f;
107          this.x = -1;
108          this.y = -1;
109      }
110  
111      /**
112       * Returns the available pixels in horizontal direction.
113       * 
114       * @return the available pixels in horizontal direction
115       */
116      public final Integer getX() {
117          return this.x;
118      }
119  
120      /**
121       * Returns the available pixels in vertical direction.
122       * 
123       * @return the available pixels in vertical direction
124       */
125      public final Integer getY() {
126          return this.y;
127      }
128  
129      /**
130       * Returns the format.
131       * 
132       * @return the format
133       */
134      public final ScreenResolution.Format getFormat() {
135          return this.format;
136      }
137  
138      /**
139       * Returns whether the {@code ScreenResolution} matches the given
140       * {@code ScreenResolution.Format}.
141       * 
142       * @param f
143       *            the {@code ScreenResolution.Format}
144       * 
145       * @return {@code true} if and only if the formats match,
146       *         {@code false} otherwise
147       */
148      public final boolean isFormat(final ScreenResolution.Format f) {
149          return this.format.equals(f);
150      }
151  
152      /**
153       * Checks the given values for x- and y-resolution against the x- and
154       * y-values of the {@code ScreenResolution}.
155       * 
156       * @param xyRes
157       *            the x-y-resolution
158       * 
159       * @return {@code true} if and only if the given values for x- and
160       *         y-resolution are a match against the x- and y-values of the
161       *         {@code ScreenResolution}, {@code false} otherwise
162       */
163      public final boolean isMatch(final int[] xyRes) {
164          return isMatch(xyRes[0], xyRes[1]);
165      }
166  
167      /**
168       * Checks the given values for x- and y-resolution against the x- and
169       * y-values of the {@code ScreenResolution}.
170       * 
171       * @param xRes
172       *            the x-resolution
173       * @param yRes
174       *            the y-resolution
175       * 
176       * @return {@code true} if and only if the given values for x- and
177       *         y-resolution are a match against the x- and y-values of the
178       *         {@code ScreenResolution}, {@code false} otherwise
179       */
180      public final boolean isMatch(final int xRes, final int yRes) {
181          return ((this.x == xRes) && (this.y == yRes));
182      }
183  
184      /**
185       * Checks the values the x- and y-values of the given
186       * {@code ScreenResolution} against the x- and y-values of the
187       * {@code ScreenResolution}.
188       * 
189       * @param screenResolution
190       *            the {@code ScreenResolution}
191       * 
192       * @return {@code true} if and only if the given
193       *         {@code ScreenResolution} is a match against the x- and
194       *         y-values of the {@code ScreenResolution}, {@code false}
195       *         otherwise
196       */
197      public final boolean isMatch(final ScreenResolution screenResolution) {
198          return (isMatch(screenResolution.getX(), screenResolution.getY()) && this.format
199                  .equals(screenResolution.getFormat()));
200      }
201  
202      /**
203       * Returns a string-representation of the {@code ScreenResolution}.
204       * 
205       * @return a string-representation
206       */
207      @Override
208      public final String toString() {
209          return "{" + super.toString() + "@[" + getId() + "], x: " + getX()
210                  + ", y: " + getY() + ", format: " + getFormat() + "}";
211      }
212  
213      /**
214       * Enumerates the formats for screen resolutions.
215       */
216      public enum Format {
217  
218          /**
219           * upright format (e.g. handheld computers).
220           * <p>
221           * anything equal or below a ratio of {@code 0.9} for
222           * {@code x/y}.
223           * </p>
224           */
225          UPRIGHT,
226  
227          /**
228           * square format (e.g. handheld computers).
229           * <p>
230           * anything between a ratio of {@code 0.9} (excluded) and
231           * {@code 1.1} (included) for {@code x/y}.
232           * </p>
233           */
234          SQUARE,
235  
236          /**
237           * a normal 4:3 format.
238           * <p>
239           * anything between a ratio of {@code 1.1} (excluded) and
240           * {@code 1.5} (included) for {@code x/y}.
241           * </p>
242           */
243          NORMAL,
244  
245          /**
246           * a wide-screen format.
247           * <p>
248           * any ratio larger than {@code 1.5} for {@code x/y}.
249           * </p>
250           */
251          WIDE,
252  
253          /**
254           * An "unknown" format.
255           */
256          UNKNOWN;
257  
258          /**
259           * returns the {@code Format} for the given resolution.
260           * 
261           * @param x
262           *            the available pixels in horizontal direction
263           * @param y
264           *            the available pixels in vertical direction
265           * @return the {@code Format}
266           */
267          public static Format getFormat(final int x, final int y) {
268              if (x <= 0 || y <= 0) {
269                  return Format.UNKNOWN;
270              }
271              double f = (double) x / (double) y;
272              if (f <= 0.9) {
273                  return Format.UPRIGHT;
274              } else if ((f > 0.9) && (f <= 1.1)) {
275                  return Format.SQUARE;
276              } else if ((f > 1.1) && (f <= 1.5)) {
277                  return Format.NORMAL;
278              }
279              return Format.WIDE;
280          }
281  
282          /**
283           * returns the {@code Format} for the given resolution.
284           * 
285           * @param xy
286           *            the available pixels as int[]{horizontal, vertical}
287           *            direction
288           * 
289           * @return the {@code Format}
290           */
291          public static Format getFormat(final int[] xy) {
292              return ScreenResolution.Format.getFormat(xy[0], xy[1]);
293          }
294  
295      }
296  
297  }
298