function flipLeft() {
	if (currentViewportPage == 1) {
		return;
	}
	
	currentViewportPage--;
	slider.animate({
		marginLeft: '+=' + viewportWidth
	});
	
	// Show/hide next/previous pages
	
	currentPageFrom = ((currentViewportPage - 1) * pagesOnScreen) + 1;
	currentPageTo = currentPageFrom - 1 + pagesOnScreen;
	
	var hidePageFrom = currentPageFrom + (pagesOnScreen * 2);
	var hidePageTo = currentPageTo + (pagesOnScreen * 2);
	hidePages(hidePageFrom, hidePageTo);
	
	var showPageFrom = currentPageFrom - pagesOnScreen;
	var showPageTo = currentPageTo - pagesOnScreen;
	showPages(showPageFrom, showPageTo);
	
	// Sync thumbnail slider to current page
	
	syncThumbnailSlider();
}

function flipRight() {
	if (currentViewportPage > (viewportPages - 1)) {
		return;
	}
	
	currentViewportPage++;
	slider.animate({
		marginLeft: '-=' + viewportWidth
	});
	
	// Show/hide next/previous pages
	
	currentPageFrom = ((currentViewportPage - 1) * pagesOnScreen) + 1;
	currentPageTo = currentPageFrom - 1 + pagesOnScreen;
	
	var hidePageFrom = currentPageFrom - (pagesOnScreen * 2);
	var hidePageTo = currentPageTo - (pagesOnScreen * 2);
	hidePages(hidePageFrom, hidePageTo);
	
	var showPageFrom = currentPageFrom + pagesOnScreen;
	var showPageTo = currentPageTo + pagesOnScreen;
	showPages(showPageFrom, showPageTo);
	
	// Sync thumbnail slider to current page if necessary
	
	syncThumbnailSlider();
}

function flipTo(page) {
	currentPageFrom = page;
	
	// Determine which viewport page the desired page is on
	
	var viewportPage = Math.ceil(page / pagesOnScreen);
	
	// Sanitize desired viewport page
	
	if (viewportPage < 1) {
		viewportPage = 1;
	} else if (viewportPage > viewportPages) {
		viewportPage = viewportPages;
	}
	
	// Hide all currently shown pages
	
	for (var i in pageIsShown) {
		if (pageIsShown[i]) {
			loadImage(i, placeholderPath);
			pageIsShown[i] = false;
		}
	}
	
	// Show desired pages + the viewport before and after it
	
	var pageFrom = ((viewportPage * pagesOnScreen) - 1) - pagesOnScreen;
	var pageTo = viewportPage * 2 * pagesOnScreen;
	
	showPages(pageFrom, pageTo);
	
	// Slide to the desired viewport
	
	currentViewportPage = viewportPage;
	var margin = viewportWidth - (currentViewportPage * viewportWidth);
	slider.animate({
		marginLeft: margin
	});
	
	// Close the fancybox if open
	
	jQuery.fancybox.close();
	
	// Sync thumbnail slider to current page if necessary
	
	syncThumbnailSlider();
}

function flipThumbnailsLeft() {
	if (currentThumbnailPage == 1) {
		return;
	}
	
	currentThumbnailPage--;
	thumbnailSlider.animate({
		marginLeft: '+=' + thumbnailPageWidth
	});
	
	// Adjust page counters
	
	thumbnailSinglePageFrom -= thumbnailsOnScreen;
	thumbnailSinglePageTo -= thumbnailsOnScreen;
}

function flipThumbnailsRight() {
	if (currentThumbnailPage > (thumbnailPages - 1)) {
		return;
	}
	
	currentThumbnailPage++;
	thumbnailSlider.animate({
		marginLeft: '-=' + thumbnailPageWidth
	});
	
	// Adjust page counters
	
	thumbnailSinglePageFrom += thumbnailsOnScreen;
	thumbnailSinglePageTo += thumbnailsOnScreen;
}

function resetThumbnailSlider() {
	thumbnailSlider.css('marginLeft', 0);
}

function syncThumbnailSlider() {
	if (currentPageFrom < thumbnailSinglePageFrom || currentPageFrom > thumbnailSinglePageTo) {
		// Determine needed thumbnail page
		
		var pageFrom = null, pageTo = null;
		for (var thumbnailPage = 1; thumbnailPage <= thumbnailPages; thumbnailPage++) {
			pageFrom = (thumbnailPage * thumbnailsOnScreen) - thumbnailsOnScreen + 1;
			pageTo = pageFrom + thumbnailsOnScreen - 1;
			
			if (currentPageFrom >= pageFrom && currentPageFrom <= pageTo) {
				// Slide to the desired viewport
				
				currentThumbnailPage = thumbnailPage;
				var margin = thumbnailPageWidth - (currentThumbnailPage * thumbnailPageWidth);
				thumbnailSlider.animate({
					marginLeft: margin
				});
				
				// Adjust page counters
				
				thumbnailSinglePageFrom = pageFrom;
				thumbnailSinglePageTo = pageTo;
				
				break;
			}
		}
	}
	
	return;
}

function loadImage(page, imagePath) {
	jQuery("#page" + page).attr("src", imagePath);
}

function togglePage(page) {
	if (page < 1 || page > pagesTotal) {
		return;
	}
	
	if (pageIsShown[page]) {
		loadImage(page, placeholderPath);
	} else {
		loadImage(page, pagePaths[page]);
	}
	
	pageIsShown[page] = !pageIsShown[page];
}

function togglePages(pageFrom, pageTo) {
	for (var page = pageFrom; page <= pageTo; page++) {
		togglePage(page);
	}
}

function showPages(pageFrom, pageTo) {
	for (page = pageFrom; page <= pageTo; page++) {
		if (!pageIsShown[page]) {
			showPage(page);
		}
	}
}

function showPage(page) {
	if (page < 1 || page > pagesTotal) {
		return;
	}
	
	loadImage(page, pagePaths[page]);
	pageIsShown[page] = true;
}

function hidePages(pageFrom, pageTo) {
	for (page = pageFrom; page <= pageTo; page++) {
		if (pageIsShown[page]) {
			hidePage(page);
		}
	}
}

function hidePage(page) {
	if (page < 1 || page > pagesTotal) {
		return;
	}
	
	loadImage(page, placeholderPath);
	pageIsShown[page] = false;
}

function showMessage(message) {
	var div = jQuery("<div />").attr("title", "Hinweis").html(message.split("\n").join("<br />")).dialog({
		modal: true,
		width: 400,
		buttons: {
			Ok: function() {
				$(this).dialog("close");
			}
		}
	});
}

function rescale(percent) {
	var mapArea = null, mapAreaId = null, coordinates = null, i = null;
	var page = null, pageId = null, pageSize = null, width = null, height = null;
	
	// Scale imagemap areas' coordinates
	
	jQuery(".mapArea").each(function(index) {
		mapArea = jQuery(this);
		mapAreaId = mapArea.attr("id");
		
		// Determine whether to work with the previously saved original coordinates or the current ones
		
		if (typeof mapAreaCoordinatesOriginal[mapAreaId] == 'undefined') {
			// Coordinates for this mapArea not yet saved
			// Fetch current ones and save them
			
			coordinates = mapArea.attr("coords");
			
			mapAreaCoordinatesOriginal[mapAreaId] = coordinates;
		} else {
			// Fetch saved coordinates
			
			coordinates = mapAreaCoordinatesOriginal[mapAreaId];
		}
		
		// Scale coordinates
		
		coordinates = coordinates.split(",");
		for (i = 0; i < coordinates.length; i++) {
			coordinates[i] = coordinates[i] / 100 * percent;
		}
		mapArea.attr("coords", coordinates.join(","));
	});
	
	// Scale pages
	
	jQuery(".page").each(function(index) {
		page = jQuery(this);
		pageId = page.attr("id");
		
		// Determine whether to work with the previously saved original page size or the current one
		
		if (typeof pageSizes[pageId] == 'undefined') {
			// Page size is not yet saved
			// Fetch current and save it
			
			width = page.width();
			height = page.height();
			
			pageSizes[pageId] = {"width": width, "height": height};
		} else {
			// Fetch saved page size
			
			pageSize = pageSizes[pageId];
			width = pageSize.width;
			height = pageSize.height;
		}
		
		// Scale the page
		
		width = Math.floor(width / 100 * percent);
		height = Math.floor(height / 100 * percent);
		
		page.width(width);
		page.height(height);
	});
	
	// Scale pagewidth/pageheight variables
	
	pageWidth = Math.floor(pageWidthOriginal / 100 * percent);
	pageHeight = Math.floor(pageHeightOriginal / 100 * percent);
	
	viewportWidth = pageWidth * pagesOnScreen;
	
	// Scale containers
	
	jQuery("#pageContainerEverything").css("width", viewportWidth + (pageNavButtonWidth * 2) + 2);
	
	jQuery("#pageContainerOuter").css({
		"width" : viewportWidth,
		"height" : pageHeight
	});
	
	jQuery("#navLeftContainer").css("paddingTop", (pageHeight / 2) - Math.floor(pageNavButtonHeight / 2));
	jQuery("#navRightContainer").css("paddingTop", (pageHeight / 2) - Math.floor(pageNavButtonHeight / 2));
	
	// Adjust page container margin
	
	slider.css("marginLeft", viewportWidth - (currentViewportPage * viewportWidth));

}

function rescaleDocument() {
	windowWidth = jQuery(window).width();
	windowHeight = jQuery(window).height() - 30;
	
	var containerWidthNew = null, containerHeightBefore = null, percentInitial = 100;
	
	containerHeightBefore = (pageHeightOriginal / 100 * percentInitial) + 2 + (2 * 20) + thumbnailHeight + 2 + 20;
	
	if ((containerWidthPadded > (windowWidth - documentPaddingMargin)) || (containerHeightBefore > windowHeight)) {
		// Compute new width
		
		percent = parseInt((100 * (windowWidth - documentPaddingMargin)) / containerWidthPadded);
		containerWidthNew = ((containerWidthPadded / 100) * percent) - 88;
		percent = parseInt((100 * containerWidthNew) / containerWidth);
		
		// Make sure there's enough vertical space for the new container height
		// Adjusted page height + border + margin to thumbnails + thumbnailheight + border + margin to window border
		
		containerHeightBefore = (pageHeightOriginal / 100 * percent) + 2 + (2 * 20) + thumbnailHeight + 2 + 20;
		
		if (containerHeightBefore > windowHeight) {
			percentHeight = parseInt((100 * windowHeight) / containerHeightBefore);
			
			containerWidthNew = (containerWidthNew / 100 * percentHeight);
			percent = parseInt((100 * containerWidthNew) / containerWidth);
			
			containerHeightAfter = (pageHeightOriginal / 100 * percent) + 2 + (2 * 20) + thumbnailHeight + 2 + 20;
		}
		
		rescale(percent);
	}
}

function zoomIn() {
	// Set and sanitize zoom factor
	
	percent += 10;
	if (percent > 100) {
		percent = 100;
	}
	
	rescale(percent);
}

function zoomOut() {
	percent -= 10;
	if (percent < 10) {
		percent = 10;
	}
	
	rescale(percent);
}
