]> git.basschouten.com Git - openhab-addons.git/blob
72e11135dd4a1d6a00df5a7be799e9a7caab370b
[openhab-addons.git] /
1 /**
2  * Copyright (c) 2010-2023 Contributors to the openHAB project
3  *
4  * See the NOTICE file(s) distributed with this work for additional
5  * information.
6  *
7  * This program and the accompanying materials are made available under the
8  * terms of the Eclipse Public License 2.0 which is available at
9  * http://www.eclipse.org/legal/epl-2.0
10  *
11  * SPDX-License-Identifier: EPL-2.0
12  */
13 package org.openhab.binding.sonyprojector.internal;
14
15 import java.nio.charset.StandardCharsets;
16 import java.util.ArrayList;
17 import java.util.Arrays;
18 import java.util.List;
19
20 import org.eclipse.jdt.annotation.NonNullByDefault;
21 import org.openhab.binding.sonyprojector.internal.communication.SonyProjectorAspect;
22 import org.openhab.binding.sonyprojector.internal.communication.SonyProjectorBlockNr;
23 import org.openhab.binding.sonyprojector.internal.communication.SonyProjectorCalibrationPreset;
24 import org.openhab.binding.sonyprojector.internal.communication.SonyProjectorColorSpace;
25 import org.openhab.binding.sonyprojector.internal.communication.SonyProjectorColorTemp;
26 import org.openhab.binding.sonyprojector.internal.communication.SonyProjectorContrastEnhancer;
27 import org.openhab.binding.sonyprojector.internal.communication.SonyProjectorFilmMode;
28 import org.openhab.binding.sonyprojector.internal.communication.SonyProjectorFilmProjection;
29 import org.openhab.binding.sonyprojector.internal.communication.SonyProjectorGammaCorrection;
30 import org.openhab.binding.sonyprojector.internal.communication.SonyProjectorInput;
31 import org.openhab.binding.sonyprojector.internal.communication.SonyProjectorIrisMode;
32 import org.openhab.binding.sonyprojector.internal.communication.SonyProjectorIrisSensitivity;
33 import org.openhab.binding.sonyprojector.internal.communication.SonyProjectorLampControl;
34 import org.openhab.binding.sonyprojector.internal.communication.SonyProjectorMosquitoNr;
35 import org.openhab.binding.sonyprojector.internal.communication.SonyProjectorMotionEnhancer;
36 import org.openhab.binding.sonyprojector.internal.communication.SonyProjectorMpegNr;
37 import org.openhab.binding.sonyprojector.internal.communication.SonyProjectorNr;
38 import org.openhab.binding.sonyprojector.internal.communication.SonyProjectorPicturePosition;
39 import org.openhab.core.types.StateOption;
40
41 /**
42  * Represents the different supported projector models
43  *
44  * @author Laurent Garnier - Initial contribution
45  */
46 @NonNullByDefault
47 public enum SonyProjectorModel {
48
49     // HW models
50
51     HW10("VPL-HW10", false, 2, 2, 2, 1, true, 0, true, 2, 3, 3, true, true, 2, 2, true, true, 0, true, 3, 0, 0),
52     HW15("VPL-HW15", false, 2, 2, 2, 1, true, 0, true, 2, 3, 3, true, true, 3, 2, true, true, 0, true, 3, 0, 0),
53     HW20("VPL-HW20", false, 2, 2, 2, 1, true, 0, true, 2, 3, 3, true, true, 3, 2, true, true, 0, true, 3, 0, 0),
54     HW30ES("VPL-HW30ES", false, 4, 3, 3, 2, true, 0, true, 2, 4, 3, true, true, 4, 2, true, true, 0, true, 4, 0, 0),
55     HW35ES("VPL-HW35ES", false, 1, 3, 1, 2, true, 0, true, 5, 6, 0, false, false, 6, 2, false, false, 2, true, 6, 3, 2),
56     HW40ES("VPL-HW40ES", false, 1, 3, 1, 2, true, 0, true, 5, 6, 0, false, false, 6, 2, false, false, 2, true, 6, 3, 2),
57     HW45ES("VPL-HW45ES", false, 1, 1, 1, 1, true, 0, false, 6, 6, 0, false, false, 6, 2, false, false, 2, true, 6, 0,
58             1),
59     HW50ES("VPL-HW50ES", false, 1, 3, 1, 2, true, 0, true, 5, 7, 5, true, false, 1, 2, false, false, 2, true, 6, 3, 2),
60     HW55ES("VPL-HW55ES", false, 1, 3, 1, 2, true, 0, true, 5, 7, 5, true, false, 1, 2, false, false, 2, true, 6, 3, 2),
61     HW58ES("VPL-HW58ES", false, 1, 3, 1, 2, true, 0, true, 5, 6, 0, false, false, 6, 2, false, false, 2, true, 6, 3, 2),
62     HW60("VPL-HW60", true, 1, 1, 1, 1, true, 0, false, 6, 1, 1, true, false, 1, 1, false, false, 1, true, 1, 0, 1),
63     HW65("VPL-HW65", true, 1, 1, 1, 1, true, 0, false, 6, 1, 1, true, false, 1, 1, false, false, 1, true, 1, 0, 1),
64     HW68("VPL-HW68", true, 1, 1, 1, 1, true, 0, false, 6, 1, 1, true, false, 1, 1, false, false, 1, true, 1, 0, 1),
65
66     // VW models
67
68     // VW10HT("VPL-VW10HT", false, 2, 1, 1, 1, true, 0, true, 1, 1, 1, true, false, 2, 2, true, true, 0, true, 3, 0, 0),
69     // VW11HT("VPL-VW11HT", false, 2, 1, 1, 1, true, 0, true, 1, 1, 1, true, false, 2, 2, true, true, 0, true, 3, 0, 0),
70     // VW12HT("VPL-VW12HT", false, 2, 1, 1, 1, true, 0, true, 1, 1, 1, true, false, 2, 2, true, true, 0, true, 3, 0, 0),
71
72     VW40("VPL-VW40", false, 2, 2, 2, 0, true, 0, true, 2, 2, 2, true, true, 2, 2, false, false, 0, false, 3, 0, 0),
73     VW50("VPL-VW50", false, 2, 2, 2, 0, true, 0, true, 2, 2, 2, true, true, 2, 2, false, false, 0, false, 3, 0, 0),
74     VW60("VPL-VW60", false, 2, 2, 2, 0, true, 0, true, 3, 2, 2, true, true, 2, 2, false, false, 0, false, 3, 0, 0),
75     VW70("VPL-VW70", false, 2, 2, 2, 1, true, 0, true, 3, 3, 3, true, true, 3, 2, true, true, 0, true, 3, 0, 0),
76     VW80("VPL-VW80", false, 2, 2, 2, 2, true, 0, true, 3, 3, 3, true, true, 3, 2, true, true, 0, true, 3, 1, 2),
77     VW85("VPL-VW85", false, 3, 2, 3, 2, true, 0, true, 3, 4, 3, true, true, 5, 2, true, true, 0, true, 4, 1, 2),
78     VW90("VPL-VW90ES", false, 3, 5, 3, 2, true, 0, true, 3, 4, 3, true, true, 5, 2, true, true, 0, true, 4, 2, 2),
79     VW95("VPL-VW95ES", false, 4, 3, 3, 2, true, 2, true, 3, 4, 3, true, true, 5, 2, true, true, 0, true, 4, 2, 2),
80
81     VW100("VPL-VW100", false, 2, 4, 2, 3, false, 0, true, 4, 2, 4, false, false, 2, 2, false, false, 0, false, 3, 0, 0),
82
83     VW200("VPL-VW200", false, 2, 2, 2, 2, false, 0, true, 3, 2, 3, true, true, 2, 2, false, false, 0, true, 3, 1, 2),
84     VW260("VPL-VW260ES", true, 1, 1, 1, 1, true, 0, false, 1, 1, 0, false, false, 1, 1, false, false, 1, true, 2, 0, 1),
85     VW270("VPL-VW270ES", true, 1, 1, 1, 1, true, 0, false, 1, 1, 0, false, false, 1, 1, false, false, 1, true, 2, 0, 3),
86     VW285("VPL-VW285ES", true, 1, 1, 1, 1, true, 0, false, 1, 1, 0, false, false, 1, 1, false, false, 1, true, 2, 0, 1),
87     VW295("VPL-VW295ES", true, 1, 1, 1, 1, true, 0, false, 1, 1, 0, false, false, 1, 1, false, false, 1, true, 2, 0, 3),
88
89     VW300("VPL-VW300ES", true, 1, 1, 1, 1, true, 0, false, 1, 1, 0, false, false, 1, 1, false, false, 1, true, 1, 0, 1),
90     VW315("VPL-VW315", true, 1, 1, 1, 1, true, 0, false, 1, 1, 0, false, false, 1, 1, false, false, 1, true, 1, 0, 1),
91     VW320("VPL-VW320", true, 1, 1, 1, 1, true, 0, false, 1, 1, 0, false, false, 1, 1, false, false, 1, true, 1, 0, 1),
92     VW328("VPL-VW328", true, 1, 1, 1, 1, true, 0, false, 1, 1, 0, false, false, 1, 1, false, false, 1, true, 1, 0, 1),
93     VW350("VPL-VW350ES", true, 1, 1, 1, 1, true, 0, false, 1, 1, 0, false, false, 1, 1, false, false, 1, true, 1, 0, 1),
94     // VW360("VPL-VW360ES", false, 2, 4, 2, 3, true, 0, true, 1, 1, 1, true, false, 1, 2, false, false, 1, true, 1, 0,
95     // 1),
96     VW365("VPL-VW365", true, 1, 1, 1, 1, true, 0, false, 1, 1, 0, false, false, 1, 1, false, false, 1, true, 1, 0, 1),
97     VW385("VPL-VW385ES", true, 1, 1, 1, 1, true, 1, false, 1, 1, 1, true, false, 1, 1, false, false, 1, true, 2, 0, 1),
98
99     VW500("VPL-VW500ES", true, 1, 1, 1, 1, true, 1, false, 1, 1, 1, true, false, 1, 1, false, false, 1, true, 1, 0, 1),
100     VW515("VPL-VW515", true, 1, 1, 1, 1, true, 1, false, 1, 1, 1, true, false, 1, 1, false, false, 1, true, 2, 0, 1),
101     VW520("VPL-VW520", true, 1, 1, 1, 1, true, 1, false, 1, 1, 1, true, false, 1, 1, false, false, 1, true, 2, 0, 1),
102     VW528("VPL-VW528", true, 1, 1, 1, 1, true, 1, false, 1, 1, 1, true, false, 1, 1, false, false, 1, true, 2, 0, 1),
103     VW550("VPL-VW550ES", true, 1, 1, 1, 1, true, 1, false, 1, 1, 1, true, false, 1, 1, false, false, 1, true, 1, 0, 1),
104     VW570("VPL-VW570ES", true, 1, 1, 1, 1, true, 1, false, 1, 1, 1, true, false, 1, 1, false, false, 1, true, 2, 0, 1),
105
106     VW600("VPL-VW600ES", true, 1, 1, 1, 1, true, 1, false, 1, 1, 1, true, false, 1, 1, false, false, 1, true, 1, 0, 1),
107     VW665("VPL-VW665", true, 1, 1, 1, 1, true, 1, false, 1, 1, 1, true, false, 1, 1, false, false, 1, true, 2, 0, 1),
108     VW675("VPL-VW675ES", true, 1, 1, 1, 1, true, 1, false, 1, 1, 1, true, false, 1, 1, false, false, 1, true, 2, 0, 1),
109     // VW685("VPL-VW685ES", true, 1, 1, 1, 1, true, 1, false, 1, 1, 1, true, false, 1, 1, false, false, 1, true, 2, 0,
110     // 1),
111     VW695("VPL-VW695ES", true, 1, 1, 1, 1, true, 1, false, 1, 1, 1, true, false, 1, 1, false, false, 1, true, 2, 0, 1),
112
113     VW760("VPL-VW760ES", true, 1, 1, 1, 1, false, 1, false, 1, 1, 1, false, false, 1, 1, false, false, 1, true, 2, 0,
114             1),
115
116     VW870("VPL-VW870ES", true, 1, 1, 1, 1, false, 1, false, 1, 1, 1, false, false, 1, 1, false, false, 1, true, 2, 0,
117             1),
118     VW885("VPL-VW885ES", true, 1, 1, 1, 1, false, 1, false, 1, 1, 1, false, false, 1, 1, false, false, 1, true, 2, 0,
119             1),
120
121     VW995("VPL-VW995ES", true, 1, 1, 1, 1, false, 1, false, 1, 1, 1, false, false, 1, 1, false, false, 1, true, 2, 0,
122             1),
123
124     VW1000ES("VPL-VW1000ES", false, 5, 3, 1, 2, true, 1, true, 1, 5, 5, true, false, 1, 2, false, false, 2, true, 5, 3,
125             2),
126     VW1100ES("VPL-VW1100ES", false, 5, 3, 1, 2, true, 1, true, 1, 5, 5, true, false, 1, 2, false, false, 2, true, 5, 3,
127             2);
128
129     // VW5000ES("VPL-VW5000ES", false, 5, 3, 1, 2, true, 0, true, 1, 5, 5, true, false, 1, 2, false, false, 2, true, 5,
130     // 3, 2);
131
132     private String name;
133     private boolean powerCmdAvailable;
134     private int calibrPresetsCategory;
135     private int inputCategory;
136     private int contrastEnhancerCategory;
137     private int filmModeCategory;
138     private boolean lampControlAvailable;
139     private int picturePositionCategory;
140     private boolean overscanAvailable;
141     private int aspectCategory;
142     private int colorTempCategory;
143     private int irisModeCategory;
144     private boolean irisManualAvailable;
145     private boolean irisSensitivityAvailable;
146     private int gammaCorrectionCategory;
147     private int nrCategory;
148     private boolean blockNrAvailable;
149     private boolean mosquitoNrAvailable;
150     private int mpegNrCategory;
151     private boolean xvColorAvailable;
152     private int colorSpaceCategory;
153     private int filmProjectionCategory;
154     private int motionEnhancerCategory;
155
156     /**
157      * Constructor
158      *
159      * @param name the model name
160      * @param powerCmdAvailable true if the POWER command is available
161      * @param calibrPresetsCategory the category from {@link SonyProjectorCalibrationPreset}
162      * @param inputCategory the category from {@link SonyProjectorInput}
163      * @param contrastEnhancerCategory the category from {@link SonyProjectorContrastEnhancer}
164      * @param filmModeCategory the category from {@link SonyProjectorFilmMode}
165      * @param lampControlAvailable true if the lamp control setting is available
166      * @param picturePositionCategory the category from {@link SonyProjectorPicturePosition}
167      * @param overscanAvailable true if the overscan setting is available
168      * @param aspectCategory the category from {@link SonyProjectorAspect}
169      * @param colorTempCategory the category from {@link SonyProjectorColorTemp}
170      * @param irisModeCategory the category from {@link SonyProjectorIrisMode}
171      * @param irisManualAvailable true if the iris manual setting is available
172      * @param irisSensitivityAvailable true if the iris sensitivity setting is available
173      * @param gammaCorrectionCategory the category from {@link SonyProjectorGammaCorrection}
174      * @param nrCategory the category from {@link SonyProjectorNr}
175      * @param blockNrAvailable true if the block noise reduction setting is available
176      * @param mosquitoNrAvailable true if the mosquito noise reduction setting is available
177      * @param mpegNrCategory the category from {@link SonyProjectorMpegNr}
178      * @param xvColorAvailable true if the xvColor setting is available
179      * @param colorSpaceCategory the category from {@link SonyProjectorColorSpace}
180      * @param filmProjectionCategory the category from {@link SonyProjectorFilmProjection}
181      * @param motionEnhancerCategory the category from {@link SonyProjectorMotionEnhancer}
182      */
183     private SonyProjectorModel(String name, boolean powerCmdAvailable, int calibrPresetsCategory, int inputCategory,
184             int contrastEnhancerCategory, int filmModeCategory, boolean lampControlAvailable,
185             int picturePositionCategory, boolean overscanAvailable, int aspectCategory, int colorTempCategory,
186             int irisModeCategory, boolean irisManualAvailable, boolean irisSensitivityAvailable,
187             int gammaCorrectionCategory, int nrCategory, boolean blockNrAvailable, boolean mosquitoNrAvailable,
188             int mpegNrCategory, boolean xvColorAvailable, int colorSpaceCategory, int filmProjectionCategory,
189             int motionEnhancerCategory) {
190         this.name = name;
191         this.powerCmdAvailable = powerCmdAvailable;
192         this.calibrPresetsCategory = calibrPresetsCategory;
193         this.inputCategory = inputCategory;
194         this.contrastEnhancerCategory = contrastEnhancerCategory;
195         this.filmModeCategory = filmModeCategory;
196         this.lampControlAvailable = lampControlAvailable;
197         this.picturePositionCategory = picturePositionCategory;
198         this.overscanAvailable = overscanAvailable;
199         this.aspectCategory = aspectCategory;
200         this.colorTempCategory = colorTempCategory;
201         this.irisModeCategory = irisModeCategory;
202         this.irisManualAvailable = irisManualAvailable;
203         this.irisSensitivityAvailable = irisSensitivityAvailable;
204         this.gammaCorrectionCategory = gammaCorrectionCategory;
205         this.nrCategory = nrCategory;
206         this.blockNrAvailable = blockNrAvailable;
207         this.mosquitoNrAvailable = mosquitoNrAvailable;
208         this.mpegNrCategory = mpegNrCategory;
209         this.xvColorAvailable = xvColorAvailable;
210         this.colorSpaceCategory = colorSpaceCategory;
211         this.filmProjectionCategory = filmProjectionCategory;
212         this.motionEnhancerCategory = motionEnhancerCategory;
213     }
214
215     /**
216      * Get the model name
217      *
218      * @return the model name
219      */
220     public String getName() {
221         return name;
222     }
223
224     /**
225      * Inform whether the POWER command is available
226      *
227      * @return true if the POWER command is available
228      */
229     public boolean isPowerCmdAvailable() {
230         return powerCmdAvailable;
231     }
232
233     /**
234      * Get the list of {@link StateOption} associated to the available calibration presets
235      *
236      * @return the list of {@link StateOption} associated to the available calibration presets
237      */
238     public List<StateOption> getCalibrPresetStateOptions() {
239         return SonyProjectorCalibrationPreset.getStateOptions(calibrPresetsCategory);
240     }
241
242     /**
243      * Get the calibration preset associated to a name
244      *
245      * @param name the name used to identify the calibration preset
246      *
247      * @return the calibration preset associated to the searched name
248      *
249      * @throws SonyProjectorException - If no calibration preset is associated to the searched name
250      */
251     public byte[] getCalibrPresetDataCodeFromName(String name) throws SonyProjectorException {
252         return SonyProjectorCalibrationPreset.getFromName(calibrPresetsCategory, name).getDataCode();
253     }
254
255     /**
256      * Get the calibration preset associated to a data code
257      *
258      * @param dataCode the data code used to identify the calibration preset
259      *
260      * @return the calibration preset associated to the searched data code
261      *
262      * @throws SonyProjectorException - If no calibration preset is associated to the searched data code
263      */
264     public String getCalibrPresetNameFromDataCode(byte[] dataCode) throws SonyProjectorException {
265         return SonyProjectorCalibrationPreset.getFromDataCode(calibrPresetsCategory, dataCode).getName();
266     }
267
268     /**
269      * Get the list of {@link StateOption} associated to the available video inputs
270      *
271      * @return the list of {@link StateOption} associated to the available video inputs
272      */
273     public List<StateOption> getInputStateOptions() {
274         return SonyProjectorInput.getStateOptions(inputCategory);
275     }
276
277     /**
278      * Get the video input associated to a name
279      *
280      * @param name the name used to identify the video input
281      *
282      * @return the video input associated to the searched name
283      *
284      * @throws SonyProjectorException - If no video input is associated to the searched name
285      */
286     public byte[] getInputDataCodeFromName(String name) throws SonyProjectorException {
287         return SonyProjectorInput.getFromName(inputCategory, name).getDataCode();
288     }
289
290     /**
291      * Get the video input associated to a data code
292      *
293      * @param dataCode the data code used to identify the video input
294      *
295      * @return the video input associated to the searched data code
296      *
297      * @throws SonyProjectorException - If no video input is associated to the searched data code
298      */
299     public String getInputNameFromDataCode(byte[] dataCode) throws SonyProjectorException {
300         return SonyProjectorInput.getFromDataCode(inputCategory, dataCode).getName();
301     }
302
303     /**
304      * Get the list of {@link StateOption} associated to the available contrast enhancer modes
305      *
306      * @return the list of {@link StateOption} associated to the available contrast enhancer modes
307      */
308     public List<StateOption> getContrastEnhancerStateOptions() {
309         return SonyProjectorContrastEnhancer.getStateOptions(contrastEnhancerCategory);
310     }
311
312     /**
313      * Get the contrast enhancer mode associated to a name
314      *
315      * @param name the name used to identify the contrast enhancer mode
316      *
317      * @return the contrast enhancer mode associated to the searched name
318      *
319      * @throws SonyProjectorException - If no contrast enhancer mode is associated to the searched name
320      */
321     public byte[] getContrastEnhancerDataCodeFromName(String name) throws SonyProjectorException {
322         return SonyProjectorContrastEnhancer.getFromName(contrastEnhancerCategory, name).getDataCode();
323     }
324
325     /**
326      * Get the contrast enhancer mode associated to a data code
327      *
328      * @param dataCode the data code used to identify the contrast enhancer mode
329      *
330      * @return the contrast enhancer mode associated to the searched data code
331      *
332      * @throws SonyProjectorException - If no contrast enhancer mode is associated to the searched data code
333      */
334     public String getContrastEnhancerNameFromDataCode(byte[] dataCode) throws SonyProjectorException {
335         return SonyProjectorContrastEnhancer.getFromDataCode(contrastEnhancerCategory, dataCode).getName();
336     }
337
338     /**
339      * Get the list of {@link StateOption} associated to the available film modes
340      *
341      * @return the list of {@link StateOption} associated to the available film modes
342      */
343     public List<StateOption> getFilmModeStateOptions() {
344         return SonyProjectorFilmMode.getStateOptions(filmModeCategory);
345     }
346
347     /**
348      * Inform whether the film mode setting is available
349      *
350      * @return true if the film mode setting is available
351      */
352     public boolean isFilmModeAvailable() {
353         return filmModeCategory > 0;
354     }
355
356     /**
357      * Get the film mode associated to a name
358      *
359      * @param name the name used to identify the film mode
360      *
361      * @return the film mode associated to the searched name
362      *
363      * @throws SonyProjectorException - If no film mode is associated to the searched name
364      */
365     public byte[] getFilmModeDataCodeFromName(String name) throws SonyProjectorException {
366         return SonyProjectorFilmMode.getFromName(filmModeCategory, name).getDataCode();
367     }
368
369     /**
370      * Get the film mode associated to a data code
371      *
372      * @param dataCode the data code used to identify the film mode
373      *
374      * @return the film mode associated to the searched data code
375      *
376      * @throws SonyProjectorException - If no film mode is associated to the searched data code
377      */
378     public String getFilmModeNameFromDataCode(byte[] dataCode) throws SonyProjectorException {
379         return SonyProjectorFilmMode.getFromDataCode(filmModeCategory, dataCode).getName();
380     }
381
382     /**
383      * Get the list of {@link StateOption} associated to the available lamp control modes
384      *
385      * @return the list of {@link StateOption} associated to the available lamp control modes
386      */
387     public List<StateOption> getLampControlStateOptions() {
388         return lampControlAvailable ? SonyProjectorLampControl.getStateOptions() : new ArrayList<>();
389     }
390
391     /**
392      * Inform whether the lamp control setting is available
393      *
394      * @return true if the lamp control setting is available
395      */
396     public boolean isLampControlAvailable() {
397         return lampControlAvailable;
398     }
399
400     /**
401      * Get the list of {@link StateOption} associated to the available picture positions
402      *
403      * @return the list of {@link StateOption} associated to the available picture positions
404      */
405     public List<StateOption> getPicturePositionStateOptions() {
406         return SonyProjectorPicturePosition.getStateOptions(picturePositionCategory);
407     }
408
409     /**
410      * Inform whether the picture position setting is available
411      *
412      * @return true if the picture position setting is available
413      */
414     public boolean isPicturePositionAvailable() {
415         return picturePositionCategory > 0;
416     }
417
418     /**
419      * Get the picture position associated to a name
420      *
421      * @param name the name used to identify the picture position
422      *
423      * @return the picture position associated to the searched name
424      *
425      * @throws SonyProjectorException - If no picture position is associated to the searched name
426      */
427     public byte[] getPicturePositionCodeFromName(String name) throws SonyProjectorException {
428         return SonyProjectorPicturePosition.getFromName(picturePositionCategory, name).getDataCode();
429     }
430
431     /**
432      * Get the picture position associated to a data code
433      *
434      * @param dataCode the data code used to identify the picture position
435      *
436      * @return the picture position associated to the searched data code
437      *
438      * @throws SonyProjectorException - If no picture position is associated to the searched data code
439      */
440     public String getPicturePositionNameFromDataCode(byte[] dataCode) throws SonyProjectorException {
441         return SonyProjectorPicturePosition.getFromDataCode(picturePositionCategory, dataCode).getName();
442     }
443
444     /**
445      * Get the list of {@link StateOption} associated to the available aspect modes
446      *
447      * @return the list of {@link StateOption} associated to the available aspect modes
448      */
449     public List<StateOption> getAspectStateOptions() {
450         return SonyProjectorAspect.getStateOptions(aspectCategory);
451     }
452
453     /**
454      * Get the aspect mode associated to a name
455      *
456      * @param name the name used to identify the aspect mode
457      *
458      * @return the aspect mode associated to the searched name
459      *
460      * @throws SonyProjectorException - If no aspect mode is associated to the searched name
461      */
462     public byte[] getAspectCodeFromName(String name) throws SonyProjectorException {
463         return SonyProjectorAspect.getFromName(aspectCategory, name).getDataCode();
464     }
465
466     /**
467      * Get the aspect mode associated to a data code
468      *
469      * @param dataCode the data code used to identify the aspect mode
470      *
471      * @return the aspect mode associated to the searched data code
472      *
473      * @throws SonyProjectorException - If no aspect mode is associated to the searched data code
474      */
475     public String getAspectNameFromDataCode(byte[] dataCode) throws SonyProjectorException {
476         return SonyProjectorAspect.getFromDataCode(aspectCategory, dataCode).getName();
477     }
478
479     /**
480      * Get the list of {@link StateOption} associated to the available color temperatures
481      *
482      * @return the list of {@link StateOption} associated to the available color temperatures
483      */
484     public List<StateOption> getColorTempStateOptions() {
485         return SonyProjectorColorTemp.getStateOptions(colorTempCategory);
486     }
487
488     /**
489      * Get the color temperature associated to a name
490      *
491      * @param name the name used to identify the color temperature
492      *
493      * @return the color temperature associated to the searched name
494      *
495      * @throws SonyProjectorException - If no color temperature is associated to the searched name
496      */
497     public byte[] getColorTempCodeFromName(String name) throws SonyProjectorException {
498         return SonyProjectorColorTemp.getFromName(colorTempCategory, name).getDataCode();
499     }
500
501     /**
502      * Get the color temperature associated to a data code
503      *
504      * @param dataCode the data code used to identify the color temperature
505      *
506      * @return the color temperature associated to the searched data code
507      *
508      * @throws SonyProjectorException - If no color temperature is associated to the searched data code
509      */
510     public String getColorTempNameFromDataCode(byte[] dataCode) throws SonyProjectorException {
511         return SonyProjectorColorTemp.getFromDataCode(colorTempCategory, dataCode).getName();
512     }
513
514     /**
515      * Get the list of {@link StateOption} associated to the available iris modes
516      *
517      * @return the list of {@link StateOption} associated to the available iris modes
518      */
519     public List<StateOption> getIrisModeStateOptions() {
520         return SonyProjectorIrisMode.getStateOptions(irisModeCategory);
521     }
522
523     /**
524      * Inform whether the iris mode setting is available
525      *
526      * @return true if the iris mode setting is available
527      */
528     public boolean isIrisModeAvailable() {
529         return irisModeCategory > 0;
530     }
531
532     /**
533      * Get the iris mode associated to a name
534      *
535      * @param name the name used to identify the iris mode
536      *
537      * @return the iris mode associated to the searched name
538      *
539      * @throws SonyProjectorException - If no iris mode is associated to the searched name
540      */
541     public byte[] getIrisModeCodeFromName(String name) throws SonyProjectorException {
542         return SonyProjectorIrisMode.getFromName(irisModeCategory, name).getDataCode();
543     }
544
545     /**
546      * Get the iris mode associated to a data code
547      *
548      * @param dataCode the data code used to identify the iris mode
549      *
550      * @return the iris mode associated to the searched data code
551      *
552      * @throws SonyProjectorException - If no iris mode is associated to the searched data code
553      */
554     public String getIrisModeNameFromDataCode(byte[] dataCode) throws SonyProjectorException {
555         return SonyProjectorIrisMode.getFromDataCode(irisModeCategory, dataCode).getName();
556     }
557
558     /**
559      * Inform whether the overscan setting is available
560      *
561      * @return true if the overscan setting is available
562      */
563     public boolean isOverscanAvailable() {
564         return overscanAvailable;
565     }
566
567     /**
568      * Inform whether the iris manual setting is available
569      *
570      * @return true if the iris manual setting is available
571      */
572     public boolean isIrisManualAvailable() {
573         return irisManualAvailable;
574     }
575
576     /**
577      * Get the list of {@link StateOption} associated to the available iris sensitivities
578      *
579      * @return the list of {@link StateOption} associated to the available iris sensitivities
580      */
581     public List<StateOption> getIrisSensitivityStateOptions() {
582         return irisSensitivityAvailable ? SonyProjectorIrisSensitivity.getStateOptions() : new ArrayList<>();
583     }
584
585     /**
586      * Inform whether the iris sensitivity setting is available
587      *
588      * @return true if the iris sensitivity setting is available
589      */
590     public boolean isIrisSensitivityAvailable() {
591         return irisSensitivityAvailable;
592     }
593
594     /**
595      * Get the list of {@link StateOption} associated to the available gamma corrections
596      *
597      * @return the list of {@link StateOption} associated to the available gamma corrections
598      */
599     public List<StateOption> getGammaCorrectionStateOptions() {
600         return SonyProjectorGammaCorrection.getStateOptions(gammaCorrectionCategory);
601     }
602
603     /**
604      * Get the gamma correction associated to a name
605      *
606      * @param name the name used to identify the gamma correction
607      *
608      * @return the gamma correction associated to the searched name
609      *
610      * @throws SonyProjectorException - If no gamma correction is associated to the searched name
611      */
612     public byte[] getGammaCorrectionCodeFromName(String name) throws SonyProjectorException {
613         return SonyProjectorGammaCorrection.getFromName(gammaCorrectionCategory, name).getDataCode();
614     }
615
616     /**
617      * Get the gamma correction associated to a data code
618      *
619      * @param dataCode the data code used to identify the gamma correction
620      *
621      * @return the gamma correction associated to the searched data code
622      *
623      * @throws SonyProjectorException - If no gamma correction is associated to the searched data code
624      */
625     public String getGammaCorrectionNameFromDataCode(byte[] dataCode) throws SonyProjectorException {
626         return SonyProjectorGammaCorrection.getFromDataCode(gammaCorrectionCategory, dataCode).getName();
627     }
628
629     /**
630      * Get the list of {@link StateOption} associated to the available nose reduction modes
631      *
632      * @return the list of {@link StateOption} associated to the available nose reduction modes
633      */
634     public List<StateOption> getNrStateOptions() {
635         return SonyProjectorNr.getStateOptions(nrCategory);
636     }
637
638     /**
639      * Get the noise reduction mode associated to a name
640      *
641      * @param name the name used to identify the noise reduction mode
642      *
643      * @return the noise reduction mode associated to the searched name
644      *
645      * @throws SonyProjectorException - If no noise reduction mode is associated to the searched name
646      */
647     public byte[] getNrCodeFromName(String name) throws SonyProjectorException {
648         return SonyProjectorNr.getFromName(nrCategory, name).getDataCode();
649     }
650
651     /**
652      * Get the noise reduction mode associated to a data code
653      *
654      * @param dataCode the data code used to identify the noise reduction mode
655      *
656      * @return the noise reduction mode associated to the searched data code
657      *
658      * @throws SonyProjectorException - If no noise reduction mode is associated to the searched data code
659      */
660     public String getNrNameFromDataCode(byte[] dataCode) throws SonyProjectorException {
661         return SonyProjectorNr.getFromDataCode(nrCategory, dataCode).getName();
662     }
663
664     /**
665      * Get the list of {@link StateOption} associated to the available block nose reduction modes
666      *
667      * @return the list of {@link StateOption} associated to the available block nose reduction modes
668      */
669     public List<StateOption> getBlockNrStateOptions() {
670         return blockNrAvailable ? SonyProjectorBlockNr.getStateOptions() : new ArrayList<>();
671     }
672
673     /**
674      * Inform whether the block noise reduction setting is available
675      *
676      * @return true if the block noise reduction setting is available
677      */
678     public boolean isBlockNrAvailable() {
679         return blockNrAvailable;
680     }
681
682     /**
683      * Get the list of {@link StateOption} associated to the available mosquito nose reduction modes
684      *
685      * @return the list of {@link StateOption} associated to the available mosquito nose reduction modes
686      */
687     public List<StateOption> getMosquitoNrStateOptions() {
688         return mosquitoNrAvailable ? SonyProjectorMosquitoNr.getStateOptions() : new ArrayList<>();
689     }
690
691     /**
692      * Inform whether the mosquito noise reduction setting is available
693      *
694      * @return true if the mosquito noise reduction setting is available
695      */
696     public boolean isMosquitoNrAvailable() {
697         return mosquitoNrAvailable;
698     }
699
700     /**
701      * Get the list of {@link StateOption} associated to the available MPEG nose reduction modes
702      *
703      * @return the list of {@link StateOption} associated to the available MPEG nose reduction modes
704      */
705     public List<StateOption> getMpegNrStateOptions() {
706         return SonyProjectorMpegNr.getStateOptions(mpegNrCategory);
707     }
708
709     /**
710      * Inform whether the MPEG noise reduction setting is available
711      *
712      * @return true if the MPEG noise reduction setting is available
713      */
714     public boolean isMpegNrAvailable() {
715         return mpegNrCategory > 0;
716     }
717
718     /**
719      * Get the MPEG noise reduction mode associated to a name
720      *
721      * @param name the name used to identify the MPEG noise reduction mode
722      *
723      * @return the MPEG noise reduction mode associated to the searched name
724      *
725      * @throws SonyProjectorException - If no MPEG noise reduction mode is associated to the searched name
726      */
727     public byte[] getMpegNrCodeFromName(String name) throws SonyProjectorException {
728         return SonyProjectorMpegNr.getFromName(mpegNrCategory, name).getDataCode();
729     }
730
731     /**
732      * Get the MPEG noise reduction mode associated to a data code
733      *
734      * @param dataCode the data code used to identify the MPEG noise reduction mode
735      *
736      * @return the MPEG noise reduction mode associated to the searched data code
737      *
738      * @throws SonyProjectorException - If no MPEG noise reduction mode is associated to the searched data code
739      */
740     public String getMpegNrNameFromDataCode(byte[] dataCode) throws SonyProjectorException {
741         return SonyProjectorMpegNr.getFromDataCode(mpegNrCategory, dataCode).getName();
742     }
743
744     /**
745      * Inform whether the xvColor setting is available
746      *
747      * @return true if the xvColor setting is available
748      */
749     public boolean isXvColorAvailable() {
750         return xvColorAvailable;
751     }
752
753     /**
754      * Get the list of {@link StateOption} associated to the available color spaces
755      *
756      * @return the list of {@link StateOption} associated to the available color spaces
757      */
758     public List<StateOption> getColorSpaceStateOptions() {
759         return SonyProjectorColorSpace.getStateOptions(colorSpaceCategory);
760     }
761
762     /**
763      * Get the color space associated to a name
764      *
765      * @param name the name used to identify the color space
766      *
767      * @return the color space associated to the searched name
768      *
769      * @throws SonyProjectorException - If no color space is associated to the searched name
770      */
771     public byte[] getColorSpaceCodeFromName(String name) throws SonyProjectorException {
772         return SonyProjectorColorSpace.getFromName(colorSpaceCategory, name).getDataCode();
773     }
774
775     /**
776      * Get the color space associated to a data code
777      *
778      * @param dataCode the data code used to identify the color space
779      *
780      * @return the color space associated to the searched data code
781      *
782      * @throws SonyProjectorException - If no color space is associated to the searched data code
783      */
784     public String getColorSpaceNameFromDataCode(byte[] dataCode) throws SonyProjectorException {
785         return SonyProjectorColorSpace.getFromDataCode(colorSpaceCategory, dataCode).getName();
786     }
787
788     /**
789      * Get the list of {@link StateOption} associated to the available film projection modes
790      *
791      * @return the list of {@link StateOption} associated to the available film projection modes
792      */
793     public List<StateOption> getFilmProjectionStateOptions() {
794         return SonyProjectorFilmProjection.getStateOptions(filmProjectionCategory);
795     }
796
797     /**
798      * Inform whether the film projection setting is available
799      *
800      * @return true if the film projection setting is available
801      */
802     public boolean isFilmProjectionAvailable() {
803         return filmProjectionCategory > 0;
804     }
805
806     /**
807      * Get the film projection mode associated to a name
808      *
809      * @param name the name used to identify the film projection mode
810      *
811      * @return the film projection mode associated to the searched name
812      *
813      * @throws SonyProjectorException - If no film projection mode is associated to the searched name
814      */
815     public byte[] getFilmProjectionCodeFromName(String name) throws SonyProjectorException {
816         return SonyProjectorFilmProjection.getFromName(filmProjectionCategory, name).getDataCode();
817     }
818
819     /**
820      * Get the film projection mode associated to a data code
821      *
822      * @param dataCode the data code used to identify the film projection mode
823      *
824      * @return the film projection mode associated to the searched data code
825      *
826      * @throws SonyProjectorException - If no film projection mode is associated to the searched data code
827      */
828     public String getFilmProjectionNameFromDataCode(byte[] dataCode) throws SonyProjectorException {
829         return SonyProjectorFilmProjection.getFromDataCode(filmProjectionCategory, dataCode).getName();
830     }
831
832     /**
833      * Get the list of {@link StateOption} associated to the available motion enhancer modes
834      *
835      * @return the list of {@link StateOption} associated to the available motion enhancer modes
836      */
837     public List<StateOption> getMotionEnhancerStateOptions() {
838         return SonyProjectorMotionEnhancer.getStateOptions(motionEnhancerCategory);
839     }
840
841     /**
842      * Inform whether the motion enhancer setting is available
843      *
844      * @return true if the motion enhancer setting is available
845      */
846     public boolean isMotionEnhancerAvailable() {
847         return motionEnhancerCategory > 0;
848     }
849
850     /**
851      * Get the motion enhancer mode associated to a name
852      *
853      * @param name the name used to identify the motion enhancer mode
854      *
855      * @return the motion enhancer mode associated to the searched name
856      *
857      * @throws SonyProjectorException - If no motion enhancer mode is associated to the searched name
858      */
859     public byte[] getMotionEnhancerCodeFromName(String name) throws SonyProjectorException {
860         return SonyProjectorMotionEnhancer.getFromName(motionEnhancerCategory, name).getDataCode();
861     }
862
863     /**
864      * Get the motion enhancer mode associated to a data code
865      *
866      * @param dataCode the data code used to identify the motion enhancer mode
867      *
868      * @return the motion enhancer mode associated to the searched data code
869      *
870      * @throws SonyProjectorException - If no motion enhancer mode is associated to the searched data code
871      */
872     public String getMotionEnhancerNameFromDataCode(byte[] dataCode) throws SonyProjectorException {
873         return SonyProjectorMotionEnhancer.getFromDataCode(motionEnhancerCategory, dataCode).getName();
874     }
875
876     /**
877      * Get the projector model mode associated to a name
878      *
879      * @param name the name used to identify the projector model
880      * @param strict true for a strict matching with the searched name
881      *
882      * @return the projector model associated to the searched name
883      *
884      * @throws SonyProjectorException - If no projector model is associated to the searched name
885      */
886     public static SonyProjectorModel getFromName(String name, boolean strict) throws SonyProjectorException {
887         String otherName = lessStrictName(name);
888         for (SonyProjectorModel value : SonyProjectorModel.values()) {
889             if (strict && value.getName().equals(name)) {
890                 return value;
891             } else if (!strict && lessStrictName(value.getName()).equals(otherName)) {
892                 return value;
893             }
894         }
895         throw new SonyProjectorException("Invalid model name: " + name);
896     }
897
898     private static String lessStrictName(String name) {
899         // Ignore the ending letters
900         String newName = name;
901         byte[] data = name.getBytes();
902         // Search the first number, starting at right
903         int last = data.length - 1;
904         for (int i = last; i >= 0; i--) {
905             if (((char) data[i]) >= '0' && ((char) data[i]) <= '9') {
906                 last = i;
907                 break;
908             }
909         }
910         byte[] newData = Arrays.copyOf(data, last + 1);
911         newName = new String(newData, StandardCharsets.UTF_8);
912         return newName;
913     }
914 }