/*
 * Gallery - a web based photo album viewer and editor
 * Copyright (C) 2000-2007 Bharat Mediratta
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or (at
 * your option) any later version.
 *
 * This program is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA  02110-1301, USA.
 */

/* Global Variables */

var thumbnails;			/* array of thumbnails */
var currentImageIndex;		/* index into thumbnails array */
var nextImageIndex;    /* index into next thumbnail array */
var prevImageIndex;    /* index into previous thumbnail array */
var mainPhoto;			/* The central image */
var photoScalingInterval;	/* scaling animation tracker */
var showLoadingTimeout;		/* Cancel the loading message display */
var showImageDataFadeTimeout	/* Fade in image data block */

var MAIN_PHOTO_WIDTH = 480;	/* Width each image is resized to when first loaded */
var PHOTO_MINIMISED = 300;	/* Width each image is resized down to when clicked */
var SCALE_DOWN_FACTOR = 12;	/* Pixels that an image scales down by at each step */
var SCALE_UP_FACTOR = 18;	/* Pixels that an image scales *up* by at each step */

/* @REVISIT: For preloading... */
fullsizePhotos = new Array();
fullsizeCount = 0;

/* Initialisation */
addEvent(window, 'load', init, false);

function init() {
	
	if (!document.getElementById) {
		/* Required functionality for even the most basic DHTML. */
		return;
	}
	/* Set up thumbnails */
	var thumbholder = document.getElementById('thumb-images-table');
	if (!thumbholder) {
		setupBackToAlbumLink(); /* Not an album page */
		return;
	}
	thumbnails = thumbholder.getElementsByTagName('img');

	for (var i = 0; i < thumbnails.length; i++) {
		thumbnails[i].thumbIndex = i;
		addEvent(thumbnails[i], 'click', activateThumbnail, false);
		thumbnails[i].onclick = cancelEventSafari;
	}

	/*
	 * If the user has just come from a photo page, they may have a cookie set that holds the index
	 * of the image that was active in the show when they left. Now they can rejoin at that point.
	 */
	if (readCookie('slideshowOffset') != null &&
		Number(readCookie('slideshowOffset')) < thumbnails.length) {
		currentImageIndex = Number(readCookie('slideshowOffset'));
		prevImageIndex = currentImageIndex-1;
		nextImageIndex = currentImageIndex+1;
		eraseCookie('slideshowOffset');
		addMessage('Restarting slideshow at index ' + currentImageIndex);
	} else {
		currentImageIndex = 0;
	}

	if (slideshowImages.length > 0) {
		setupMainImage();
		switchImages(currentImageIndex, true);
	}

	setupSubAlbums();
}

/* Called each time a new image is switched to */
function setupMainImage() {
	mainPhoto = document.getElementById('main-image');

	if (slideshowImageWidths[currentImageIndex] < 0
		|| MAIN_PHOTO_WIDTH <= slideshowImageWidths[currentImageIndex]) {
		mainPhoto.style.width = MAIN_PHOTO_WIDTH + 'px';
	} else {
		/*
		* The image is below our ideal slideshow width, so we don't want to stretch it
		* horizontally.  Instead we center the image using the stylesheet.
		*/
		mainPhoto.style.width = slideshowImageWidths[currentImageIndex] + 'px';
	}

	mainPhoto.style.height = 'auto'; /* @REVISIT - Safari doesn't play nice with this */

	mainPhoto.origWidth = parseInt(getElementStyle(mainPhoto.id, 'width'));
	mainPhoto.origLeft = parseInt(getElementStyle(mainPhoto.id, 'left'));
	mainPhoto.galleryimg = 'no'; /* Disables IE's image toolbar, which was causing flicker */

	// addEvent(mainPhoto, 'click', showPhotoDetails, false);
}


function activateThumbnail(e) {
    /* Find the source element through varying levels of browser support */
    var targetElement = window.event ? window.event.srcElement : e ? e.target : null;
    if (!targetElement) {
		return;
    }
    knackerEvent(e);
    switchImages(targetElement.thumbIndex);
    targetElement.blur();	/* Remove focus halo */
}

function switchImages(thumbIndex, firstLoad) {
   
	if (currentImageIndex == thumbIndex && !firstLoad) {
		addMessage("That image is already selected.");
		return;
	}
    
	removeImageDataBlock();
	
	/* Wrap around */
	if (thumbIndex < 0) {
		thumbIndex = thumbnails.length - 1;
	} else if (thumbIndex == thumbnails.length) {
		thumbIndex = 0;
	}
	
	if (slideshowImageWidths[thumbIndex] < 0) {
		/* This item is not a photo.. redirect to view it */
		if (!firstLoad) {
			location = slideshowImages[thumbIndex];
		} else {
			hideLoadingMessage();
		}
		return;
	}
	
	highlightCurrentThumb(thumbIndex);
	// Reactivate for item title 
    // updateItemTitle(thumbIndex);

    hideLoadingMessage();

    var newImageSrc = slideshowImages[thumbIndex];
    var newImage = document.createElement('img');

    mainPhoto.id = null; /* Isn't enough in some browsers */
    mainPhoto.removeAttribute('id');

    newImage.id = 'main-image';
    addEvent(newImage, 'load', bigPhotoLoad, false);
    addEvent(newImage, 'error', bigPhotoFail, false);

    if (slideshowState == PLAYING) {
		pause();
		returnToPlaying = true;
    }

    /* Avoid showing loading message if its going to be fast */
    showLoadingTimeout = setTimeout("showLoadingMessage()", 600);

    addMessage("Swapping " + currentImageIndex + ", and " + thumbIndex + "...");
    currentImageIndex = thumbIndex;
	nextImageIndex = thumbIndex+1; 
	prevImageIndex = thumbIndex-1;

    newImage.src = newImageSrc;
    mainPhoto.parentNode.removeChild(mainPhoto);
    document.getElementById('main-image-td').getElementsByTagName('p')[0].appendChild(newImage);
	
    setupMainImage();

	setupSatelliteImages();
	
    // if (mainPhoto.state == 'downsized') {
	// insertimagedatablock();
	insertfullsizelink();
    // }
}

/* Called each time a new image is switched to */
function setupSatelliteImages() {
	
	if (nextImageIndex < thumbnails.length) {
		addMessage("Setting up next image");
		
		var newNextImageSrc = thumbnails[nextImageIndex].src;
		var newNextImage = document.createElement('img');
		newNextImage.src = newNextImageSrc;

		addMessage("Updated next image with " + newNextImageSrc);
		newNextImage.thumbIndex = nextImageIndex;
		addEvent(newNextImage, 'click', activateThumbnail, false);
		newNextImage.onclick = cancelEventSafari;
		newNextImage.galleryimg = 'no';	
		newNextImage.id = "next-image";
		
		nextPhoto = document.getElementById('next-image');
		nextPhoto.parentNode.removeChild(nextPhoto);	
		document.getElementById('next-image-td').getElementsByTagName('p')[0].appendChild(newNextImage);
		addMessage("Next Image Updated");
	} else {
	
		var emptyNextImage = document.createElement('img');
		emptyNextImage.id = "next-image";
		emptyNextImage.src = "themes/lkcustom/images/blank.png";
		emptyNextImage.galleryimg = 'no';	
		emptyNextImage.style.border = 0;

		nextPhoto = document.getElementById('next-image');
		if (nextPhoto) {
			nextPhoto.parentNode.removeChild(nextPhoto);
			document.getElementById('next-image-td').getElementsByTagName('p')[0].appendChild(emptyNextImage);
			addMessage("Removed Next Image since there is not a next image");
		}
	}
	
	if (prevImageIndex >= 0) {
		addMessage("Setting up prev image");
		
		var newPrevImageSrc = thumbnails[prevImageIndex].src;
		var newPrevImage = document.createElement('img');
		newPrevImage.src = newPrevImageSrc;
		newPrevImage.id = "prev-image";
		
		addMessage("Updated previous image with " + newPrevImageSrc);
		newPrevImage.thumbIndex = prevImageIndex;
		addEvent(newPrevImage, 'click', activateThumbnail, false);
		newPrevImage.onclick = cancelEventSafari;
		newPrevImage.galleryimg = 'no';	
		
		prevPhoto = document.getElementById('prev-image');
		prevPhoto.parentNode.removeChild(prevPhoto);	
		document.getElementById('prev-image-td').getElementsByTagName('p')[0].appendChild(newPrevImage);		
		addMessage("Previous Image Updated");

	} else {
	
		var emptyPrevImage = document.createElement('img');
		emptyPrevImage.id = "prev-image";
		emptyPrevImage.src = "themes/lkcustom/images/blank.png";
		emptyPrevImage.galleryimg = 'no';
		emptyPrevImage.style.border = 0;
		
		prevPhoto = document.getElementById('prev-image');
		if (prevPhoto) {
			prevPhoto.parentNode.removeChild(prevPhoto);
			document.getElementById('prev-image-td').getElementsByTagName('p')[0].appendChild(emptyPrevImage);
			addMessage("Removed Previous Image since there is not a prev image");
		}
	}

}

function bigPhotoLoad() {
    mainPhoto.style.height = 'auto';
    addMessage('Photo loaded');
    hideLoadingMessage();

    /*
     * The little switcheroo below prevents a problem with IE incorrectly calculating the 'height'
     * property for an image that has had its width changed when set to 'auto' (they should scale
     * together). Should be imperceptible in other browsers.
     */
    mainPhoto.style.height = '345px';
    mainPhoto.style.height = 'auto';
    if (returnToPlaying) {
	play();
    }
}

function bigPhotoFail() {
    addMessage('FAIL: Photo failed to load...');
    addMessage(mainPhoto.src);
    hideLoadingMessage();
    if (slideshowState == PLAYING) {
	advanceSlideShow();
    }
}

function showLoadingMessage() {
    var loadingMsg = document.createElement('div');
    loadingMsg.id = 'loading';
    loadingMsg.appendChild(document.createTextNode(LOADING_IMAGE));
    document.getElementById('album-main-container').appendChild(loadingMsg);
}

function hideLoadingMessage() {
    clearTimeout(showLoadingTimeout);
    var loading = document.getElementById('loading');
    if (loading && getElementStyle(loading.id, '-moz-opacity') > 0.0) {
	loading.style.MozOpacity = parseFloat(getElementStyle(loading.id, '-moz-opacity')) - 0.05;
	showLoadingTimeout = setTimeout("hideLoadingMessage()", 50);
    } else if (loading) {
	loading.parentNode.removeChild(loading);
    }
}

function highlightCurrentThumb(thumbIndex) {
    /* First, un-highlight the current image... */
    thumbnails[currentImageIndex].className =
	thumbnails[currentImageIndex].className.replace(/\bcurrentImage\b/, '');
    thumbnails[thumbIndex].className += ' currentImage';
}

function updateItemTitle(thumbIndex) {
    var itemTitle = document.getElementById('item-title').firstChild;
    itemTitle.data = thumbnails[thumbIndex].getAttribute('alt');
}

/*
 * Photo -scaling functions
 */
function showPhotoDetails(e) {
    addMessage('scaling image, dimensions: ' + mainPhoto.origWidth + 'x' + mainPhoto.origHeight);
    clearInterval(photoScalingInterval);
    if (slideshowState == PLAYING) {
	pause();
	returnToPlaying = true;
    }

    if (mainPhoto.state != 'downsized') {
	photoScalingInterval = setInterval("downSizePhoto()", 30);
	mainPhoto.state = 'downsized';
    } else {
	removeImageDataBlock();
	photoScalingInterval = setInterval("upSizePhoto()", 20);
	mainPhoto.state = 'upsized';
    }
}

function downSizePhoto() {
    if (parseInt(mainPhoto.style.width) > PHOTO_MINIMISED ||
	    parseInt(getElementStyle(mainPhoto.id, 'left')) > 40) {
	if (parseInt(mainPhoto.style.width) > PHOTO_MINIMISED) {
	    mainPhoto.style.width = parseInt(mainPhoto.style.width) - SCALE_DOWN_FACTOR + 'px';
	}

	/* REVISIT Works in everything but Safari... */
	mainPhoto.style.height = 'auto';

	if (parseInt(getElementStyle(mainPhoto.id, 'left')) > 40) {
	    mainPhoto.style.left = (parseInt(getElementStyle(mainPhoto.id, 'left')) -
		mainPhoto.origLeft/12) + 'px';
	}
	if (getElementStyle(mainPhoto.id, 'top') == 'auto') {
	    mainPhoto.style.top = '0';
	}
	if (parseInt(getElementStyle(mainPhoto.id, 'top')) < 40) {
	    mainPhoto.style.top = (parseInt(getElementStyle(mainPhoto.id, 'top')) + 5) + 'px';
	}
    } else {
	clearInterval(photoScalingInterval);
	addMessage('Image scaled to ' + mainPhoto.style.width + 'x' + mainPhoto.style.height);
	mainPhoto.state = 'downsized';
	// insertimagedatablock();
	insetrfullsizelink();
    }
}

function upSizePhoto() {
    if (parseInt(mainPhoto.style.width) < mainPhoto.origWidth ||
	    parseInt(getElementStyle(mainPhoto.id, 'left')) < mainPhoto.origLeft) {
	if (parseInt(mainPhoto.style.width) < mainPhoto.origWidth-5) {
	    mainPhoto.style.width = (parseInt(mainPhoto.style.width) + SCALE_UP_FACTOR) + 'px';
	}
	if (parseInt(getElementStyle(mainPhoto.id, 'left')) < mainPhoto.origLeft) {
	    mainPhoto.style.left = (parseInt(getElementStyle(mainPhoto.id, 'left')) +
		mainPhoto.origLeft/10) + 'px';
	}
	if (parseInt(getElementStyle(mainPhoto.id, 'top')) > 0) {
	    mainPhoto.style.top = (parseInt(getElementStyle(mainPhoto.id, 'top')) - 5) + 'px';
	}
    } else {
	/* Clean up and reset */
	clearInterval(photoScalingInterval);
	mainPhoto.style.width = mainPhoto.origWidth + 'px';
	mainPhoto.style.height = 'auto';
	mainPhoto.style.left = mainPhoto.origLeft + 'px';
	mainPhoto.style.top = 'auto';
	addMessage('Image scaled back to ' + mainPhoto.width + 'x' + mainPhoto.height);
	mainPhoto.state = 'upsized';
	if (returnToPlaying) {
	    play();
	}
    }
}

function insertimagedatablock() {
    var dataBlock = document.createElement('div');
    dataBlock.id = 'imagedatablock';

    var dataBlockHeading = document.createElement('h3');
    dataBlockHeading.appendChild(document.createTextNode(PHOTO_DATA));
    dataBlock.appendChild(dataBlockHeading);

    if (thumbnails[currentImageIndex].className.match(/size:=([0-9]+)=/)) {
	var imageSize = Number(RegExp.$1) / 1024;
	var sizeInfo = document.createElement('p');
	sizeInfo.appendChild(
	    document.createTextNode(FILE_SIZE.replace(/%SIZE%/, Math.round(imageSize))));
	// dataBlock.appendChild(sizeInfo);
    }
    if (thumbnails[currentImageIndex].className.match(/summary:=([^=]+)=/)) {
	var summaryInfo = document.createElement('p');
	summaryInfo.appendChild(document.createTextNode(SUMMARY + RegExp.$1));
	dataBlock.appendChild(summaryInfo);
    }
    if (thumbnails[currentImageIndex].className.match(/description:=(.+)=/)) {
	var descriptionInfo = document.createElement('p');
	descriptionInfo.appendChild(document.createTextNode(DESCRIPTION + RegExp.$1));
	dataBlock.appendChild(descriptionInfo);
    }

    var fullsizeLink = document.createElement('a');
    fullsizeLink.id = 'fullsizelink';
    fullsizeLink.href = thumbnails[currentImageIndex].parentNode.href
	+ (thumbnails[currentImageIndex].parentNode.href.indexOf('?') >= 0 ? '&' : '?')
	+ 'thumbIndex=' + currentImageIndex;
    /* Allow a user to rejoin the slideshow at this point */
    addEvent(fullsizeLink, 'click', saveCurrentImageIndex, false);

    fullsizeLink.appendChild(document.createTextNode(VIEW_IMAGE));
    var linkPara = document.createElement('p');
    linkPara.appendChild(fullsizeLink);
    dataBlock.appendChild(linkPara);

    /* In Gecko-based browsers, this'll fade the data block in smoothly. */
    dataBlock.style.MozOpacity = 0.2;
    showImageDataFadeTimeout = setTimeout('fadeInImageDataBlock()', 50);

    document.getElementById('album-main-container').appendChild(dataBlock);
}

function insertfullsizelink() {
    var dataBlock = document.createElement('div');
    dataBlock.id = 'fullsizelink-container';

	var mainPhotoAnchor = document.getElementById('main-image-href');
	
    var fullsizeLink = document.createElement('a');
    fullsizeLink.id = 'fullsizelink';
	var fullLink = thumbnails[currentImageIndex].parentNode.href
	+ (thumbnails[currentImageIndex].parentNode.href.indexOf('?') >= 0 ? '&' : '?')
	+ 'thumbIndex=' + currentImageIndex;

    fullsizeLink.href = fullLink;	
	mainPhotoAnchor.href = fullLink;
	
    /* Allow a user to rejoin the slideshow at this point */
    addEvent(fullsizeLink, 'click', saveCurrentImageIndex, false);
	addEvent(mainPhoto, 'click', saveCurrentImageIndex, false);
	
    fullsizeLink.appendChild(document.createTextNode(VIEW_IMAGE));
    var linkPara = document.createElement('p');
    linkPara.appendChild(fullsizeLink);
    dataBlock.appendChild(linkPara);

    /* In Gecko-based browsers, this'll fade the data block in smoothly. */
    dataBlock.style.MozOpacity = 0.2;
    showImageDataFadeTimeout = setTimeout('fadeInImageDataBlock()', 50);

    // document.getElementById('main-image-container').appendChild(dataBlock);
}

function fadeInImageDataBlock() {
    clearTimeout(showImageDataFadeTimeout);
    var dataBlock = document.getElementById('fullsizelink-container');
    /* Don't bring -moz-opacity all the way to 1.0, as it causes flicker in Firefox 1.0 */
    if (dataBlock && getElementStyle(dataBlock.id, '-moz-opacity') < 0.92) {
	dataBlock.style.MozOpacity = parseFloat(getElementStyle(dataBlock.id, '-moz-opacity')) + 0.08;
	showImageDataFadeTimeout = setTimeout('fadeInImageDataBlock()', 50);
    }
}

function removeImageDataBlock() {
    var dataBlock = document.getElementById('fullsizelink-container');
    if (dataBlock) {
	dataBlock.parentNode.removeChild(dataBlock);
    }
}

/* Subalbums table */

function setupSubAlbums() {
    /* First check if there is a sub-album table */
    if (!document.getElementById('gsSubAlbumMatrix')) {
	return;
    }
    var subs = document.getElementById('gsSubAlbumMatrix').getElementsByTagName('td');
    for (var i = 0; i < subs.length; i++) {
	addEvent(subs[i], 'click', selectSubAlbum, false);
	var hasLink = subs[i].getElementsByTagName('a')[0];
	if (hasLink) {
	    addEvent(subs[i], 'mouseover', highlightSubAlbum, true);
	    addEvent(subs[i], 'mouseout', unHighlightSubAlbum, true);
	}
    }
}

function highlightSubAlbum(e) {
    /* Find the source element through varying levels of browser support */
    var targetElement = window.event ? window.event.srcElement : e ? e.target : null;
    if (!targetElement) {
	return;
    }
    while (targetElement.nodeName.toLowerCase() != 'td' &&
	   targetElement.nodeName.toLowerCase() != 'body') {
	targetElement = targetElement.parentNode;
    }
    if (targetElement.nodeName.toLowerCase() == 'body') {
	return;
    }
    targetElement.className += ' sahover';
}

function unHighlightSubAlbum(e) {
    /* Find the source element through varying levels of browser support */
    var targetElement = window.event ? window.event.srcElement : e ? e.target : null;
    if (!targetElement) {
	return;
    }
    while (targetElement.nodeName.toLowerCase() != 'td' &&
	   targetElement.nodeName.toLowerCase() != 'body') {
	targetElement = targetElement.parentNode;
    }
    if (targetElement.nodeName.toLowerCase() == 'body') {
	return;
    }
    targetElement.className = targetElement.className.replace(/\bsahover\b/, '');
}

function selectSubAlbum(e) {
    /* Find the source element through varying levels of browser support */
    var targetElement = window.event ? window.event.srcElement : e ? e.target : null;
    if (!targetElement) {
	return;
    }
    knackerEvent(e);

    while (targetElement.nodeName.toLowerCase() != 'td' &&
	   targetElement.nodeName.toLowerCase() != 'body') {
	targetElement = targetElement.parentNode;
    }
    if (targetElement.nodeName.toLowerCase() == 'body') {
	return;
    }
    eraseCookie('slideshowOffset');
    var firstlink = targetElement.getElementsByTagName('a')[0];
    if (firstlink) {
	window.location = firstlink.href;
    }
}

/* Photo page functions */

function setupBackToAlbumLink() {
    var pageLinks = document.getElementsByTagName('a');
    for (var i = 0; i < pageLinks.length; i++) {
	if (pageLinks[i].className.match(/\bbacktoalbum\b/)) {
	    addEvent(pageLinks[i], 'click', saveCurrentImageIndex, false);
	}
    }
}

function saveCurrentImageIndex() {
    if (window.location.toString().match(/thumbIndex=([0-9]+)/)) {
	createCookie('slideshowOffset', RegExp.$1);
    } else if (currentImageIndex) {
	createCookie('slideshowOffset', currentImageIndex);
    }
}
