function remove_element(e)
{
  //if(e && e.parentNode)
  //  e.parentNode.removeChild(e);
  // Alternatively...
  if(e)
    e.style.display='none';
}

//
// SlideShowNext
//

function SlideShowNext(idx,last,delay)
{
  // The image to load
  this.idx= (idx+ss.len) % ss.len;
  // Last image in a slide-show, or -1.
  this.last=dflt(last,-1);
  // Minumum delay before displaying it.
  this.delay=dflt(delay,0);

  this.id=false;
  this.timer=false;
  this.req=false; // XMLHttpRequest object
  this.xml=false; // XML that describes the next image.
  this.img=false;
  this.img_complete=false; // img.complete doesn't work on Safari.

  // Event Handlers
  var self=this;

  this.evt_req_complete =function()
  {
    if(self.req && self.req.readyState==4)
    {
      if(self.req.status==200)
      {
        self.xml=
          self.req.responseXML.documentElement.getElementsByTagName('image');
        if(self.xml)
        {
          self.xml=self.xml[0];
          self.create_img();
        }
      }
      self.req=false;
    }
  }
  this.evt_img_onload =function(e)
  {
    if(e.currentTarget)   e=e.currentTarget; // Mozilla/Safari/w3c
    else if(window.event) e=window.event.srcElement; // IE

    if(self.img==e)
    {
      self.img_complete=true;   
      self.show();
    }
  }
  this.evt_timer =function()
  {
    self.timer=false;
    self.show();
  }
} // end SlideShowNext

SlideShowNext.prototype.load=function()
{
  this.id='img_'+this.idx+'_'+ss.isize;
  this.timer=setTimeout(this.evt_timer,this.delay);
  this.req=new XMLHttpRequest();
  if(this.req)
  {
    this.req.open('GET','?d=x&img='+this.idx+'&isize='+ss.isize,true);
    this.req.setRequestHeader(
      'If-Modified-Since','Sat, 1 Jan 2000 00:00:00 GMT');
    this.req.onreadystatechange=this.evt_req_complete;
    this.req.send(null);
  }
  else
  {
    this.cancel();
    return;
  }
  document.getElementById('busy').style.display='inline';
}

SlideShowNext.prototype.cancel=function()
{
  if(this.timer)
    clearTimeout(this.timer);
  if(this.img)
    remove_element(this.img);
  if(this.req)
    this.req.abort();
  if(this==ss.next)
    ss.next=false;
}

/** Utility function, called by evt_req_complete(). Creates the img element. */
SlideShowNext.prototype.create_img=function()
{
  this.img=document.getElementById(this.id);
  if(this.img)
  {
    this.img_complete=true; // not necessarily true, but probably OK.
    this.show();
  }
  else
  {
    // Create a new image.
    this.img=document.createElement('img');
    this.img.style.display='none';
    document.getElementById('single').appendChild(this.img);
    this.img.setAttribute('id',this.id);
    addEvent(this.img,'load',this.evt_img_onload);
    this.img.setAttribute('src',this.xml.getAttribute('src'));
    this.img.setAttribute('width',this.xml.getAttribute('width'));
    this.img.setAttribute('height',this.xml.getAttribute('height'));
  }
}

SlideShowNext.prototype.show=function()
{
  // Ready when timeout has expired and the img is loaded.
  if( ss.next!=this || this.timer || !this.xml || !this.img_complete)
    return;

  // Show the image
  remove_element( document.getElementById(ss.curr_id) );
  this.img.style.display='block';
  // Change the title
  document.title=this.xml.getAttribute('title');
  document.getElementById('title').innerHTML=document.title;
  // Change the download link
  document.getElementById('download').href='?dl&img='+this.idx;
  // Change the nav links
  document.getElementById('nav_t').href='?d=t&img='+this.idx;
  document.getElementById('nav_c').href='?d=c&img='+this.idx;
  document.getElementById('busy').style.display='none';
  // Clean up and get the next one...
  var stop=( this.idx!=ss.curr && this.idx==this.last );
  ss.curr=this.idx;
  ss.curr_id=this.id;
  ss.next=false;
  if(stop)
  {
    ss.do_stop();
  }
  else if(this.last>=0)
  {
    ss.next=new SlideShowNext(ss.curr+1,this.last,ss.delay);
    ss.next.load()
  }
}

//
//  SlideShow
//

function SlideShow(curr,len,isize,delay)
{
  this.curr=curr;
  this.curr_id='img_'+curr+'_'+isize;

  this.len=len;
  this.next=false;
  // The desired image size (may not always be the size of the current image).
  this.isize=isize;

  this.delay=dflt(delay,4000);

  // constants
  this.min_isize=0;
  this.max_isize=5;
}

SlideShow.prototype.do_prev=function()
{
  this.do_next(-1);
}

SlideShow.prototype.do_next=function(offset)
{
  offset=dflt(offset,1);
  var next=new SlideShowNext(this.curr+offset);
  if(this.next)
  {
    if(this.next.last>=0)
      return; // Playing slide show - ignore.
    if(this.next.idx==next.idx)
      return; // already loading this one (for some reason).
    this.next.cancel()
  }
  this.next=next;
  this.next.load()
}

SlideShow.prototype.do_play=function()
{
  var next=new SlideShowNext(this.curr+1,this.curr,this.delay);
  if(this.next)
  { 
    if(this.next.idx==next.idx)
      return; // already loading this one
    this.next.cancel();
  }
  this.next=next;
  this.next.load()
  // Set control to STOP
  document.getElementById('play').style.display='none';
  document.getElementById('stop').style.display='inline';
  document.getElementById('prev').className='off';
  document.getElementById('next').className='off';
}

SlideShow.prototype.do_stop=function()
{
  if(this.next)
    this.next.cancel();
  document.getElementById('busy').style.display='none';
  document.getElementById('play').style.display='inline';
  document.getElementById('stop').style.display='none';
  document.getElementById('prev').className='on';
  document.getElementById('next').className='on';
}

SlideShow.prototype.do_bigger=function()
{
  if(this.isize < this.max_isize)
    ss.resize(this.isize+1);
}

SlideShow.prototype.do_smaller=function()
{
  if(this.isize > this.min_isize)
    ss.resize(this.isize-1);
}


/** Utility function called by do_bigger() & do_smaller(). */
SlideShow.prototype.resize=function(isize)
{
  this.isize=isize;
  // Store isize to a cookie - this tells the server which size image to send.
  document.cookie=('isize='+this.isize+'; path=/');
  // Load the new image.
  var last=-1;
  if(this.next)
  {
    last=this.next.last;
    this.next.cancel();
  }
  this.next=new SlideShowNext(this.curr,last);
  this.next.load()

  // toggle size icons
  var smaller=document.getElementById('smaller');
  if(this.isize > this.min_isize)
    smaller.className='on';
  else
    smaller.className='off';

  var bigger=document.getElementById('bigger');
  if(this.isize < this.max_isize)
    bigger.className='on';
  else
    bigger.className='off';
}


