/**
 * PhotoSwitcher
 *   by Sam Riesland
 *
 *   A relatively hackish first attempt at a photo switcher album thing...
 *
 * Note: This script depends on jquery.js being loaded first in the HTML page.
 */

var CatNameToIdx = new Array();
var CurrentCat = 0;
var CurrentSubCat = 0;
var ImgNum = 0; // current image index
var ImgLength = 0; // number of images to load in viewer
ImgCategories = null; // main structure to hold photos
var ImgPreloaderArray = null; // current collection of images in memory
var CaptionElementId = "conTitle";
var Safari = (navigator.userAgent.indexOf('Safari')!=-1);
var LoadingImgSrc = "../common/loading.png";

$(document).ready(function() {
	$('#controller #conPrevious a').click(function() {
		nextImage(-1);
	});
	
	$('#controller #conNext a').click(function() {
		nextImage(1);
	});
});

/*************************************************************
 * Classes
 */

function Category(index, name, label) {
    this.index = index;
    this.name = name;
    CatNameToIdx[name] = index;
    this.label = label;
    this.thumbnail = null;
    this.subCategories = null;
    this.images = null;
}

function Picture(src, caption) {
    this.src = src;
    this.caption = caption;
}

/*
 * ImagePreloader
 *   Author: Guyon Roche
 *
 *   Takes an array of images and calls the passed in function "callback" when
 *   it is finished preloading the images into the browser.  The callback
 *   function takes two arguments: (an array of images, and the number loaded
 *   successfully).
 */
function ImagePreloader(images, callback)
{
   // store the callback for later use
   this.callback = callback;

   // initialize internal state.
   this.nLoaded = 0;
   this.nProcessed = 0;
   this.aImages = new Array;

   // record the number of images.
   this.nImages = images.length;
 
   // for each image, call preload()
   for ( var i = 0; i < images.length; i++ )
      this.preload(images[i]);
}
ImagePreloader.prototype.preload = function(image)
{
   // create new Image object and add to array
   var oImage = new Image;
   this.aImages.push(oImage);
  
   // set up event handlers for the Image object
   oImage.onload = ImagePreloader.prototype.onload;
   oImage.onerror = ImagePreloader.prototype.onerror;
   oImage.onabort = ImagePreloader.prototype.onabort;
  
   // assign pointer back to this.
   oImage.oImagePreloader = this;

   // flag indicating successful load of image
   oImage.bLoaded = false;
  
   // assign the .src property of the Image object starting the load of the image
   oImage.src = image.src;
}
ImagePreloader.prototype.onComplete = function()
{
   this.nProcessed++;
   if ( this.nProcessed == this.nImages )
   {
      this.callback(this.aImages, this.nLoaded);
   }
}
// onload event is raised when image is loaded into memory
ImagePreloader.prototype.onload = function()
{
   this.bLoaded = true;
   this.oImagePreloader.nLoaded++;
   this.oImagePreloader.onComplete();
}
// raised when an error occurs while loading the image
ImagePreloader.prototype.onerror = function()
{
   this.bError = true;
   this.oImagePreloader.onComplete();
}
// raised if the user cancels the load by clicking their browser's stop button
ImagePreloader.prototype.onabort = function()
{
   this.bAbort = true;
   this.oImagePreloader.onComplete();
}


/*************************************************************
 * Functions
 */

function createSubCategory(cName, scName, scLabel, thumbnail, images) {
    var cIndex = CatNameToIdx[cName];
    if (ImgCategories[cIndex].subCategories == null) {
        ImgCategories[cIndex].subCategories = new Array();
    }
    var i = ImgCategories[cIndex].subCategories.length;
    var sc = new Category(i, scName, scLabel);
    sc.thumbnail = thumbnail;
    sc.images = images;
    ImgCategories[cIndex].subCategories.push(sc);
}

function setCaption() {
    // while I realize I shouldn't be using innerHTML, it is necessary for the
    // embedded HTML Erin wants to include in her captions... using textContent
    // just doesn't quite work.
    document.getElementById(CaptionElementId).innerHTML = ImgCategories[CurrentCat].subCategories[CurrentSubCat].images[ImgNum].caption;
}

function onPreload(aImages, nImages) {
    if (nImages != 1) {
        // show error in caption...
        document.getElementById(CaptionElementId).innerHTML = "Failed to load...";
    }
    else {
        setCaption();
    }
}

function changeImgNum(num) {
    ImgNum = num;
    var newImg = ImgCategories[CurrentCat].subCategories[CurrentSubCat].images[ImgNum];
    if (Safari) {
        // a safari bug -- have to load a very small image first so the sizing is right.
	document.images["slideshow"].src = LoadingImgSrc;
        setCaption();
	document.images["slideshow"].src = newImg.src;
        return;
    }
    if (ImgPreloaderArray[ImgNum] == null) {
        document.getElementById(CaptionElementId).textContent = "Loading...";  // caption
        var wrapperArray = new Array;
        wrapperArray.push(newImg);
        ImgPreloaderArray[ImgNum] = new ImagePreloader(wrapperArray, onPreload); // initiate download of image
    }
    else {
        setCaption();
    }
    document.slideshow.src = ImgPreloaderArray[ImgNum].aImages[0].src;
}

function nextImage(direction) {
    if (ImgNum < 0) {
        return;
    }
    newImgNum = ImgNum + direction;
    if (newImgNum > ImgLength) {
        newImgNum = 0;
    }
    if (newImgNum < 0) {
        newImgNum = ImgLength;
    }
    changeImgNum(newImgNum);
}

function changeSubCat(newIndex) {
    var thumbnails = document.getElementById("pmThumbnails").getElementsByTagName('img');
    thumbnails[CurrentSubCat].setAttribute('class', 'unselected');
    thumbnails[newIndex].setAttribute('class', 'selected');
    CurrentSubCat = newIndex;
    ImgLength = ImgCategories[CurrentCat].subCategories[CurrentSubCat].images.length - 1;
    // create a preloader for each image
    ImgPreloaderArray = new Array(ImgCategories[CurrentCat].subCategories[CurrentSubCat].images.length);
    for (var i=0; i<ImgPreloaderArray.length; i++) {
        ImgPreloaderArray[i] = null;
    }
    changeImgNum(0);
}

function addThumbnail(index, pmThumbnails) {
    var thumbListLI = document.createElement("li");
    var thumbBox = document.createElement("div");
    var thumbLink = document.createElement("a");
    var thumbImg = document.createElement("img");
    var thumbCaption = document.createElement("span");
    //thumbLink.setAttribute('onclick', 'javascript:changeSubCat('+index+')');
    thumbLink.setAttribute('href', '#');
	$(thumbLink).click(function () { changeSubCat(index); });
    thumbBox.setAttribute('class', "thumbBox");
    thumbCaption.setAttribute('class', "thumbCaption");
    thumbCaption.textContent = ImgCategories[CurrentCat].subCategories[index].label;
    thumbImg.setAttribute('alt', ImgCategories[CurrentCat].subCategories[index].name);
    thumbImg.setAttribute('src', ImgCategories[CurrentCat].subCategories[index].thumbnail);
    thumbImg.setAttribute('class', 'unselected');
    thumbLink.appendChild(thumbImg);
    thumbLink.appendChild(thumbCaption);
    thumbBox.appendChild(thumbLink);
    thumbListLI.appendChild(thumbBox);
    pmThumbnails.appendChild(thumbListLI);
}

function changeCat(inForm) {
    // setup category
    var oldThumbsLength = ImgCategories[CurrentCat].subCategories.length;
    var sIndex = inForm.categorySelector.selectedIndex;
    var catName = inForm.categorySelector.options[sIndex].value;
    CurrentCat = CatNameToIdx[catName];
    ThumbsLength = ImgCategories[CurrentCat].subCategories.length;

    // setup thumbnails
    var pmThumbnails = document.getElementById("pmThumbnails");
    var thumbnails = pmThumbnails.getElementsByTagName('img');
    var thumbnailCaptions = pmThumbnails.getElementsByTagName('span');
    for (var i=0; i<ThumbsLength; i++) {
        if (i < oldThumbsLength) {
            thumbnails[i].src = ImgCategories[CurrentCat].subCategories[i].thumbnail;
			thumbnailCaptions[i].textContent = ImgCategories[CurrentCat].subCategories[i].label;
        }
        else {;
            addThumbnail(i, pmThumbnails);
        }
    }
    var thumbListLIs = pmThumbnails.getElementsByTagName('li');
    for (var j=i; j<oldThumbsLength; j++) {
        pmThumbnails.removeChild(thumbListLIs[i]);
    }
    changeSubCat(0);

    // for debugging purposes...
    //alert(document.getElementById("photoMenu").innerHTML);
}

function populatePhotoMenu(inForm) {
    for (var i=0; i<ImgCategories.length; i++) {
        var newOpt = document.createElement("option");
        if (Safari) {
            // safari likes innerHTML better, strange
            newOpt.innerHTML = ImgCategories[i].label; 
        }
        else {
			newOpt.text= ImgCategories[i].label;
        }
        newOpt.value = ImgCategories[i].name;
        //var cs = document.getElementById("categorySelector");
        var opts = inForm["categorySelector"].options;
        //inForm["categorySelector"].options.add(newOpt, i);
        inForm["categorySelector"].options[opts.length] = newOpt;
    }
    var pmThumbnails = document.getElementById("pmThumbnails");
    for (var j=0; j<ImgCategories[CurrentCat].subCategories.length; j++) {
        addThumbnail(j, pmThumbnails);
    } 
    changeSubCat(0);
}

