001         package com.croftsoft.apps.ads;
002    
003         import java.applet.Applet;
004         import java.awt.*;
005         import java.io.*;
006         import java.net.*;
007         import java.util.*;
008    
009         /*********************************************************************
010         * Rotating ad banner applet.
011         *
012         * @version
013         *   2001-07-18
014         * @since
015         *   1997
016         * @author
017         *   <a href="https://www.croftsoft.com/">David Wallace Croft</a>
018         *********************************************************************/
019    
020         public final class  Ads extends Applet implements Runnable
021         //////////////////////////////////////////////////////////////////////
022         //////////////////////////////////////////////////////////////////////
023         {
024    
025         private static final String  APPLET_TITLE
026           = "Ads \u00A9 2001 David Wallace Croft";
027    
028         private static final String  APPLET_INFO
029           = "\n" + APPLET_TITLE + "\n"
030           + "croft@alumni.caltech.edu\n"
031           + "http://www.alumni.caltech.edu/~croft/\n"
032           + "Version 2001-07-18\n";
033    
034         private static final String  PARAM_DATA_FILENAME = "dataFilename";
035    
036         /**
037         * Modify to redirect control of what ads are displayed.
038         *
039         * The link is relative to the CodeBase although this may be modified
040         * as well.
041         */
042         private static final String  DEFAULT_DATA_FILENAME = "ads.dat";
043    
044         /**
045         * How long each image is displayed, in milliseconds.
046         */
047         private static final long    AIR_TIME = 15000;
048    
049         //
050    
051         private static Random  random = new Random ( );
052    
053         //
054    
055         private String     dataFilename;
056    
057         private Vector     imageURL_StringVector;
058    
059         private Vector     site_URL_StringVector;
060    
061         private Hashtable  imageUrlStringToImageHashtable;
062    
063         private Graphics   g;
064    
065         private Dimension  size;
066    
067         private Image      offscreenImage;
068    
069         private Graphics   offscreenGraphics;
070    
071         private boolean    shouldRun;
072    
073         private Thread     thread;
074    
075         private int        index;
076    
077         //////////////////////////////////////////////////////////////////////
078         //////////////////////////////////////////////////////////////////////
079    
080         public String  getAppletInfo ( )
081         //////////////////////////////////////////////////////////////////////
082         {
083           return APPLET_INFO;
084         }    
085    
086         public synchronized void  init ( )
087         //////////////////////////////////////////////////////////////////////
088         {
089           setCursor ( Cursor.getPredefinedCursor ( Cursor.HAND_CURSOR ) );
090    
091           imageURL_StringVector = new Vector ( );
092    
093           site_URL_StringVector = new Vector ( );
094    
095           imageUrlStringToImageHashtable = new Hashtable ( );
096    
097           dataFilename = getParameter ( PARAM_DATA_FILENAME );
098    
099           if ( dataFilename == null )
100           {
101             dataFilename = DEFAULT_DATA_FILENAME;
102           }
103    
104           loadData ( );
105         }
106    
107         public synchronized void  destroy ( )
108         //////////////////////////////////////////////////////////////////////
109         {
110           if ( g != null )
111           {
112             g.dispose ( );
113           }
114    
115           if ( offscreenGraphics != null )
116           {
117             offscreenGraphics.dispose ( );
118           }
119         }
120    
121         public synchronized void  start ( )
122         //////////////////////////////////////////////////////////////////////
123         {
124           g = getGraphics ( );
125    
126           size = size ( );
127    
128           offscreenImage = createImage ( size.width, size.height );
129    
130           offscreenGraphics = offscreenImage.getGraphics ( );
131    
132           shouldRun = true;
133    
134           ( thread = new Thread ( this ) ).start ( );
135         }
136    
137         public synchronized void  stop ( )
138         //////////////////////////////////////////////////////////////////////
139         {
140           shouldRun = false;
141    
142           if ( thread != null )
143           {
144             thread.interrupt ( );
145           }
146         }
147    
148         public void  run ( )
149         //////////////////////////////////////////////////////////////////////
150         {
151           int  count = imageURL_StringVector.size ( );
152    
153           while ( shouldRun )
154           {
155             int [ ]  random_order = random_order_list ( count );
156    
157             for ( int  i = 0; shouldRun && i < count; i++ )
158             {
159               index = random_order [ i ];
160    
161               try
162               {
163                 String  imageUrlString
164                   = ( String ) imageURL_StringVector.elementAt ( index );
165    
166                 Image  image = ( Image )
167                   imageUrlStringToImageHashtable.get ( imageUrlString );
168    
169                 if ( image == null )
170                 {
171                   image = getImage (
172                     new URL ( getCodeBase ( ), imageUrlString ) );
173    
174                   imageUrlStringToImageHashtable.put ( imageUrlString, image );
175                 }
176    
177                 if ( prepareImage ( image, size.width, size.height, this ) )
178                 {
179                   offscreenGraphics.drawImage (
180                     image, 0, 0, size.width, size.height, this );
181    
182                   paint ( g );
183                 }
184               }
185               catch ( Exception  e )
186               {
187                 e.printStackTrace ( );
188    
189                 showStatus ( e.getMessage ( ) );
190               }
191    
192               try
193               {
194                 thread.sleep ( AIR_TIME );
195               }
196               catch ( InterruptedException  e ) { }
197             }
198           }
199         }
200    
201         public boolean  imageUpdate (
202           Image  image, int  flags, int  x, int  y, int  w, int  h )
203         //////////////////////////////////////////////////////////////////////
204         {
205           if ( flags == 32 )
206           {
207             offscreenGraphics.drawImage (
208               image, 0, 0, size.width, size.height, this );
209    
210             paint ( g );
211           }
212    
213           return super.imageUpdate ( image, flags, x, y, w, h );
214         }
215    
216         public boolean  mouseMove ( Event evt, int x, int y )
217         //////////////////////////////////////////////////////////////////////
218         {
219           if ( site_URL_StringVector == null ) return true;
220    
221           if ( site_URL_StringVector.size ( ) <= index ) return true;
222    
223           showStatus ( ( String ) site_URL_StringVector.elementAt ( index ) );
224    
225           return true;
226         }
227    
228         public boolean  mouseUp ( Event  evt, int  x, int  y )
229         //////////////////////////////////////////////////////////////////////
230         {
231           if ( site_URL_StringVector == null ) return true;
232    
233           if ( site_URL_StringVector.size ( ) <= index ) return true;
234    
235           try
236           {
237             getAppletContext ( ).showDocument ( new URL (
238               ( String ) site_URL_StringVector.elementAt ( index ) ) );
239    
240           }
241           catch ( MalformedURLException  e )
242           {
243             e.printStackTrace ( );
244    
245             showStatus ( e.getMessage ( ) );
246           }
247    
248           return true;
249         }
250    
251         public void  paint ( Graphics  graphics )
252         //////////////////////////////////////////////////////////////////////
253         {
254           if ( offscreenImage == null ) return;
255    
256           graphics.drawImage ( offscreenImage, 0, 0, this );
257         }
258    
259         public void  update ( Graphics  graphics )
260         //////////////////////////////////////////////////////////////////////
261         {
262           paint ( graphics );
263         }
264    
265         public void  repaint ( )
266         //////////////////////////////////////////////////////////////////////
267         {
268           paint ( g );
269         }
270    
271         //////////////////////////////////////////////////////////////////////
272         // private methods
273         //////////////////////////////////////////////////////////////////////
274    
275         private synchronized boolean  loadData ( )
276         //////////////////////////////////////////////////////////////////////
277         {
278           try
279           {
280             URL  dataURL = new URL ( getCodeBase ( ), dataFilename );
281    
282             InputStream  conn = dataURL.openStream ( );
283    
284             DataInputStream  data = new DataInputStream ( conn );
285    
286             while ( true )
287             {
288               String  line = data.readLine ( );
289    
290               if ( line == null ) break;
291    
292               imageURL_StringVector.addElement ( line );
293    
294               site_URL_StringVector.addElement ( data.readLine ( ) );
295    
296               if ( data.readLine ( ) == null ) break;
297             }
298           }
299           catch ( Exception  e )
300           {
301             e.printStackTrace ( );
302    
303             showStatus ( e.getMessage ( ) );
304    
305             return false;
306           }
307    
308           return true;
309         }
310    
311         private static int [ ]  random_order_list ( int  count ) {
312         //////////////////////////////////////////////////////////////////////
313           Vector  vector = new Vector ( count );
314           for ( int  i = 0; i < count; i++ ) {
315             vector.addElement ( new Integer ( i ) );
316           }
317           int [ ]  random_order = new int [ count ];
318           for ( int  i = 0; i < count; i++ ) {
319             Integer  lucky = ( Integer ) vector.elementAt (
320               ( int ) roll ( 1, count - i, -1 ) );
321             vector.removeElement ( lucky );
322             random_order [ i ] = lucky.intValue ( );
323           }
324           return random_order;
325         }
326    
327         private static long roll (
328           long multiplier,
329           long base,
330           long offset )
331         //////////////////////////////////////////////////////////////////////
332         {
333           long temp = 0;
334    
335           for ( long index_roll = 0; index_roll < multiplier; index_roll++ )
336           {
337             temp += 1 + Math.round (
338               ( double ) ( base - 1 ) * random.nextDouble ( ) );
339           }
340    
341           return temp + offset;
342         }
343    
344         //////////////////////////////////////////////////////////////////////
345         //////////////////////////////////////////////////////////////////////
346         }