/*
 * import JSVM
 */

/*
 * public class Slideshow
 */

function Slideshow ( slides , width , height )
{ this . screen = Screen_Factory . get_Screen ( width , height ) ;
  this . set = new Set ( slides ) ;
  this . sequencer = new Sequencer ( this . set , this . screen ) ;
  this . set_order = Slideshow_set_order ;
  this . play = Slideshow_play ;
  this . pause = Slideshow_pause ;
  this . ff = Slideshow_ff ;
  this . rr = Slideshow_rr ;
  this . next = Slideshow_next ;
  this . prev = Slideshow_prev ;
  this . set_background_color = Slideshow_set_background_color ;
  { document . write ( this . screen . get_HTML ( ) ) ;
    JSVM . add_Updatable ( this . set ) ;
    JSVM . add_Updatable ( this . sequencer ) ;
  }
}

function Slideshow_set_order ( order )
  { this . set . set_order ( order ) ;
  } ;
function Slideshow_play ( )
  { this . sequencer . play ( ) ;
  } ;
function Slideshow_pause ( )
  { this . sequencer . pause ( ) ;
  } ;
function Slideshow_ff ( )
  { this . sequencer . ff ( ) ;
  } ;
function Slideshow_rr ( )
  { this . sequencer . rr ( ) ;
  } ;
function Slideshow_next ( )
  { this . sequencer . goto_next ( ) ;
  } ;
function Slideshow_prev ( )
  { this . sequencer . goto_previous ( ) ;
  } ;
function Slideshow_set_background_color ( color )
  { this . screen . set_background_color ( color ) ;
  } ;

/*
 * public class Slide
 */

function Slide ( image_URL , caption , link_URL , exposure_milliseconds )
{ this . image_URL = image_URL ;
  this . caption = caption ;
  this . link_URL = link_URL ;
  this . exposure_milliseconds = exposure_milliseconds ;
  this . image = new Image ( ) ;
  this . load = Slide_load ;
  this . is_loading = Slide_is_loading ;
  this . is_loaded = Slide_is_loaded ;
}

function Slide_load ( )
{ if ( this . image . complete )
  { return ;
  }
  if ( this . image . src == this . image_URL )
  { return ;
  }
  this . image . src = this . image_URL ;
}
function Slide_is_loading ( )
{ return ( ! this . image . complete ) && this . image . src == this . image_URL ;
}
function Slide_is_loaded ( )
{ return this . image . complete ;
}

/*
 * public class Set
 */

function Set ( slides )
{ this . slides = slides ;
  this . preloading = true ;
  this . get_Slide = Set_get_Slide ;
  this . set_order = Set_set_order ;
  this . update = Set_update ;
}

function Set_get_Slide ( index )
{ while ( index < 0 )
  { index += this . slides . length ;
  }
  while ( index >= this . slides . length )
  { index -= this . slides . length ;
  }
  return this . slides [ index ] ;
}
function Set_set_order ( order )
{ order . set_order ( this . slides ) ;
}
function Set_update ( )
{ if ( ! this . preloading )
  { return ;
  }
  var x = 0 ;
  var loading = 0 ;
  while ( x < this . slides . length && loading < 3 )
  { if ( ! this . slides [ x ] . is_loaded ( ) )
    { this . slides [ x ] . load ( ) ;
      loading ++ ;
    }
    x ++ ;
  }
  if ( loading == 0 )
  { this . preloading = false ;
  }
}

/*
 *
 * public interface Order
 * { public void set_order ( frameset ) ;
 * }
 *
 */

function exchange ( array , index_1 , index_2 )
{ var temp = array [ index_1 ] ;
  array [ index_1 ] = array [ index_2 ] ;
  array [ index_2 ] = temp ;
}

function get_random_int ( min , max )
{ return Math . floor ( Math . random ( ) * ( max - min ) ) + min ;
}

/*
 * public class Reverse_Order
 */

function Reverse_Order ( )
{ this . set_order = Reverse_Order_set_order ;
}

function Reverse_Order_set_order ( slides )
{ var stop = Math . floor ( slides . length / 2 ) ;
  var x = 0 ;
  var y = slides . length - 1 ;
  while ( x <= stop )
  { exchange ( slides , x ++ , y -- ) ;
  }
}

/*
 * public class Random_Order
 */

function Random_Order ( )
{ this . set_order = Random_Order_set_order ;
}

function Random_Order_set_order ( slides )
{ var x = 0 ;
  while ( x < slides . length )
  { exchange ( slides , x ++ , get_random_int ( 0 , slides . length ) ) ;
  }
}

/*
 * public class Sequencer
 */

Sequencer . PAUSE = 1 ;
Sequencer . PLAY = 2 ;
Sequencer . FF = 3 ;
Sequencer . RR = 4 ;

function Sequencer ( set , screen )
{ this . set = set ;
  this . screen = screen ;
  this . next_update = new Date ( ) . getTime ( ) ;
  this . interval = 1 ;
  this . current_index = 0 - this . interval ;
  this . state = Sequencer . PLAY ;
  this . update = Sequencer_update ;
  this . set_current_index = Sequencer_set_current_index ;
  this . goto_next = Sequencer_goto_next ;
  this . goto_previous = Sequencer_goto_previous ;
  this . play = Sequencer_play ;
  this . pause = Sequencer_pause ;
  this . ff = Sequencer_ff ;
  this . rr = Sequencer_rr ;
}

function Sequencer_update ( )
{ if ( this . state == Sequencer . PAUSE )
  { return ;
  }
  else if ( this . state == Sequencer . PLAY )
  { if ( this . next_update <= new Date ( ) . getTime ( ) )
    { var next_index = this . current_index + this . interval ;
      if ( this . set . get_Slide ( next_index ) . is_loaded ( ) )
      { this . set_current_index ( next_index ) ;
      }
    }
  }
  else if ( this . state == Sequencer . FF )
  { this . goto_next ( ) ;
  }
  else if ( this . state == Sequencer . RR )
  { this . goto_previous ( ) ;
  }
}
function Sequencer_set_current_index ( current_index )
{ this . current_index = current_index ;
  var slide = this . set . get_Slide ( this . current_index ) ;
  slide . load ( ) ;
  this . screen . show ( slide ) ;
  this . next_update = slide . exposure_milliseconds + new Date ( ) . getTime ( ) ;
}
function Sequencer_goto_next ( )
{ this . set_current_index ( this . current_index + this . interval ) ;
}
function Sequencer_goto_previous ( )
{ this . set_current_index ( this . current_index - this . interval ) ;
}
function Sequencer_play ( )
{ this . state = Sequencer . PLAY ;
}
function Sequencer_pause ( )
{ this . state = Sequencer . PAUSE ;
}
function Sequencer_ff ( )
{ this . state = Sequencer . FF ;
}
function Sequencer_rr ( ) 
{ this . state = Sequencer . RR ;
}

/*
 * public class Screen_Factory
 */

Screen_Factory = new Object ( ) ; // class object for Screen_Factory
Screen_Factory . ID = 1 ; // static unique ID for screens (document elements)
Screen_Factory . get_Screen = Screen_Factory_get_Screen ; // factory method returns Screen object
Screen_Factory . get_ID = Screen_Factory_get_ID ; // return unique ID for each call

function Screen_Factory_get_Screen ( width , height )
{ var ID = Screen_Factory . get_ID ( ) ;
  var v = navigator . appVersion ;
  var n = navigator . appName ;
  var a = navigator . userAgent ;
  if ( n . indexOf ( 'Microsoft' ) != -1 && parseInt ( v ) >= 4 ) { return new IE56_Screen ( ID , width , height ) ; }
  if ( a . indexOf ( 'Netscape6' ) != -1 ) { return new NS6_Screen ( ID , width , height ) ; }
  return new HTML4_Screen ( ID , width , height ) ;
}
function Screen_Factory_get_ID ( )
{ return Screen_Factory . ID ++ ;
}

/*
 *
 * public interface screen
 * { public String get_HTML ( ) ;
 *   public void show ( Slide slide ) ;
 *   public void set_background_color ( String color ) ;
 * }
 *
 */

/*
 * public class IE56_Screen implements Screen
 */

IE56_Screen . TRANSITIONS = [ "progid:DXImageTransform.Microsoft.Barn( motion=out,orientation=vertical)" ,
	"progid:DXImageTransform.Microsoft.Blinds( Bands=10,direction=up)" ,
	"progid:DXImageTransform.Microsoft.Checkerboard( Direction=right,SquaresX=2,SquaresY=2)" ,
	"progid:DXImageTransform.Microsoft.Fade(Overlap=1.00)" ,
	"progid:DXImageTransform.Microsoft.GradientWipe(GradientSize=0.25,wipestyle=0,motion=forward)" ,
	"progid:DXImageTransform.Microsoft.Inset()" ,
	"progid:DXImageTransform.Microsoft.Iris(irisstyle=PLUS,motion=out)" ,
	"progid:DXImageTransform.Microsoft.Pixelate(MaxSquare=50)" ,
	"progid:DXImageTransform.Microsoft.RadialWipe(wipestyle=CLOCK)" ,
	"progid:DXImageTransform.Microsoft.RandomBars()" ,
	"progid:DXImageTransform.Microsoft.RandomDissolve()" ,
	"progid:DXImageTransform.Microsoft.Slide(slidestyle=HIDE,Bands=1)" ,
	"progid:DXImageTransform.Microsoft.Spiral(GridSizeX=16,GridSizeY=16)" ,
	"progid:DXImageTransform.Microsoft.Stretch(stretchstyle=SPIN)" ,
	"progid:DXImageTransform.Microsoft.Strips(motion=leftdown)" ,
	"progid:DXImageTransform.Microsoft.Wheel(spokes=4)" ,
	"progid:DXImageTransform.Microsoft.Zigzag(GridSizeX=16,GridSizeY=16)" ] ;
IE56_Screen . FILTERS = [ "progid:DXImageTransform.Microsoft.Alpha( style=1,opacity=25,finishOpacity=100,startX=0,finishX=100,startY=100,finishY=0)" ,
	"progid:DXImageTransform.Microsoft.AlphaImageLoader( src=notebook.GIF, sizingmethod=crop)" ,
	"progid:DXImageTransform.Microsoft.BasicImage( Rotation=0,Mirror=0,Invert=0,XRay=0,Grayscale=0,Opacity=1.00)" ,
	"progid:DXImageTransform.Microsoft.Blur( PixelRadius=5,MakeShadow=false)" ,
	"progid:DXImageTransform.Microsoft.Chroma( Color=#FFFFFF)" ,
	"progid:DXImageTransform.Microsoft.dropShadow( Color=999999,offX=5,offY=5,positive=true)" ,
	"progid:DXImageTransform.Microsoft.Emboss()" ,
	"progid:DXImageTransform.Microsoft.Engrave( )" ,
	"progid:DXImageTransform.Microsoft.Glow(color=#ff00ff,strength=5)" ,
	"progid:DXImageTransform.Microsoft.Gradient(gradientType=0,startColorStr=#ff00ff,endColorStr=#00ff99)" ,
	"progid:DXImageTransform.Microsoft.MotionBlur(direction=0,strength=5)" ,
	"progid:DXImageTransform.Microsoft.Pixelate( maxsquare=10)" ,
	"progid:DXImageTransform.Microsoft.Shadow(direction=0,color=#ff00ff,strength=5)" ,
	"progid:DXImageTransform.Microsoft.Wave(freq=1,LightStrength=10,Phase=10,Strength=5)" ] ;

function IE56_Screen ( ID , width , height )
{ this . ID = ID ;
  this . width = width ;
  this . height = height ;
  this . get_HTML = IE56_Screen_get_HTML ;
  this . show = IE56_Screen_show ;
  this . get_scale = IE56_Screen_get_scale ;
  this . get_transition = IE56_Screen_get_transition ;
  this . get_filter = IE56_Screen_get_filter ;
  this . set_background_color = IE56_Screen_set_background_color ;
}

function IE56_Screen_get_HTML ( )
{ return '<table id="t' + this . ID + '" style="border-collapse:collapse;border-style:none;width:' + this . width + 'px;height:' + this . height + 'px;"><tr><td style="vertical-align:middle;text-align:center;overflow:hidden;"><img id="i' + this . ID + '" src="" alt="Slideshow 1.0 [Matthew Copeland] copyright 2002" style="width:' + this . width + 'px;height:' + this . height + 'px;border-style:none;" /></td></tr></table>' ;
}
function IE56_Screen_show ( slide )
{ var scale = this . get_scale ( slide ) ;
  with ( document . all [ 'i' + this . ID ] )
  { style . filter = this . get_transition ( ) + this . get_filter ( ) ;
    filters [ 0 ] . apply ( ) ;
    filters [ 1 ] . apply ( ) ;
    style . width = ( slide . image . width * scale ) + 'px' ;
    style . height = ( slide . image . height * scale ) + 'px' ;
    src = slide . image . src ;
    alt = slide . caption ;
    filters [ 0 ] . play ( ) ;
    onclick = function ( ) { location = slide . link_URL ; } ;
    onmouseover = function ( ) { status = slide . link_URL ; } ;
    onmouseout = function ( ) { status = '' ; } ;
  }
}
function IE56_Screen_get_scale ( slide )
{ var width = this . width / slide . image . width ;
  var height = this . height / slide . image . height ;
  return width < height ? width : height ;
}
function IE56_Screen_get_transition ( )
{ return IE56_Screen . TRANSITIONS [ get_random_int ( 0 , 16 ) ] ;
}
function IE56_Screen_get_filter ( )
{ return IE56_Screen . FILTERS [ 2 ] ;
}
function IE56_Screen_set_background_color ( color )
{ document . all [ 't' + this . ID ] . style . background = color ;
}

/*
 * public class NS6_Screen implements Screen
 */

function NS6_Screen ( ID , width , height )
{ this . ID = ID ;
  this . width = width ;
  this . height = height ;
  this . get_HTML = function ( )
  { return '<table id="t' + this . ID + '" style="border-spacing:0px;border-style:none;width:' + this . width + 'px;height:' + this . height + 'px;"><tr><td style="vertical-align:middle;text-align:center;padding0px;"><img id="i' + this . ID + '" src="" alt="Slideshow 1.0 [Matthew Copeland] copyright 2002" style="border-style:none;" /></td></tr></table>' ;
  } ;
  this . show = function ( slide )
  { var scale = this . get_scale ( slide ) ;
    document . getElementById ( 'i' + this . ID ) . onclick = function ( ) { window . location = slide . link_URL ; } ;
    document . getElementById ( 'i' + this . ID ) . onmouseover = function ( ) { window . status = slide . link_URL ; } ;
    document . getElementById ( 'i' + this . ID ) . onmouseout = function ( ) { window . status = '' ; } ;
    document . getElementById ( 'i' + this . ID ) . width = this . width ;
    document . getElementById ( 'i' + this . ID ) . height = this . height ;
    document . getElementById ( 'i' + this . ID ) . src = slide . image_URL ;
    document . getElementById ( 'i' + this . ID ) . alt = slide . caption ;
  } ;
  this . get_scale = function ( slide )
  { var width = this . width / slide . image . width ;
    var height = this . height / slide . image . height ;
    return width < height ? width : height ;
  } ;
  this . set_background_color = function ( color )
  { document . getElementById ( 't' + this . ID ) . style . backgroundColor = color ;
  } ;
}

/*
 * public class HTML4_Screen
 */

function HTML4_Screen ( ID , width , height )
{ this . ID = ID ;
  this . width = width ;
  this . height = height ;
  this . get_HTML = HTML4_Screen_get_HTML ;
  this . show = HTML4_Screen_show ;
  this . get_scale = HTML4_Screen_get_scale ;
  this . set_background_color = HTML4_Screen_set_background_color ;
}

function HTML4_Screen_get_HTML ( )
{ return '<table cellpadding="0" cellspacing="0" border="0" width="' + this . width + '" height="' + this . height + '"><tr><td valign="center" align="center"><img name="i' + this . ID + '" src="" alt="Slideshow 1.0 [Matthew Copeland] copyright 2002" border="0" /></td></tr></table>' ;
}
function HTML4_Screen_show ( slide )
{ var scale = this . get_scale ( slide ) ;
  document [ 'i' + this . ID ] . onclick = function ( ) { window . location = slide . link_URL ; } ;
  document [ 'i' + this . ID ] . onmouseover = function ( ) { window . status = slide . link_URL ; } ;
  document [ 'i' + this . ID ] . onmouseout = function ( ) { window . status = '' ; } ;
  document [ 'i' + this . ID ] . width = slide . image . width * scale ;
  document [ 'i' + this . ID ] . height = slide . image . height * scale ;
  document [ 'i' + this . ID ] . src = slide . image . src ;
  document [ 'i' + this . ID ] . alt = slide . caption ;
}
function HTML4_Screen_get_scale ( slide )
{ var width = this . width / slide . image . width ;
  var height = this . height / slide . image . height ;
  return width < height ? width : height ;
}
function HTML4_Screen_set_background_color ( color )
{ return ;
}