////
//// support code for Subbiah Design website
////
////
//// home page slideshow
////

//
// required:
//   jquery.js (version 1.3.2+) (see jquery.com)
//


// The slideshow is implemented as an object of type Slideshow.

//
// Slideshow object constructor
// the constructor initializes variables that are set per instance
//
function Slideshow() {
  // list of slides
  this.slides = Array(); // each element will be an object with image and text
  // number of slides
  this.nslides = 0;
  // index of currently displayed slide
  this.current = -1;
  // index of next slide to display
  this.next = -1;
  // timer for update()
  this.intervalid = null;
  // timer for automatic slide change, used within update()
  this.timerid = null;
  // currently animating from one slide to another
  this.animating = false;
  // queue of actions
  this.actionqueue = Array(); // each element will be an object with action and possibly slide index
  // slide show paused
  this.paused = false;
}

//
// Slideshow object default constants
// set in prototype
// these can be overridden in each instance, but do not need to be
//
// time for normal transition
Slideshow.prototype.changeTime = 800;
// time between automatic slide changes
Slideshow.prototype.onTime = 4000;



//
// addAction()
// add action to queue
// action should be
//  'show' = immediately show item
//  'prev' = animate to previous
//  'next' = animate to next
//
Slideshow.prototype.addAction = function(action, item) {
  slideshow = this; // this slideshow object

  // add action to queue
  slideshow.actionqueue.push({action:action, item:item});
}

//
// update()
// called at regular intervals to process queue and take other actions
// must be set up to be called by setInterval()
//
Slideshow.prototype.update = function() {
  slideshow = this; // this slideshow object

  // check if currently animating something
  //
  if (slideshow.animating) {
    // do nothing until animation finishes
  }
  // not animating - safe to proceed
  //
  else {
    // perform next action in queue, if any
    //
    if (slideshow.actionqueue.length > 0) {

      // cancel any pending automatic changes
      if (slideshow.timerid != null) {
        clearTimeout (slideshow.timerid);
        slideshow.timerid = null;
      }
      // stop any animations in progress, just to be safe
      jQuery.each(slideshow.slides, function() {
        this.slide.stop(true, true);
      });

      // get next action
      todo = slideshow.actionqueue.shift();

      // set flag that we are animating
      slideshow.animating = true;

      // perform action
      if (todo.action == 'show') {
        slideshow.showQuick(todo.item);
      }
      else { /*if (todo.action == 'next') {*/
        slideshow.showNext();
      }
    }
    // nothing in queue
    else {
      // check if paused
      if (slideshow.paused) {
        // cancel any pending automatic slide change
        if (slideshow.timerid != null) {
          clearTimeout (slideshow.timerid);
          slideshow.timerid = null;
        }
      }
      // not paused - check if we should start timer for auto change
      else if (slideshow.timerid == null) {
        // start timer for auto change
        slideshow.timerid = setTimeout("slideshow.timerid=null;slideshow.addAction('next')", slideshow.onTime);
      }
    }
  }
}

//
// showQuick()
// immediately show slide, without any animation
// called by update()
// used only for initial display of first slide
//  islide = slide to show
//
Slideshow.prototype.showQuick = function(islide) {
  slideshow = this; // this slideshow object

  // set current, previous, next
  slideshow.setCurrent(islide);

  // show selected slide, and hide others
  jQuery.each(slideshow.slides, function(i) {
    if (i == slideshow.current) {
      this.slide.css({opacity:1.0,display:"block"});
    }
    else {
      this.slide.css({opacity:0.0,display:"none"});
    }
  });

  // everything was done immediately, so set flag that we are not animating
  slideshow.animating = false;
}

//
// showNext()
// change to next group with animation
// called by update()
//
Slideshow.prototype.showNext = function() {
  slideshow = this; // this slideshow object

  // call helper function
  slideshow.showSlide(slideshow.current,slideshow.next);
}

//
// showSlide()
// change from one slide to another, with animation
// called by showNext()
//
Slideshow.prototype.showSlide = function(iold, inew) {
  slideshow = this; // this slideshow object

  //
  // animate to next slide
  //

  // fade out old slide
  slideshow.slides[iold].slide
    .animate({opacity:0.0}, slideshow.changeTime, function() {$(this).css({display:"none"}) });

  // fade in new slide
  slideshow.slides[inew].slide
    .css({opacity:0.0,display:"block"})
    .animate({opacity:1.0}, slideshow.changeTime);

  // set new current slide
  slideshow.setCurrent(inew);

  // reset animating flag after slide change interval
  $("#divslideshow").animate({left:"+=0"},slideshow.changeTime+1, function(){slideshow.animating=false;});

}

//
// clickNext()
// show next slide (button click response)
//
Slideshow.prototype.clickNext = function() {
  slideshow = this; // this slideshow object
  // add action to queue
  slideshow.addAction('next');
  // update immediately
  slideshow.update();
}
//
// pauseShow()
// pause slideshow (hover response)
//
Slideshow.prototype.pauseShow = function() {
  slideshow = this; // this slideshow object
  // set to paused
  slideshow.paused = true;
  // update immediately
  slideshow.update();
}
//
// resumeShow()
// resume slideshow after pause (hover response)
//
Slideshow.prototype.resumeShow = function() {
  slideshow = this; // this slideshow object
  // set to not paused
  slideshow.paused = false;
  // update immediately
  slideshow.update();
}
//
// utility: set current slide (and next)
// automatically brings into correct range
//
Slideshow.prototype.setCurrent = function(i) {
  slideshow = this; // this slideshow object
  slideshow.current  = (i + slideshow.nslides) % slideshow.nslides; // bring into range
  slideshow.next     = (i + slideshow.nslides + 1) % slideshow.nslides;
}


//
// initialize and start show
//

$(document).ready(function(){

  slideshow = new Slideshow();

  // randomly pick one slide to be shown first
  //
  slideshow.nslides = $("#divslideshow div.slide").length;
  if (slideshow.nslides == 0) {
    return;
  }
  slideshow.setCurrent(Math.floor(Math.random()*slideshow.nslides)); // sets current, prev, next

  // save array of slide objects, set initial properties, attach mouse functions
  $("#divslideshow div.slide").each( function(i) {
    // save in array
    slideshow.slides[i] = {};
    slideshow.slides[i].slide = $(this);
    slideshow.slides[i].image = $(this).find("div.image").eq(0);
    // set display of slide
    slideshow.slides[i].slide.css({display:"none"});
  });

  // if there is just one slide, immediately show it and return
  if (slideshow.nslides == 1) {
    slideshow.showQuick(0);
    return;
  }

  // attach hover over slides, to pause the show
  $("#divslideshow").hover( function() { slideshow.pauseShow(); },
                            function() { slideshow.resumeShow(); } );

  // attach functions to click on slide
  $("#divslideshow").click(function() { slideshow.clickNext(); this.blur(); return false; });

  // show first slide
  slideshow.addAction('next', slideshow.current);

  // start processing interval
  // the processing interval does not have to be extremely small in our case
  slideshow.intervalid = setInterval("slideshow.update()",100);

});
