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 }