001 package com.croftsoft.apps.infant; 002 003 import java.awt.*; 004 import java.io.*; 005 import java.util.*; 006 007 import com.croftsoft.core.CroftSoftConstants; 008 import com.croftsoft.core.beans.XmlBeanCoder; 009 import com.croftsoft.core.gui.CursorLib; 010 import com.croftsoft.core.math.MathConstants; 011 import com.croftsoft.core.util.log.*; 012 013 /*********************************************************************** 014 * Configuration. 015 * 016 * @version 017 * $Id: InfantConfig.java,v 1.31 2007/06/29 01:09:13 croft Exp $ 018 * @since 019 * 2006-01-03 020 * @author 021 * <a href="https://www.croftsoft.com/">David Wallace Croft</a> 022 ***********************************************************************/ 023 024 public final class InfantConfig 025 //////////////////////////////////////////////////////////////////////// 026 //////////////////////////////////////////////////////////////////////// 027 { 028 029 private static final String VERSION 030 = "$Date: 2007/06/29 01:09:13 $"; 031 032 private static final String TITLE 033 = "CroftSoft Infant"; 034 035 private static final String INFO 036 = TITLE + "\n" 037 + "Version " + VERSION + "\n" 038 + CroftSoftConstants.COPYRIGHT + "\n" 039 + CroftSoftConstants.DEFAULT_LICENSE + "\n" 040 + CroftSoftConstants.HOME_PAGE + "\n"; 041 042 private static final String 043 CONFIG_FILENAME = "config.xml", 044 REPORT_DIR = "data", 045 SETUP_DIR = "setup", 046 DEFAULT_SETUP_FILENAME = "setup.txt"; 047 048 private static final int 049 FRAME_WIDTH = 800, 050 FRAME_HEIGHT = 750; // leave pad for applet warning 051 052 private static final double UPDATE_RATE = 100.0; 053 054 private static final Color 055 BACKGROUND_COLOR = Color.BLACK, 056 FOREGROUND_COLOR = Color.WHITE; 057 058 private static final String 059 SHUTDOWN_CONFIRMATION_PROMPT = null; // "Exit " + TITLE + "?"; 060 061 private static final Font FONT 062 = new Font ( "Arioso", Font.BOLD, 20 ); 063 064 private static final String [ ] IMAGE_FILENAMES = { 065 "image0.png", 066 "image1.bmp", 067 "image2.bmp", 068 "image3.bmp", 069 "image4.bmp", 070 "image5.bmp", 071 "image6.bmp" }; 072 073 private static final long 074 IMAGE_DISPLAY_TIME 075 = 400 * MathConstants.NANOSECONDS_PER_MILLISECOND, 076 INTER_STIMULUS_INTERVAL 077 = 1 * MathConstants.NANOSECONDS_PER_SECOND; 078 079 private static final int LOG_LINES_MAX = 1000; 080 081 private static final double SCALE = 1.0; 082 083 // 084 085 private transient boolean dirty; 086 087 private transient String [ ] imagePaths; 088 089 private transient Log log; 090 091 // 092 093 private int controllerIndex; 094 095 private long 096 imageDisplayTime, 097 interStimulusInterval; 098 099 private double scale; 100 101 //////////////////////////////////////////////////////////////////////// 102 //////////////////////////////////////////////////////////////////////// 103 104 public static String getInfantDirPath ( ) 105 //////////////////////////////////////////////////////////////////////// 106 { 107 return System.getProperty ( "user.home" ) 108 + File.separator 109 + ".croftsoft" 110 + File.separator 111 + "infant"; 112 } 113 114 public static String getInfantImagesDirPath ( ) 115 //////////////////////////////////////////////////////////////////////// 116 { 117 return getInfantDirPath ( ) 118 + File.separator 119 + "images"; 120 } 121 122 public static String getInfantReportDirPath ( ) 123 //////////////////////////////////////////////////////////////////////// 124 { 125 return getInfantDirPath ( ) 126 + File.separator 127 + REPORT_DIR; 128 } 129 130 public static String getInfantSetupDirPath ( ) 131 //////////////////////////////////////////////////////////////////////// 132 { 133 return getInfantDirPath ( ) 134 + File.separator 135 + SETUP_DIR; 136 } 137 138 public static InfantConfig load ( ) 139 //////////////////////////////////////////////////////////////////////// 140 { 141 createLocalFiles ( ); 142 143 try 144 { 145 final File file 146 = new File ( getInfantDirPath ( ), CONFIG_FILENAME ); 147 148 if ( file.exists ( ) ) 149 { 150 final InfantConfig infantConfig 151 = ( InfantConfig ) XmlBeanCoder.loadFromXmlFile ( file ); 152 153 return infantConfig; 154 } 155 } 156 catch ( IOException ex ) 157 { 158 ex.printStackTrace ( ); 159 } 160 161 return new InfantConfig ( ); 162 } 163 164 //////////////////////////////////////////////////////////////////////// 165 //////////////////////////////////////////////////////////////////////// 166 167 public InfantConfig ( ) 168 //////////////////////////////////////////////////////////////////////// 169 { 170 createImagePaths ( ); 171 172 imageDisplayTime = IMAGE_DISPLAY_TIME; 173 174 interStimulusInterval = INTER_STIMULUS_INTERVAL; 175 176 scale = SCALE; 177 } 178 179 //////////////////////////////////////////////////////////////////////// 180 // accessor methods 181 //////////////////////////////////////////////////////////////////////// 182 183 public Color getBackgroundColor ( ) { return BACKGROUND_COLOR; } 184 185 public int getControllerIndex ( ) { return controllerIndex; } 186 187 public Cursor getCursor ( ) 188 { return CursorLib.createInvisibleCursor ( ); } 189 190 public Color getForegroundColor ( ) { return FOREGROUND_COLOR; } 191 192 public String getInfo ( ) { return INFO; } 193 194 public Font getFont ( ) { return FONT; } 195 196 public Dimension getFrameSize ( ) 197 { return new Dimension ( FRAME_WIDTH, FRAME_HEIGHT ); } 198 199 public String getFrameTitle ( ) { return TITLE; } 200 201 public long getImageDisplayTime ( ) { return imageDisplayTime; } 202 203 public long getInterStimulusInterval ( ) 204 { return interStimulusInterval; } 205 206 public String [ ] getImagePaths ( ) { return imagePaths; } 207 208 public Log getLog ( ) { return log; } 209 210 public int getLogLinesMax ( ) { return LOG_LINES_MAX; } 211 212 public double getScale ( ) { return scale; } 213 214 public String getShutdownConfirmationPrompt ( ) 215 { return SHUTDOWN_CONFIRMATION_PROMPT; } 216 217 public String getThreadName ( ) { return TITLE; } 218 219 public double getUpdateRate ( ) { return UPDATE_RATE; } 220 221 //////////////////////////////////////////////////////////////////////// 222 // mutator methods 223 //////////////////////////////////////////////////////////////////////// 224 225 public void setControllerIndex ( final int controllerIndex ) 226 //////////////////////////////////////////////////////////////////////// 227 { 228 if ( controllerIndex == this.controllerIndex ) 229 { 230 return; 231 } 232 233 this.controllerIndex = controllerIndex; 234 235 dirty = true; 236 } 237 238 public void setImageDisplayTime ( final long imageDisplayTime ) 239 //////////////////////////////////////////////////////////////////////// 240 { 241 this.imageDisplayTime = imageDisplayTime; 242 243 dirty = true; 244 } 245 246 public void setInterStimulusInterval ( 247 final long interStimulusInterval ) 248 //////////////////////////////////////////////////////////////////////// 249 { 250 this.interStimulusInterval = interStimulusInterval; 251 252 dirty = true; 253 } 254 255 public void setLog ( final Log log ) { this.log = log; } 256 257 public void setScale ( final double scale ) 258 //////////////////////////////////////////////////////////////////////// 259 { 260 this.scale = scale; 261 262 dirty = true; 263 } 264 265 //////////////////////////////////////////////////////////////////////// 266 // lifecycle methods 267 //////////////////////////////////////////////////////////////////////// 268 269 public void saveIfChanged ( final InfantAccessor infantAccessor ) 270 throws IOException 271 //////////////////////////////////////////////////////////////////////// 272 { 273 final long imageDisplayTime 274 = infantAccessor.getImageDisplayTime ( ); 275 276 final long interStimulusInterval 277 = infantAccessor.getInterStimulusInterval ( ); 278 279 if ( !dirty 280 && ( imageDisplayTime == this.imageDisplayTime ) 281 && ( interStimulusInterval == this.interStimulusInterval ) ) 282 { 283 return; 284 } 285 286 setImageDisplayTime ( imageDisplayTime ); 287 288 setInterStimulusInterval ( interStimulusInterval ); 289 290 final String infantDirPath = getInfantDirPath ( ); 291 292 XmlBeanCoder.saveToXmlFile ( 293 this, 294 new File ( infantDirPath, CONFIG_FILENAME ) ); 295 296 dirty = false; 297 } 298 299 //////////////////////////////////////////////////////////////////////// 300 // private static methods 301 //////////////////////////////////////////////////////////////////////// 302 303 private static void createLocalFiles ( ) 304 //////////////////////////////////////////////////////////////////////// 305 { 306 try 307 { 308 309 final File reportDirFile 310 = new File ( getInfantReportDirPath ( ) ); 311 312 if ( !reportDirFile.exists ( ) ) 313 { 314 reportDirFile.mkdirs ( ); 315 } 316 317 final File imagesDirFile 318 = new File ( getInfantImagesDirPath ( ) ); 319 320 if ( !imagesDirFile.exists ( ) ) 321 { 322 imagesDirFile.mkdirs ( ); 323 324 for ( String filename : IMAGE_FILENAMES ) 325 { 326 copyLocalFile ( 327 "images/" + filename, 328 imagesDirFile, 329 filename ); 330 } 331 } 332 333 final File setupDirFile 334 = new File ( getInfantSetupDirPath ( ) ); 335 336 if ( !setupDirFile.exists ( ) ) 337 { 338 setupDirFile.mkdirs ( ); 339 340 copyLocalFile ( 341 "setup/" + DEFAULT_SETUP_FILENAME, 342 setupDirFile, 343 DEFAULT_SETUP_FILENAME ); 344 } 345 } 346 catch ( Exception ex ) 347 { 348 ex.printStackTrace ( ); 349 } 350 } 351 352 private static void copyLocalFile ( 353 final String resourceFilename, 354 final File dirFile, 355 final String filename ) 356 //////////////////////////////////////////////////////////////////////// 357 { 358 final ClassLoader classLoader 359 = InfantConfig.class.getClassLoader ( ); 360 361 InputStream inputStream = null; 362 363 OutputStream outputStream = null; 364 365 try 366 { 367 inputStream = new BufferedInputStream ( 368 classLoader.getResourceAsStream ( resourceFilename ) ); 369 370 final File file = new File ( dirFile, filename ); 371 372 outputStream = new BufferedOutputStream ( 373 new FileOutputStream ( file ) ); 374 375 int i; 376 377 while ( ( i = inputStream.read ( ) ) > -1 ) 378 { 379 outputStream.write ( i ); 380 } 381 } 382 catch ( Exception ex ) 383 { 384 ex.printStackTrace ( ); 385 } 386 finally 387 { 388 if ( outputStream != null ) 389 { 390 try 391 { 392 outputStream.close ( ); 393 } 394 catch ( Exception ex ) 395 { 396 ex.printStackTrace ( ); 397 } 398 } 399 400 if ( inputStream != null ) 401 { 402 try 403 { 404 inputStream.close ( ); 405 } 406 catch ( Exception ex ) 407 { 408 ex.printStackTrace ( ); 409 } 410 } 411 } 412 } 413 414 private void createImagePaths ( ) 415 //////////////////////////////////////////////////////////////////////// 416 { 417 try 418 { 419 final File infantImagesDir 420 = new File ( getInfantImagesDirPath ( ) ); 421 422 final File [ ] imageFiles = infantImagesDir.listFiles ( ); 423 424 final Set<String> imagePathSet = new HashSet<String> ( ); 425 426 for ( final File imageFile : imageFiles ) 427 { 428 imagePathSet.add ( imageFile.getCanonicalPath ( ) ); 429 } 430 431 imagePaths = imagePathSet.toArray ( new String [ 0 ] ); 432 433 Arrays.sort ( imagePaths ); 434 } 435 catch ( IOException ex ) 436 { 437 ex.printStackTrace ( ); 438 } 439 } 440 441 //////////////////////////////////////////////////////////////////////// 442 //////////////////////////////////////////////////////////////////////// 443 }