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        }