/*
 * based on HTML5 Rocks: Page Flip Effect by Hakim El Hattab (Fi)
 * http://www.html5rocks.com/tutorials/casestudies/20things_pageflip.html
 *
 * heavily modified by Yoocon
 *
 * License: Apache 2 (http://www.apache.org/licenses/LICENSE-2.0)
 */
var renderInterval;

var PAGEFLIP_BASE_URI = '/motorblog/';

function pageflip() {
	// Dimensions of the whole book
	var BOOK_WIDTH = 1620,
		BOOK_HEIGHT = 620,

		// Dimensions of one page in the book
		PAGE_WIDTH = 800,
		PAGE_HEIGHT = 519,

		// Vertical spacing between the top edge of the book and the papers
		PAGE_X = 808,
		PAGE_Y = 128,

		// The canvas size equals to the book dimensions + this padding
		CANVAS_PADDING = 60,

		SECOND_OUTDENT_WIDTH  = 120,
		SECOND_OUTDENT_HEIGHT = 15,
		BUCKLE_HEIGHT	  = 20,
		PAGE_HEIGHT_BUCKLE_HEIGHT = PAGE_HEIGHT + BUCKLE_HEIGHT,
		CLICK_BORDER_WIDTH	  = 100,

		gradientImage,
		page = 0,

		canvas = document.getElementById("pageflip-canvas"),
		context = null,

		book = $("#book"),
		left_side = document.getElementById("left-side"),
		left_shadow = document.getElementById("left-shadow"),

		mouse = { x: 0, y: 0, startX: 0, startY: 0, offsetX: 0 },
		flips = new Array(),

		// List of all the page elements in the DOM
		pages,

		use_tooltip = false;

	function resizeWindow() {
		var bs = $('#book section:first')[0];
		var x = getOffsetLeft(bs);
		//$('#book-navigation a.prev').css('left', ''+(PAGE_X-x+20)+'px');
		//$('#book-navigation a.next').css('left', ''+(PAGE_X*2+x-72)+'px');
	}

	function showNavigation () {
		var page_element = $('#book section')[page];
		var prev = $('a[rel=prev]', page_element)[0];
		var next = $('a[rel=next]', page_element)[0];

		if(!use_tooltip)
			$('#page-tooltip').remove();

		if(prev) {
			if (use_tooltip && $('#page-tooltip').hasClass('prev')){
				var TooltipText = getToolTipText($(prev).attr('href'));
				$('.text','#page-tooltip').text(TooltipText);
			}
			$('#book-navigation a.prev').attr('href', $(prev).attr('href')).show().stop().fadeTo(500, 1);
		} else {
			if (use_tooltip && $('#page-tooltip').hasClass('prev')){
				$('#page-tooltip').stop().fadeTo(500, 0);
			}
			$('#book-navigation a.prev').stop().fadeTo(500, 0, function (){
				$(this).hide();
			});
		}
		if(next){
			if (use_tooltip && $('#page-tooltip').hasClass('next')){
				var TooltipText = getToolTipText($(next).attr('href'));
				$('.text','#page-tooltip').text(TooltipText);
			}
			$('#book-navigation a.next').attr('href', $(next).attr('href')).show().stop().fadeTo(500, 1);
		} else {
			if (use_tooltip && $('#page-tooltip').hasClass('next')){
				$('#page-tooltip').stop().fadeTo(500, 0);
			}
			$('#book-navigation a.next').stop().fadeTo(500, 0, function (){
				$(this).hide();
			});
		}

		$('#book-navigation a').hover(
			function (){
				booklearned = true;
				if(use_tooltip) {
					var TooltipText = getToolTipText($(this).attr('href'));
					var x = $(this).position().left, y = $(this).position().top;
					if ($(this).hasClass('next')){
						$('#page-tooltip').css('left', ''+(x-10)+'px').css('top', ''+y+'px')
								  .removeClass('prev').addClass('next');
					}else{
						$('#page-tooltip').css('left', ''+(x-10)+'px').css('top', ''+y+'px')
								  .removeClass('next').addClass('prev');
					}
					$('#page-tooltip').children('.text').text(TooltipText).end().stop().animate({'margin-top': -65, 'opacity': 1}, 'fast', 'easeOutCirc');;
				}
			},
			function (){
				if(use_tooltip) {
					$('#page-tooltip').stop().animate({'margin-top': -85, 'opacity': 0}, 'fast', 'easeOutCirc');
				}
			}
		);
	}
	function getToolTipText(str){
		if(!str) return '';
		var matchedNum = str.split('\/').reverse()[0].replace(/[^-.0-9]/g,'');
		if (matchedNum != ''){
			return 'Seite ' + matchedNum;
		}else{
			return 'Cover';
		}
	}

	function disablePageFlip () {
		$(page).css("left", PAGE_X.toString() + 'px');
		$(page).css("top",  PAGE_Y.toString() + 'px');
		$('#page-tooltip').remove();
		unbindPageEvents();
		booklearned = true;
		showNavigation();

		FLIR.init({path: '/resources/flir/', 'hq': true});
		FLIR.auto(['h1']);
	}

	function setClipping (page, lx, ly, ux, uy) {
		if (lx < 5) {
			lx = 0;
		}
		if (ux < 5) {
			ux = 0;
		}
		page.style.left = PAGE_X.toString() + 'px';
		page.style.top = PAGE_Y.toString() + 'px';
		if (lx === 0 && ux === 0) {
			page.style.width = '0px';
			return;
		}
		if (lx === PAGE_WIDTH && ux === PAGE_WIDTH) {
			page.style.width = ~~(1 * (PAGE_WIDTH)).toString() + 'px';
			return;
		}
		page.style.width = ~~(1 * (ux - 1)) + "px";
	}

	function reinitialize () {
			var i,
				len,
				new_flip;
			pages =  $('section', book);


			FLIR.init({path: '/resources/flir/', 'hq': true});
			FLIR.auto(['h1']);
			// Organize the depth of our pages and create the flip definitions
			for (i = 0, len = pages.length; i < len; i += 1) {
				pages[i].style.zIndex = len - i;
				pages[i].style.display = 'block';
				if (!flips[i] || (flips[i].page !== pages[i])) {
					new_flip = {
						// Current progress of the flip (left -1 to right +1)
						//progress: i <= page ? -1 : 1,
						// The target value towards which progress is always moving
						//target: i <= page ? -1 : 1,
						// The page DOM element related to this flip
						page: pages[i],
						//url: $(pages[i]).find('a[rel=this]').attr('href'),
						// True while the page is being dragged
						dragging: false
					};
					if (!flips.length) {
						new_flip.progress = new_flip.target = 1;
						flips = [new_flip];
					} else if (i > page) {
						new_flip.progress = new_flip.target = 1;
						flips.push(new_flip);
					} else {
						page += 1;
						new_flip.progress = new_flip.target = -1;
						flips.unshift(new_flip);
					}
				}
				if (i < page) {
					setClipping(pages[i], 0, PAGE_HEIGHT, 0, 0);
				} else {
					setClipping(pages[i], PAGE_WIDTH, PAGE_HEIGHT, PAGE_WIDTH, 0);
				}
			}
			mouse.offsetX = 0;
			showNavigation();
		}
	function getOffsetLeft (e) {
		var result;
		for (result = 0; e; e = e.offsetParent) {
			result += e.offsetLeft;
		}
		return result;
	}
	function getOffsetTop (e) {
		var result;
		for (result = 0; e; e = e.offsetParent) {
			result += e.offsetTop;
		}
		return result;
	}
	function autoLoadAdjacentPages (newPage) {
		var NEW_SECTION = '<section style="display: none;"></section>',
			section = $(pages[newPage]),
			reinit_count = 0,
			ns = null,
			link;
		if (!section.next().length) {
			link = section.find('a[rel=next]');
			if (link.length) {
				reinit_count += 1;
				section.after(NEW_SECTION);
				ns = section.next();
				ns.load(link.attr('href') + ' #pages section:first > *', function () {
					if (--reinit_count === 0) {
						reinitialize();
					}
				});
			}
		}
		if (!section.prev().length) {
			link = section.find('a[rel=prev]');
			if (link.length) {
				reinit_count += 1;
				section.before(NEW_SECTION);
				ns = section.prev();
				ns.load(link.attr('href') + ' #pages section:first > *', function () {
					if (--reinit_count === 0) {
						reinitialize();
					}
				});
			}
		}
		document.title = section.find('h2').text();
	}
	function gotoPage (newPage, nohistory) {
		var i,
			BROWSE_DURATION = 200,
			next;

		if(newPage >= flips.length) return;

		for (i = 0; i < flips.length; i += 1) {
			if (flips[i].dragging || (i === page)) {
				flips[i].target = newPage > page ? -1 : 1;
				newPage = Math.min(Math.max(newPage, 0), flips.length);
			}
		}
		if (page < newPage) {
			for (i = page + 1; i < newPage; i += 1) {
				(function () {
					var j = i;
					window.setTimeout(
						function () {
							setClipping(flips[j].page, 0, PAGE_HEIGHT, 0, 0);
							flips[j].progress = 0.9;
							flips[j].target = -1;
						},
						(i - page) * BROWSE_DURATION * 1.5
					);
				})();
			}
		}
		if (page > newPage) {
			for (i = page; i >= newPage; i -= 1) {
				(function () {
					var j = i;
					window.setTimeout(
						function () {
							flips[j].progress = Math.max(flips[j].progress, -0.9);
							flips[j].target = 1;
						},
						(page - i - 1) * BROWSE_DURATION * 1.5
					);
				})();
			}
		}
		if (page === newPage) {
			if (page > 0) {
				flips[page-1].target = -1;
			}
		}
		if ((page !== newPage) && !nohistory && History.enabled) {
			next = $(pages[newPage]).find('a[rel=this]').attr('href');
			if (next) {
				History.pushState(null, null, next);
			}
		}
		page = newPage;
		window.setTimeout(function () {
			showNavigation();
			autoLoadAdjacentPages(page);
		}, 500);
	}

	var overNextButton = false;
	function navMouseOverHandler(event) {
		flips[page].target = (PAGE_WIDTH-CLICK_BORDER_WIDTH)/PAGE_WIDTH;
		overNextButton = true;
	}
	function navMouseOutHandler(event) {
		overNextButton = false;
	}
	function mouseMoveHandler(event) {
		if(overNextButton) return;
		// Offset mouse position so that the top of the book spine is 0,0
		mouse.x = event.clientX - getOffsetLeft(pages[0]);
		mouse.x += mouse.offsetX;
		mouse.y = event.clientY - getOffsetTop(pages[0]);
		if (flips[page] && !flips[page].dragging) {
			if ((mouse.x < PAGE_WIDTH) && (PAGE_WIDTH - mouse.x < CLICK_BORDER_WIDTH) && (page < flips.length - 1)) {
				if((mouse.y >= 0) && (mouse.y <= PAGE_HEIGHT)) {
					booklearned = true;
					book.css('cursor', 'pointer');
					flips[page].target = Math.min(mouse.x, PAGE_WIDTH - CLICK_BORDER_WIDTH) / PAGE_WIDTH;
				}
			} else if (mouse.x > 0) {
				flips[page].target = 1;
			}
			if (!(page < flips.length - 1) || !(PAGE_WIDTH - mouse.x < CLICK_BORDER_WIDTH)){
				if((page > 0) && (mouse.x < 0))
					book.css('cursor', 'pointer');
				else
					book.css('cursor', 'default');
			}
		}
	}
	function mouseDownHandler (event) {
		if (event.target.tagName.toLowerCase() === 'a') {
			return;		// allow mouse interaction with the underlying elements
		}

		// Make sure the mouse pointer is inside of the book
		if (Math.abs(mouse.x) < PAGE_WIDTH) {
			mouse.startX = mouse.x;
			mouse.startY = mouse.y;
			if (mouse.x < 0 && page - 1 >= 0) {
				// We are on the left side, drag the previous page
				flips[page - 1].dragging = true;
			} else if (mouse.x > 0 && page + 1 < flips.length) {
				// We are on the right side, drag the current page
				flips[page].dragging = true;
			}
		}

		// Prevents the text selection
		event.preventDefault();
	}
	function mouseUpHandler (event) {
		var mouseClicked = (Math.abs(mouse.x - mouse.startX) + Math.abs(mouse.y - mouse.startY) < 2),
			mouseOnRightBorder = (PAGE_WIDTH - mouse.x < CLICK_BORDER_WIDTH),
			i;
		for (i = 0; i < flips.length; i += 1) {
			// If this flip was being dragged, animate to its destination
			if (flips[i].dragging) {
				if (mouseClicked) {
					// Click
					if (mouseOnRightBorder && (mouse.x > 0)) {
						gotoPage(Math.min(page + 1, flips.length));
					} else if (mouse.x < 0) {
						gotoPage(Math.max(page - 1, 0));
					} else {
						gotoPage(page);
					}
				} else {
					// Mouse Up after Move
					if ((mouse.startX > 0) && (mouse.x < PAGE_WIDTH*3/4)) {
						gotoPage(Math.min(page + 1, flips.length));
					} else if ((mouse.startX < 0) && (mouse.x > 0)) {
						gotoPage(Math.max(page - 1, 0));
					} else {
						gotoPage(page);
					}
				}
			}
			flips[i].dragging = false;
		}
	}
	function hide_left_page () {
		if (flips.length !== pages.length) {
			reinitialize();
		}
		if ((flips[0].progress < -0.997) || ($(pages[0]).find('a[rel=prev]').length)) {
			$(left_shadow).fadeIn(300);
			$(left_side).show();
			return false;
		} else {
			$(left_shadow).fadeOut(300);
			$(left_side).hide();
			return true;
		}
	}
	function drawFlip (flip) {
		// Strength of the fold is strongest in the middle of the book
		var flip_progress = flip.progress,
			Math_abs = Math.abs,
			Math_max = Math.max,
			Math_min = Math.min,
			strength = 1 - Math_abs(flip_progress),
			// Width of the folded paper
			foldWidth = (PAGE_WIDTH>>1) * (1 - flip_progress),
			//pw_p_fp
			pw_p_fp = PAGE_WIDTH * flip_progress,
			// X position of the folded paper
			foldX = pw_p_fp + foldWidth,
			// How far the page should outdent vertically due to perspective
			verticalOutdent = 20 * strength,
			ratio = SECOND_OUTDENT_WIDTH/foldWidth,
			SWITCH_RATIO = -0.25,
			SWITCH_RATIO_CALC = (-1-SWITCH_RATIO),
			a1, a2, b1, b2, c1, c2, d1, d2, e1, e2,
			z1 = (SECOND_OUTDENT_WIDTH>>1) * flip_progress,
			z2 = flip_progress / SWITCH_RATIO_CALC,
			z3 = PAGE_HEIGHT + verticalOutdent,
			// The maximum width of the left and right side shadows
			paperShadowWidth = (PAGE_WIDTH>>1) * Math_max(Math_min(1 - flip_progress, 0.5), 0),
			rightShadowWidth = (PAGE_WIDTH>>1) * Math_max(Math_min(strength, 0.5), 0),
			leftShadowWidth = (PAGE_WIDTH>>1) * Math_max(Math_min(strength, 0.5), 0),
			DOG_EAR_END	= 600 / PAGE_WIDTH,
			//DOG_EAR_UPPER_START	= 50/PAGE_WIDTH;
			DOG_EAR_UPPER_START	= 1 / PAGE_WIDTH,
			DOG_EAR_STEEPNESS = PAGE_HEIGHT / DOG_EAR_UPPER_START,
			dogEarUpperLeftX,
			dogEarUpperLeftY,
			dogEarUpperRightX,
			dogEarUpperRightY,
			dogEarRightY,
			dogEarLowerLeftX,
			dogEarLowerLeftY,
			progress = 1 - flip_progress,
			abs_progress = Math_abs(progress),
			DOG_EAR_HEIGHT,
			a,
			b,
			w,
			p;

		if (progress > DOG_EAR_END) {
			dogEarLowerLeftY = 0;
			dogEarLowerLeftX = pw_p_fp;
			dogEarUpperLeftY = 0;
			dogEarUpperLeftX = pw_p_fp;
			dogEarUpperRightX = PAGE_WIDTH - foldWidth;
			dogEarUpperRightY = 0;
			dogEarRightY = PAGE_HEIGHT;
		} else if (progress > DOG_EAR_UPPER_START) {
			dogEarLowerLeftX = pw_p_fp;
			dogEarUpperLeftY = 0;
			dogEarUpperRightY = 0;
			dogEarRightY = 0;
			dogEarUpperLeftX = ((progress - DOG_EAR_UPPER_START) / (DOG_EAR_END - DOG_EAR_UPPER_START)) * PAGE_WIDTH * DOG_EAR_END;
			dogEarUpperRightX = PAGE_WIDTH - dogEarUpperLeftX / 2;
			dogEarUpperLeftX = PAGE_WIDTH - dogEarUpperLeftX;
		} else {
			dogEarLowerLeftX = pw_p_fp;
			dogEarUpperLeftX = foldX + foldWidth;
			dogEarUpperRightX = PAGE_WIDTH;
			dogEarRightY = PAGE_HEIGHT - progress * DOG_EAR_STEEPNESS;
			dogEarUpperRightY = dogEarRightY;
			dogEarUpperLeftY = dogEarRightY;
		}
		if (progress <= DOG_EAR_END) {
			DOG_EAR_HEIGHT = 10;
			b = DOG_EAR_HEIGHT<<1 / DOG_EAR_END;
			a = -b / DOG_EAR_END;
			/*a = -2 * DOG_EAR_HEIGHT / (DOG_EAR_END * DOG_EAR_END);
			b = -a * DOG_EAR_END;*/
			dogEarLowerLeftY = a * progress * progress + b * progress;
			if (progress > DOG_EAR_UPPER_START) {
				w = DOG_EAR_END - DOG_EAR_UPPER_START;
				p = progress - DOG_EAR_UPPER_START;
				b = DOG_EAR_HEIGHT<<1 / w;
				a = -b / w;
				/*a = -2 * DOG_EAR_HEIGHT / (w * w);
				b = -a * w;*/
				dogEarUpperLeftY = -a * p * p - b * p;
			}
		}

		context.save();
		context.translate(PAGE_X - BOOK_WIDTH + PAGE_WIDTH*2 + CANVAS_PADDING, PAGE_Y - BOOK_HEIGHT + PAGE_HEIGHT + CANVAS_PADDING);
		var incline = (dogEarUpperLeftX - dogEarLowerLeftX) / (PAGE_HEIGHT - dogEarRightY + 1),
			lineWidth = 200 * strength,
			x1 = dogEarUpperLeftX - (progress > DOG_EAR_END ? lineWidth : (PAGE_WIDTH-dogEarUpperLeftX)/PAGE_WIDTH/DOG_EAR_END*lineWidth),
			sharpShadowGradient;
		// Draw a sharp shadow on the left side of the page
		if (abs_progress > 0.05) {
			sharpShadowGradient = context.createLinearGradient(
				(x1 + dogEarLowerLeftX - lineWidth)>>1,
				(dogEarUpperLeftY + PAGE_HEIGHT - dogEarLowerLeftY + verticalOutdent*0.5)/2,
				(dogEarUpperRightX + foldX)>>1,
				PAGE_HEIGHT>>1
			);
			var d = 0.1;
			var a = -4;
			var b = 0.4;
			var start = Math_min(0.3-abs_progress*0.3, 0.4);
			var v = Math_max(a*progress+b, 0);
			if (v < 0) {
				v = 0;
			} else if (v > 1) {
				v = 1;
			} else if (isNaN(v)){
				v = 1;
			}
			try {
				sharpShadowGradient.addColorStop(0, 'rgba(0,0,0,'+v+')');
			} catch(e) {
				/* anscheinend gibt es Probleme, wenn die String-Darstellung in e-Notation ist */
			}
			sharpShadowGradient.addColorStop(0.2, 'rgba(1,0,0,0.2)');
			sharpShadowGradient.addColorStop(1, 'rgba(1,0,0,0.2)');
		} else {
			sharpShadowGradient = context.createLinearGradient(
				dogEarLowerLeftX - lineWidth, 0,
				foldX, 0
			);
			sharpShadowGradient.addColorStop(0, 'rgba(0,0,0,0.2)');
			sharpShadowGradient.addColorStop(1, 'rgba(0,0,0,0.2)');
		}
		context.fillStyle = sharpShadowGradient;
		context.beginPath();
		context.moveTo(foldX, 0 - verticalOutdent);
		context.lineTo(foldX, PAGE_HEIGHT + verticalOutdent);
		context.lineTo(dogEarLowerLeftX - lineWidth, PAGE_HEIGHT + verticalOutdent);
		context.lineTo(dogEarUpperLeftX - lineWidth, 0 - verticalOutdent);
		context.fill();

		// zusätzliche Schatten
		var thirdShadowWidth = foldWidth;
		var thirdShadowGradient = context.createLinearGradient(pw_p_fp - thirdShadowWidth, 0, pw_p_fp, 0);
		thirdShadowGradient.addColorStop(0, 'rgba(0,0,0,0)');
		thirdShadowGradient.addColorStop(1, 'rgba(0,0,0,0.2)');

		context.fillStyle = thirdShadowGradient;
		context.beginPath();
		context.moveTo(pw_p_fp - thirdShadowWidth, -verticalOutdent);
		context.lineTo(pw_p_fp - thirdShadowWidth, z3);
		context.lineTo(pw_p_fp, z3);
		context.lineTo(pw_p_fp, -verticalOutdent);
		context.fill();

		var thirdShadowStrength;
		if (progress > 1.99)
			thirdShadowStrength = 0;
		else if (progress < 1)
			thirdShadowStrength = 0.4;
		else
			thirdShadowStrength = 0.8 - progress * 0.4;
		thirdShadowWidth = 50;
		if (thirdShadowWidth > foldWidth) {
			thirdShadowWidth = foldWidth + 1;
		}
		thirdShadowGradient = context.createLinearGradient(foldX, 0, foldX+50 /* sic */, 0);
		thirdShadowGradient.addColorStop(0, 'rgba(0,0,0,' + thirdShadowStrength + ')');
		thirdShadowGradient.addColorStop(1, 'rgba(0,0,0,0)');
		context.fillStyle = thirdShadowGradient;
		context.beginPath();
		context.moveTo(foldX, 0);
		context.lineTo(foldX, PAGE_HEIGHT);
		context.lineTo(foldX + thirdShadowWidth, PAGE_HEIGHT);
		context.lineTo(foldX + thirdShadowWidth, 0);
		context.fill();

		// Right side drop shadow
		var rightShadowGradient = context.createLinearGradient(foldX, 0, foldX + rightShadowWidth, 0);
		rightShadowGradient.addColorStop(0, 'rgba(0,0,0,' + (strength * 0.2) + ')');
		rightShadowGradient.addColorStop(0.8, 'rgba(0,0,0,0.0)');

		context.fillStyle = rightShadowGradient;
		context.beginPath();
		context.moveTo(dogEarUpperRightX, dogEarRightY !== PAGE_HEIGHT ? dogEarRightY : 0);
		context.lineTo(dogEarUpperRightX + rightShadowWidth, dogEarRightY !== PAGE_HEIGHT ? dogEarRightY : 0);
		context.lineTo(foldX + rightShadowWidth, PAGE_HEIGHT);
		context.lineTo(foldX, PAGE_HEIGHT);
		context.fill();
	

		// Left side drop shadow
		var leftShadowGradient = context.createLinearGradient(pw_p_fp - leftShadowWidth, 0, pw_p_fp, 0);
		leftShadowGradient.addColorStop(0, 'rgba(0,0,0,0.0)');
		leftShadowGradient.addColorStop(1, 'rgba(0,0,0,'+(strength*0.15)+')');
		
		context.fillStyle = leftShadowGradient;
		context.beginPath();
		context.moveTo(dogEarUpperLeftX - leftShadowWidth + incline*(dogEarRightY+2*BUCKLE_HEIGHT), -BUCKLE_HEIGHT);
		context.lineTo(dogEarUpperRightX, -BUCKLE_HEIGHT);
		context.lineTo(dogEarUpperRightX, dogEarRightY-BUCKLE_HEIGHT);
		context.lineTo(foldX, PAGE_HEIGHT);
		context.lineTo(pw_p_fp - leftShadowWidth, PAGE_HEIGHT);
		context.fill();

		var secondShadowWidth = leftShadowWidth + 50;
		leftShadowGradient = context.createLinearGradient(pw_p_fp - secondShadowWidth, 0, pw_p_fp, 0);
		leftShadowGradient.addColorStop(0, 'rgba(0,0,0,0.0)');
		leftShadowGradient.addColorStop(1, 'rgba(0,0,0,'+(strength*0.1 + 0.015)+')');

		context.fillStyle = leftShadowGradient;
		context.beginPath();
		context.moveTo(dogEarUpperLeftX - secondShadowWidth + incline*(dogEarRightY+2*BUCKLE_HEIGHT), -BUCKLE_HEIGHT);
		context.lineTo(dogEarUpperLeftX, -BUCKLE_HEIGHT);
		context.lineTo(dogEarUpperLeftX, dogEarRightY-BUCKLE_HEIGHT);
		context.lineTo(foldX, PAGE_HEIGHT);
		context.lineTo(pw_p_fp - secondShadowWidth, PAGE_HEIGHT);
		context.fill();

		context.fillStyle = context.createPattern(gradientImage, 'repeat');
		context.strokeStyle = 'rgba(0,0,0,0.06)';
		context.lineWidth = 0.5;


		// Draw the folded piece of paper
		context.beginPath();
		context.moveTo(dogEarUpperRightX, dogEarRightY);
		context.lineTo(foldX, PAGE_HEIGHT);

		if (flip_progress < SWITCH_RATIO) {
			a1 = foldX;
			a2 = foldX + z1 * ratio;
			b1 = PAGE_HEIGHT + verticalOutdent*1.6;
			b2 = z3 - flip_progress*SECOND_OUTDENT_HEIGHT;
			c1 = a2; //foldX + z1*ratio;
			c2 = foldX + z1;
			d1 = b1; //PAGE_HEIGHT + verticalOutdent*1.6;
			d2 = PAGE_HEIGHT + verticalOutdent*2;
			e1 = z3 + verticalOutdent*0.85*(flip_progress+1);
			e2 = z3 + verticalOutdent*0.5*(flip_progress+1);

			context.bezierCurveTo(
				a1 + (a2-a1) * z2,
				b1 + (b2-b1) * z2,
				c1 + (c2-c1) * z2,
				d1 + (d2-d1) * z2,
				pw_p_fp*ratio, 
				e1 + (e2-e1) * z2
			);
			context.lineTo(pw_p_fp, z3);
		} else
			context.bezierCurveTo(
				dogEarLowerLeftX+foldWidth,	PAGE_HEIGHT + verticalOutdent*2 - dogEarLowerLeftY,
				dogEarLowerLeftX+foldWidth,	PAGE_HEIGHT + verticalOutdent*2 - dogEarLowerLeftY,
				dogEarLowerLeftX,		z3   - dogEarLowerLeftY
			);
		context.lineTo(dogEarUpperLeftX, dogEarUpperLeftY-verticalOutdent);
		if (flip_progress < SWITCH_RATIO) {
			a1 = -verticalOutdent * (1.85 + 0.85 * flip_progress);
			a2 = -verticalOutdent * (1.5 + 0.5 * flip_progress);
			b1 = foldX + z1 * ratio;
			b2 = foldX + z1;
			c1 = -verticalOutdent * 1.6;
			c2 = -verticalOutdent * 2;
			d1 = foldX;
			d2 = foldX + z1 * ratio;
			e1 = -verticalOutdent * 1.6;
			e2 = -verticalOutdent * 1 + flip_progress*SECOND_OUTDENT_HEIGHT;
			context.lineTo(pw_p_fp * ratio, a1 + (a2-a1) * z2);
			context.bezierCurveTo(
					b1 + (b2-b1) * z2,
					c1 + (c2-c1) * z2,
					d1 + (d2-d1) * z2,
					e1 + (e2-e1) * z2,
					foldX, 0
				);
		} else {
			context.bezierCurveTo(
				dogEarUpperRightX, dogEarUpperRightY - (verticalOutdent * 2),
				dogEarUpperRightX, dogEarUpperRightY - (verticalOutdent * 2),
				dogEarUpperRightX, dogEarUpperRightY
			);
		}
		var w = dogEarLowerLeftX + 12 - foldX;
		var r = (dogEarUpperRightX - foldX) / (PAGE_HEIGHT - dogEarRightY + 1);

		// the origin is in the upper left corner of the page
		//context.translate(w+PAGE_WIDTH, PAGE_HEIGHT);
		context.translate(w+PAGE_WIDTH - 11, PAGE_HEIGHT + 50);
		context.rotate(r);
		//context.translate(dogEarUpperRightX+PAGE_WIDTH, PAGE_HEIGHT);
		context.fill();
		context.stroke();
		context.restore();

		// Change page element width to match the x position of the fold
		setClipping(flip.page, foldX, PAGE_HEIGHT, dogEarUpperRightX, dogEarRightY);
	}
	function render() {
		var i = 0,
			len = 0,
			flip = null,
			step,
			flips_length = flips.length;
		for (i = 0, len = flips_length; i < len; i += 1) {
			flip = flips[i];
			var flip_progress = flip.progress;
			if ((Math.abs(flip_progress) < 0.999 || (flip_progress === 1 || flip_progress === -1 ) && flip.dragging)) {
				context.clearRect(0, 0, canvas.width, canvas.height);
				break;
			}
		}

		for (i = 0, len = flips_length; i < len; i += 1) {
			flip = flips[i];
			var flip_dragging = flip.dragging,
				flip_progress = flip.progress;

			if (flip_dragging) {
				flip.target = Math.max(Math.min(Math.min(mouse.x, PAGE_WIDTH - CLICK_BORDER_WIDTH) / PAGE_WIDTH, 1), -1);
			}

			// Ease progress towards the target value 
			step = (flip.target - flip_progress) * 0.2;
			if (flip_progress < -0.9 && step < 0 && step > -0.01) {
				step = -0.01;
			}
			flip_progress += step;
			if (flip_progress < -1) {
				flip.progress = -1;
			} else if (flip_progress > 0.995 && flip_progress !== 1) {
				flip.progress = 1;
				drawFlip(flip);
			} else if (flip_progress < -0.995 && flip_progress !== -1) {
				flip.progress = -1;
				drawFlip(flip);
			}
			// If the flip is being dragged or is somewhere in the middle of the book, render it
			if (flip_dragging || ((flip_progress > -0.999) && (flip_progress < 0.997))) {
				flip.progress = flip_progress;
				drawFlip(flip);
			}
		}
		hide_left_page();
	}

	function gotoByUrl (url, nohistory) {
		url = normalizeURL(url, History.getState().url);

		for (i = 0; i < pages.length; i += 1) {
			var $this = $(pages[i]).find('a[rel=this]');
			if ($this.attr('href') === url) {
				gotoPage(i, nohistory);
				return;
			}
		}

		var current_host = History.getState()['url'].match(/https?:\/\/([^\/]+)/)[1];
		var new_host = null;

		if (url.indexOf('://') !== -1) {
			var matches = url.match(/https?:\/\/([^\/]+)\/(.*)/);
			new_host = matches[1];
			if (new_host === current_host)
				url = matches[2];
		}

		if ((new_host && (new_host !== current_host)) ||
		    (url.indexOf(PAGEFLIP_BASE_URI) != 0))
			location.href = url;
		else {
			releaseBinds();
			if (History.enabled)
				History.pushState(null, null, url);
			loadPageAjax(url);
		}
	}
	function releaseBinds() {
			$(window).unbind('statechange');
			$('#pages a[rel=prev]').die('click');
			$('#pages a[rel=next]').die('click');
			$('a:not([rel])').die('click');
			$(document).unbind("mousemove");
			$(document).unbind("mousedown");
			$(document).unbind("mouseup");
			$(document).unbind("keypress");
			$(window).unbind('resize');
	}

	/* Abbruch Non-HTML5 Browser*/
	if (!canvas) { disablePageFlip(); return; }
	try {
		context = canvas.getContext("2d");
	}catch(err){
		disablePageFlip(); return;
	}
	if (!context) { disablePageFlip(); return; }

	if ($.browser.msie && $.browser.version < "9") { disablePageFlip(); return; }

	$(canvas).show();

	unbindPageEvents();
	commonEventHandlers();
	gradientImage = new Image();
	gradientImage.src = '/resources/img/magazin/gradient.jpg';

	reinitialize();
	autoLoadAdjacentPages(0);

	// Resize the canvas to match the book size
	canvas.width = PAGE_WIDTH*2 + (CANVAS_PADDING * 2);
	canvas.height = PAGE_HEIGHT + (CANVAS_PADDING * 2);

	// Offset the canvas so that it's padding is evenly spread around the book
	canvas.style.top = (BOOK_HEIGHT-PAGE_HEIGHT-CANVAS_PADDING) + "px";
	canvas.style.left = (BOOK_WIDTH-PAGE_WIDTH*2-CANVAS_PADDING) + "px";

	// Render the page flip 30 times a second
	clearInterval(renderInterval);
	renderInterval = setInterval(render, 1000 / 30);

	$(document).bind("mousemove", mouseMoveHandler);
	$(document).bind("mousedown", mouseDownHandler);
	$(document).bind("mouseup",	mouseUpHandler);
	$('#book-navigation a.next').bind("mouseover", navMouseOverHandler)
				    .bind("mouseout",  navMouseOutHandler);

	$(window).bind('resize', resizeWindow);

	/* IE kann ab Version 9 zwar Canvas, aber interpretiert das pointer-events im CSS nur fuer SVG */
	if($.browser.msie) {
		function relayMouseEvents(event) {
			if(!pages || (typeof page === 'undefined') || !pages[page]) return;
			var e = document.createEvent("MouseEvents");
			var offset = $(pages[page]).offset();
			$(canvas).hide();
			var element = document.elementFromPoint(event.clientX, event.clientY);
			$(canvas).show();
			if(!element) {
				$(canvas).css('cursor', 'default');
				return;
			}
			e.initMouseEvent(event.type, true, true, window,
				event.detail, event.screenX, event.screenY, event.screenX - offset.left, event.screenY - offset.top, false, false, false, false, event.button, null);
			element.dispatchEvent(e);
		}
		$(canvas).bind("mousemove", relayMouseEvents);
		$(canvas).bind("mouseover", relayMouseEvents);
		$(canvas).bind("mouseout", relayMouseEvents);
		$(canvas).bind("click", relayMouseEvents);
		$('#book section *').live("mousemove", function(e) {
			if(e.target.tagName.toLowerCase() == 'a')
				$(canvas).css('cursor', 'pointer');
			else
				$(canvas).css('cursor', 'default');
		});
	}

	// navigation via links: if there is a prev/next page, directly browse to it; otherwise load it first
	$('#pages a[rel=prev], #book-navigation a[rel=prev]').live('click', function (e) {
		var section = $(pages[page]);
		if (section.prev().length) {
			gotoPage(page-1);
		}
		e.preventDefault();
		return false;
	});

	$('#pages a[rel=next], #book-navigation a[rel=next]').live('click', function (e) {
		var section = $(pages[page]);
		if (section.next().length)
			gotoPage(page+1);
		e.preventDefault();
		return false;
	});
	$('a:not([rel])').live('click', function (e) {
		var url = $(e.target).attr('href');
		if(url) {
			gotoByUrl(url);
			e.preventDefault(); return false;
		}
	});

	$(window).bind('statechange', function (e) {
		var uri;
		if (History.enabled) {
			uri = History.getState()['url'];
			uri = uri.match(/https?:\/\/[^\/]+(\/.*)/)[1];
		} else
			uri = location.pathname;
		gotoByUrl(uri, true);
		e.preventDefault();
		return false;
	});

	showNavigation();
	$(window).bind("keydown", function (e) {
		var keycode = e.keyCode || e.which;
		switch(keycode) {
		case 37:	// links
			if(page > 0)
				gotoPage (page - 1);
			return false;
		case 39:	// rechts
			booklearned = true;
			if(page < pages.length-1) {
				booklearned = true;
				gotoPage (page + 1);
			}
			return false;
		}
	});
}

