jQuery.fn.lightbox = function(options) {

  slideshow_id =  jQuery(this).attr('href').substr(1); // chop off the "#" from the href value

  settings = jQuery.extend({
    overlay_background_color: '#000',
    overlay_opacity:          0.8
  },options);

  jQuery("body").append( build_lightbox() );
  open();


  // ** constructor methods **

  function build_lightbox(){

    control_strings = [];
    slideshow_frames = [];

    jQuery.each(slideshow_images[slideshow_id]['images'],function(i){

      i += 1; // css styles are 1-based, so we increment i to accomodate

      control_strings.push('<li><a href="#slideshow_frame' + i + '" class="frame' + i + '"><span>' + i + '</span></a></li>');
      if ( slideshow_images[slideshow_id]['url'] )
        slideshow_frames.push('<div id="slideshow_frame' + i + '" class="hidden clearfix" style="background-image: url(\'' + this + '\');"><a href="' + slideshow_images[slideshow_id]['url'] + '" class="mask"></a></div>');
      else
        slideshow_frames.push('<div id="slideshow_frame' + i + '" class="hidden clearfix" style="background-image: url(\'' + this + '\');"></div>');
    });

    if ( slideshow_images[slideshow_id]['url'] )
      slideshow_html = '<div id="slideshow"><div id="slideshow-controls" class="controls"><ul class="clearfix" style="z-index: 200">' + control_strings.join('') + '</ul></div><a href="' + slideshow_images[slideshow_id]['url'] + '" class="website" target="_blank"><span>' + slideshow_images[slideshow_id]['title'] + '</span></a>' + slideshow_frames.join('') + '</div>';
    else
      slideshow_html = '<div id="slideshow"><div id="slideshow-controls" class="controls"><ul class="clearfix" style="z-index: 200">' + control_strings.join('') + '</ul></div>' + slideshow_frames.join('') + '</div>';

    return '<div id="lightbox-overlay"></div><div id="lightbox-position"><div id="lightbox-matte">' + slideshow_html + '<div id="lightbox-control">click to close</div></div></div>';

  }


  // ** control methods **

  function open(){

    jQuery('embed, object, select').css({ 'visibility' : 'hidden' });

    var page_size = get_page_size();
    var page_scroll = get_page_scroll();

    jQuery("#lightbox-overlay").css({
      backgroundColor:  settings.overlay_background_color,
      opacity:          settings.overlay_opacity,
      width:            page_size[0],
      height:           page_size[1]
    }).fadeIn();

    jQuery('#lightbox-position').css({
      top:  page_scroll[1] + (page_size[3] / 10),
      left: page_scroll[0]
    }).show();

    // attach a resize and scroll event to ensure proper positioning
    jQuery(window).resize( reposition );
    jQuery(window).scroll( reposition );

    jQuery("#lightbox-matte").click( close );

    jQuery("#slideshow-controls").rotator({
      selectedClass: 'selected',
      unselectClass: 'unselect',
      hideClass:     'hidden',
      interval:      0
    });

  }

  function reposition(){

    var page_size = get_page_size();
    var page_scroll = get_page_scroll();

    jQuery('#lightbox-overlay').css({
      width:    page_size[0],
      height:   page_size[1]
    });

    jQuery('#lightbox-position').css({
      top:  page_scroll[1] + (page_size[3] / 10),
      left: page_scroll[0]
    });

  }

  function close(){
    jQuery('#lightbox-position').remove();
    jQuery('#lightbox-overlay').fadeOut(function() { jQuery('#lightbox-overlay').remove(); });

    jQuery('embed, object, select').css({ 'visibility' : 'visible' });
  }


  // ** utility methods **

  // @return Array Return an array with page width, height and window width, height
  // from quicksmode.com
  function get_page_size() {
    var xScroll, yScroll;
    if (window.innerHeight && window.scrollMaxY) {
      xScroll = window.innerWidth + window.scrollMaxX;
      yScroll = window.innerHeight + window.scrollMaxY;
    } else if (document.body.scrollHeight > document.body.offsetHeight){ // all but Explorer Mac
      xScroll = document.body.scrollWidth;
      yScroll = document.body.scrollHeight;
    } else { // Explorer Mac...would also work in Explorer 6 Strict, Mozilla and Safari
      xScroll = document.body.offsetWidth;
      yScroll = document.body.offsetHeight;
    }
    var windowWidth, windowHeight;
    if (self.innerHeight) { // all except Explorer
      if(document.documentElement.clientWidth){
        windowWidth = document.documentElement.clientWidth;
      } else {
        windowWidth = self.innerWidth;
      }
      windowHeight = self.innerHeight;
    } else if (document.documentElement && document.documentElement.clientHeight) { // Explorer 6 Strict Mode
      windowWidth = document.documentElement.clientWidth;
      windowHeight = document.documentElement.clientHeight;
    } else if (document.body) { // other Explorers
      windowWidth = document.body.clientWidth;
      windowHeight = document.body.clientHeight;
    }
    // for small pages with total height less then height of the viewport
    if(yScroll < windowHeight){
      pageHeight = windowHeight;
    } else {
      pageHeight = yScroll;
    }
    // for small pages with total width less then width of the viewport
    if(xScroll < windowWidth){
      pageWidth = xScroll;
    } else {
      pageWidth = windowWidth;
    }
    arrayPageSize = new Array(pageWidth,pageHeight,windowWidth,windowHeight);
    return arrayPageSize;
  };

  // @return Array Return an array with x,y page scroll values.
  // from quicksmode.com
  function get_page_scroll() {
    var xScroll, yScroll;
    if (self.pageYOffset) {
      yScroll = self.pageYOffset;
      xScroll = self.pageXOffset;
    } else if (document.documentElement && document.documentElement.scrollTop) {   // Explorer 6 Strict
      yScroll = document.documentElement.scrollTop;
      xScroll = document.documentElement.scrollLeft;
    } else if (document.body) {// all other Explorers
      yScroll = document.body.scrollTop;
      xScroll = document.body.scrollLeft;
    }
    arrayPageScroll = new Array(xScroll,yScroll);
    return arrayPageScroll;
  };

};
