001/* 002 * ============================================================================ 003 * Copyright © 2002-2023 by Thomas Thrien. 004 * All Rights Reserved. 005 * ============================================================================ 006 * Licensed to the public under the agreements of the GNU Lesser General Public 007 * License, version 3.0 (the "License"). You may obtain a copy of the License at 008 * 009 * http://www.gnu.org/licenses/lgpl.html 010 * 011 * Unless required by applicable law or agreed to in writing, software 012 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 013 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 014 * License for the specific language governing permissions and limitations 015 * under the License. 016 */ 017 018package org.tquadrat.foundation.value; 019 020import static org.apiguardian.api.API.Status.STABLE; 021import static org.tquadrat.foundation.i18n.I18nUtil.retrieveText; 022import static org.tquadrat.foundation.lang.CommonConstants.EMPTY_STRING; 023import static org.tquadrat.foundation.lang.DebugOutput.ifDebug; 024import static org.tquadrat.foundation.lang.Objects.requireNonNullArgument; 025import static org.tquadrat.foundation.value.Speed.METER_PER_SECOND; 026import static org.tquadrat.foundation.value.internal.Tools.BASE_BUNDLE_NAME; 027import static org.tquadrat.foundation.value.internal.Tools.retrieveName; 028 029import java.util.EnumSet; 030import java.util.Locale; 031import java.util.MissingResourceException; 032import java.util.ResourceBundle; 033import java.util.Set; 034import java.util.function.Supplier; 035 036import org.apiguardian.api.API; 037import org.tquadrat.foundation.annotation.ClassVersion; 038import org.tquadrat.foundation.i18n.Text; 039import org.tquadrat.foundation.i18n.Translation; 040import org.tquadrat.foundation.lang.Lazy; 041import org.tquadrat.foundation.util.RangeMap; 042 043/** 044 * The wind force according to the Beaufort table. 045 * 046 * @extauthor Thomas Thrien - thomas.thrien@tquadrat.org 047 * @version $Id: WindForce.java 1073 2023-10-01 11:08:51Z tquadrat $ 048 * @since 0.0.4 049 * 050 * @UMLGraph.link 051 */ 052@ClassVersion( sourceVersion = "$Id: WindForce.java 1073 2023-10-01 11:08:51Z tquadrat $" ) 053@API( status = STABLE, since = "0.0.4" ) 054public enum WindForce 055{ 056 /*------------------*\ 057 ====** Enum Declaration **================================================= 058 \*------------------*/ 059 /** 060 * Wind force 0 Bft. 061 */ 062 @Text 063 ( 064 description = "The name for 0 Bft.", 065 translations = 066 { 067 @Translation( language = "de", text = "Windstille" ), 068 @Translation( language = "en", text = "Calm" ) 069 } 070 ) 071 BFT0( 0, "0.2" ), 072 073 /** 074 * Wind force 1 Bft. 075 */ 076 @Text 077 ( 078 description = "The name for 1 Bft.", 079 translations = 080 { 081 @Translation( language = "de", text = "Leiser Zug" ), 082 @Translation( language = "en", text = "Light Air" ) 083 } 084 ) 085 BFT1( 1, "1.5" ), 086 087 /** 088 * Wind force 2 Bft. 089 */ 090 @Text 091 ( 092 description = "The name for 2 Bft.", 093 translations = 094 { 095 @Translation( language = "de", text = "Leichte Brise" ), 096 @Translation( language = "en", text = "Light Breeze" ) 097 } 098 ) 099 BFT2( 2, "3.3" ), 100 101 /** 102 * Wind force 3 Bft. 103 */ 104 @Text 105 ( 106 description = "The name for 3 Bft.", 107 translations = 108 { 109 @Translation( language = "de", text = "Schwache Brise" ), 110 @Translation( language = "en", text = "Gentle Breeze" ) 111 } 112 ) 113 BFT3( 3, "5.4" ), 114 115 /** 116 * Wind force 4 Bft. 117 */ 118 @Text 119 ( 120 description = "The name for 4 Bft.", 121 translations = 122 { 123 @Translation( language = "de", text = "Mäßige Brise" ), 124 @Translation( language = "en", text = "Moderate Breeze" ) 125 } 126 ) 127 BFT4( 4, "8.9" ), 128 129 /** 130 * Wind force 5. 131 */ 132 @Text 133 ( 134 description = "The name for 5 Bft.", 135 translations = 136 { 137 @Translation( language = "de", text = "Frische Brise" ), 138 @Translation( language = "en", text = "Fresh Breeze" ) 139 } 140 ) 141 BFT5( 5, "11.0" ), 142 143 /** 144 * Wind force 6. 145 */ 146 @Text 147 ( 148 description = "The name for 6 Bft.", 149 translations = 150 { 151 @Translation( language = "de", text = "Starker Wind" ), 152 @Translation( language = "en", text = "Strong Breeze" ) 153 } 154 ) 155 BFT6( 6, "14.0" ), 156 157 /** 158 * Wind force 7. 159 */ 160 @Text 161 ( 162 description = "The name for 7 Bft.", 163 translations = 164 { 165 @Translation( language = "de", text = "Steifer Wind" ), 166 @Translation( language = "en", text = "Moderate Gale" ) 167 } 168 ) 169 BFT7( 7, "17.0" ), 170 171 /** 172 * Wind force 8. 173 */ 174 @Text 175 ( 176 description = "The name for 8 Bft.", 177 translations = 178 { 179 @Translation( language = "de", text = "Stürmischer Wind" ), 180 @Translation( language = "en", text = "Gale" ) 181 } 182 ) 183 BFT8( 8, "21.0" ), 184 185 /** 186 * Wind force 9. 187 */ 188 @Text 189 ( 190 description = "The name for 9 Bft.", 191 translations = 192 { 193 @Translation( language = "de", text = "Sturm" ), 194 @Translation( language = "en", text = "Strong Gale" ) 195 } 196 ) 197 BFT9( 9, "24.0" ), 198 199 /** 200 * Wind force 10 Bft. 201 */ 202 @Text 203 ( 204 description = "The name for 10 Bft.", 205 translations = 206 { 207 @Translation( language = "de", text = "Schwerer Sturm" ), 208 @Translation( language = "en_GB", text = "Whole Gale" ), 209 @Translation( language = "en", text = "Storm" ) 210 } 211 ) 212 BFT10( 10, "28.0" ), 213 214 /** 215 * Wind force 11 Bft. 216 */ 217 @Text 218 ( 219 description = "The name for 11 Bft.", 220 translations = 221 { 222 @Translation( language = "de", text = "Orkanartiger Sturm" ), 223 @Translation( language = "en_GB", text = "Storm" ), 224 @Translation( language = "en", text = "Violent Storm" ) 225 } 226 ) 227 BFT11( 11, "33.0" ), 228 229 /** 230 * Wind force 12 Bft. 231 */ 232 @Text 233 ( 234 description = "The name for 12 Bft.", 235 translations = 236 { 237 @Translation( language = "de", text = "Orkan" ), 238 @Translation( language = "en", text = "Hurricane" ) 239 } 240 ) 241 BFT12( 12, "36.9" ), 242 243 /** 244 * Wind force 13 Bft.; although it is not official, we added it to the 245 * list. 246 */ 247 @Text 248 ( 249 description = "The name for 13 Bft.", 250 translations = 251 { 252 @Translation( language = "de", text = "Schwerer Orkan" ), 253 @Translation( language = "en", text = "Heavy Hurricane" ) 254 } 255 ) 256 BFT13( 13, EMPTY_STRING ); 257 258 /*------------*\ 259 ====** Attributes **======================================================= 260 \*------------*/ 261 /** 262 * The maximum wind speed in m/s. 263 */ 264 @SuppressWarnings( "UseOfConcreteClass" ) 265 private final SpeedValue m_MaxSpeed; 266 267 /** 268 * The numerical value for the wind force. 269 */ 270 private final int m_Number; 271 272 /*------------------------*\ 273 ====** Static Initialisations **=========================================== 274 \*------------------------*/ 275 /** 276 * The translation table. 277 */ 278 private static final Lazy<RangeMap<WindForce>> m_TranslationTable; 279 280 static 281 { 282 @SuppressWarnings( "OverlyLongLambda" ) 283 final var supplier = (Supplier<RangeMap<WindForce>>) () -> 284 { 285 final var retValue = RangeMap.of( BFT13, true ); 286 double maxSpeed; 287 for( final var windForce : values() ) 288 { 289 if( windForce == BFT13 ) continue; 290 maxSpeed = windForce.getMaxSpeed().baseValue().doubleValue(); 291 retValue.addRange( maxSpeed, windForce ); 292 } 293 294 //---* Done *------------------------------------------------------ 295 return retValue; 296 }; 297 m_TranslationTable = Lazy.use( supplier ); 298 } 299 300 /*--------------*\ 301 ====** Constructors **===================================================== 302 \*--------------*/ 303 /** 304 * Creates a new {@code WindForce} object. 305 * 306 * @param number The numerical wind force. 307 * @param maxSpeed The maximum wind speed for this wind force in m/s. 308 */ 309 private WindForce( final int number, final String maxSpeed ) 310 { 311 m_Number = number; 312 m_MaxSpeed = maxSpeed.isEmpty() 313 ? new SpeedValue( METER_PER_SECOND, Double.POSITIVE_INFINITY ) 314 : new SpeedValue( METER_PER_SECOND, maxSpeed ); 315 } // WindForce() 316 317 /*---------*\ 318 ====** Methods **========================================================== 319 \*---------*/ 320 /** 321 * Returns the wind force for the given wind speed. 322 * 323 * @param speed The wind speed in m/s. 324 * @return The wind force. 325 */ 326 public static WindForce determineWindForce( final double speed ) 327 { 328 return determineWindForce( METER_PER_SECOND, speed ); 329 } // determineWindForce() 330 331 /** 332 * Returns the wind force for the given wind speed. 333 * 334 * @param unit The unit for the speed value. 335 * @param speed The wind speed. 336 * @return The wind force. 337 */ 338 public static WindForce determineWindForce( final Speed unit, final double speed ) 339 { 340 return determineWindForce( new SpeedValue( requireNonNullArgument( unit, "unit" ), speed ) ); 341 } // determineWindForce() 342 343 /** 344 * Returns the wind force for the given wind speed. 345 * 346 * @param speed The wind speed. 347 * @return The wind force. 348 */ 349 @SuppressWarnings( "UseOfConcreteClass" ) 350 public static WindForce determineWindForce( final SpeedValue speed ) 351 { 352 return m_TranslationTable.get().get( requireNonNullArgument( speed, "speed" ).baseValue().doubleValue() ); 353 } // determineWindForce() 354 355 /** 356 * Return an empty 357 * {@link Set} 358 * of {@code WindForce} instances. 359 * 360 * @return An empty set. 361 */ 362 public static Set<WindForce> emptySet() { return EnumSet.noneOf( WindForce.class ); } 363 364 /** 365 * Returns maximum wind speed for this wind force. 366 * 367 * @return The maximum speed. 368 */ 369 public final SpeedValue getMaxSpeed() { return m_MaxSpeed; } 370 371 /** 372 * Returns the wind force number. 373 * 374 * @return The number. 375 */ 376 public final int getNumber() { return m_Number; } 377 378 /** 379 * {@inheritDoc} 380 */ 381 @Override 382 public final String toString() 383 { 384 final var retValue = retrieveName( this ); 385 386 //---* Done *---------------------------------------------------------- 387 return retValue; 388 } // toString() 389 390 /** 391 * Returns the String representation for this wind force for the given 392 * language. 393 * 394 * @param locale The locale. 395 * @return The String representation. 396 */ 397 public final String toString( final Locale locale ) 398 { 399 String retValue; 400 try 401 { 402 final var module = getClass().getModule(); 403 final var bundle = ResourceBundle.getBundle( BASE_BUNDLE_NAME, requireNonNullArgument( locale, "locale" ), module ); 404 retValue = retrieveText( bundle, this ); 405 } 406 catch( final MissingResourceException e ) 407 { 408 ifDebug( e ); 409 retValue = toString(); 410 } 411 412 //---* Done *---------------------------------------------------------- 413 return retValue; 414 } // toString() 415} 416// class WindForce 417 418/* 419 * End of File 420 */