/**
 *	INFO.NL EDIT :: Dit script is in zijn eigen namespace gezet. Het aanroepen
 *                  gebeurt via het registreren van dit script in de Base.js
 *                  class (zie onderste regel).
 *                  Hier en daar in dit bestand zijn al dingen aangepast, 
 *                  zoek hiernaar op: INFO.NL EDIT
 *                  Aanpassingen in de configuratie variabelen zijn niet
 *                  apart aangegeven. Bij implementatie svp alles copy/pasten.
 *                  
 *  
 *  ImageFlow 0.9
 *
 *	This code is based on Michael L. Perrys Cover flow in Javascript.
 *	For he wrote that "You can take this code and use it as your own" [1]
 *	this is my attempt to improve some things. Feel free to use it! If
 *	you have any questions on it leave me a message in my shoutbox [2].
 *
 *	The reflection is generated server-sided by a slightly hacked  
 *	version of Richard Daveys easyreflections [3] written in PHP.
 *	
 *	The mouse wheel support is an implementation of Adomas Paltanavicius
 *	JavaScript mouse wheel code [4].
 *
 *	Thanks to Stephan Droste ImageFlow is now compatible with Safari 1.x.
 *
 *
 *	[1] http://www.adventuresinsoftware.com/blog/?p=104#comment-1981
 *	[2] http://shoutbox.finnrudolph.de/
 *	[3] http://reflection.corephp.co.uk/v2.php
 *	[4] http://adomas.org/javascript-mouse-wheel/
 */

// OT: (function($) { var Imageflow = function()
function Imageflow () {
	/* Configuration variables */
	var conf_reflection_p  = 0.5;			// Sets the height of the reflection in % of the source image 
	var conf_focus         = 3;         // Sets the numbers of images on each side of the focussed one
	var conf_slider_width  = 10;        // Sets the px width of the slider div
	var conf_images_cursor = 'pointer'; // Sets the cursor type for all images default is 'default'
	var conf_slider_cursor = 'move';	// Sets the slider cursor type
	// INFO.NL EDIT - added config 
	// Whether or not clicking the front image will link using attr detailURL (which doesn't validate btw)
	// If given a function, it will call it. The function context will be the image (so this == image in DOM)
//  var conf_image_links = function(){ Base.Ajax.getItemInfo($(front_image).attr('id'), '#coverflow-iteminfo'); };
//	var conf_image_links = function(){ $("#coverflow-iteminfo").load("mod_on_display/ajax/iteminfo.php", {imgId: $(front_image).attr('bookID')}); }; 
	var conf_image_links = function() {
		//$("#coverflow-iteminfo").children().hide();
		$("#cflow-bookinfo").children().hide();
		$("#iteminfo-loader").show();
		imgId = $(front_image).attr('bookID');
		divId = "#iteminfo-" + imgId;
		if ($(divId).show().length > 0)
		{
			$("#iteminfo-loader").hide();
		}
		$("#cflow-images img").unbind("click");
		$(front_image).click(function() {
			window.location = $(this).attr("detailURL");
		});
	};
	var conf_start_image   = 3;          // image to start with. 0 = first image.
	var conf_use_caption   = false;      // Display alt attribute as caption
  
	/* Id names used in the HTML */
	var conf_imageflow = 'coverflow';    // Default is 'imageflow'
	var conf_loading   = 'cflow-loading';      // Default is 'loading'
	var conf_images    = 'cflow-images';       // Default is 'images'
//	var conf_captions  = 'cflow-captions';     // Default is 'captions'
//	var conf_scrollbar = 'cflow-scrollbar';    // Default is 'scrollbar'
//	var conf_slider    = 'cflow-slider';       // Default is 'slider'
  
	/* Define global variables */
	var caption_id = 0;
	var new_caption_id = 0;
	var current = 0;
	var target = 0;
	var mem_target = 0;
	var timer = 0;
	var array_images = new Array();
//	var new_slider_pos = 0;
//	var dragging = false;
//	var dragobject = null;
//	var dragx = 0;
	var posx = 0;
	var new_posx = 0;
	var xstep = 150;
	
	// VZ - Below vars need to be global
	var img_div = null;
	var max_conf_focus = null;
	var size = 0;
	var images_width = 0;
	var images_top = 0;
	var images_left = 0;
//	var caption_div = null;
//	var scrollbar_width = 0;
//	var slider_div = null;
	var imageflow_div = null;
	
	var front_image = null; // INFO.NL EDIT - used to make click-on-image events be set only once
  
  // INFO.NL EDIT
	// - Handles what happens with front image after animation
	// moved here from moveTo function, because onclick 
	// events were set after each "keyframe"
	function handleFrontImage()
	{
		switch( conf_image_links ){
			case true:
				front_image.onclick = function() { window.location = this.url; }
				break;
			
			case false:
				front_image.onclick = null;
				break;
			
			default:
				conf_image_links();
		}
	}

	function step()
	{
		switch (target < current - 1 ||
			target > current + 1) 
		{
  		case true:
  			moveTo(current + (target - current) / 3);
  			window.setTimeout(step, 50);
  			timer = 1;
  			break;
  
  		default:
  			timer = 0;
			handleFrontImage();
  			break;
		}
	}
  
  function glideTo(x, new_caption_id)
  {	
  	/* Animate gliding to new x position */
  	target = x;
  	mem_target = x;
  	if (timer == 0)
  	{
  		window.setTimeout(step, 50);
  		timer = 1;
  	}
  	
  	/* Display new caption */
  	caption_id = new_caption_id;
    
    // INFO.NL EDIT - use of caption has been made configurable
    if (conf_use_caption)
		caption = img_div.childNodes.item(array_images[caption_id]).getAttribute('alt');
    else
		caption = '';
      
  	if (caption == '')
	{
		caption = '&nbsp;';
	}
//  	caption_div.innerHTML = caption;

/*
  	// Set scrollbar slider to new position
  	if (dragging == false)
  	{
  		new_slider_pos = (scrollbar_width * (-(x*100/((max-1)*xstep))) / 100) - new_posx;
//BaseTemplate.Common.logToConsole(new_slider_pos);
  		slider_div.style.marginLeft = new_slider_pos + 'px'; // INFO.NL EDIT - calculation of slider pos. see L.210
  	}
*/
  }

  function moveTo(x)
  {
  	current = x;
  	var zIndex = max;
    
  	/* Main loop */
  	for (var index = 0; index < max; index++)
  	{
  		var image = img_div.childNodes.item(array_images[index]);
  		var current_image = index * -xstep;
  
  		/* Don't display images that are not conf_focussed */
  		if ((current_image + max_conf_focus) < mem_target ||
  			(current_image-max_conf_focus) > mem_target)
  		{
  			image.style.visibility = 'hidden';
  			image.style.display = 'none';
  		}
  		else 
  		{
if (!image.complete)
{
// 	if (typeof console !== 'undefined' && typeof console.log !== 'undefined')
// 	{
// 		console.log("Not resizing image because it's incomplete!");
// 	}
}
else
{
  			var z = Math.sqrt(10000 + x * x) + 100;
  			var xs = x / z * size + size;
  
  			/* Still hide images until they are processed, but set display style to block */
  			image.style.display = 'block';

  			/* Process new image height and image width */
  			var new_img_h = (image.h / image.w * image.pc) / z * size;

  			switch ( new_img_h > max_height )
  			{
  				case false:
  					var new_img_w = image.pc / z * size;
  					break;
  
  				default:
  					new_img_h = max_height;
  					var new_img_w = image.w * new_img_h / image.h;
  					break;
  			}
  			var new_img_top = (images_width * 0.34 - new_img_h) + images_top + ((new_img_h / (conf_reflection_p + 1)) * conf_reflection_p);
  
  			/* Set new image properties */
  			image.style.left = xs - (image.pc / 2) / z * size + images_left + 'px';
  			if (new_img_w && new_img_h)
  			{ 
  				image.style.height = new_img_h + 'px'; 
  				image.style.width = new_img_w + 'px'; 
  				image.style.top = new_img_top + 'px';
  			}
  			image.style.visibility = 'visible';
  
  			/* Set image layer through zIndex */
  			switch ( x < 0 )
  			{
  				case true:
  					zIndex++;
  					break;
  
  				default:
  					zIndex = zIndex - 1;
  					break;
  			}
  			
  			/* Change zIndex and onclick function of the focussed image */
  			if (image.i != caption_id)
  			{
				image.onclick = function() {
					glideTo(this.x_pos, this.i);
				};
			}
			else
			{
				zIndex = zIndex + 1;
				// INFO.NL EDIT - onclick functionality placed in step() function
				front_image = image;
			}
  			image.style.zIndex = zIndex;
}
  		}
  		x += xstep;
  	} // end for
  }

/*
	function ff(image, unresizedImage)
	{
		if (unresizedImage.src.length < 12 ||
			unresizedImage.width == undefined ||
			unresizedImage.height == undefined ||
			(unresizedImage.width <= 1 &&
			unresizedImage.height <= 1))
		{
			// Load a 'no cover supplied' image
			image.src = "static/images/icons/noCover.png";
			// A new 'load' event will trigger
			unresizedImage = null;
			return;
		}

		image.w = unresizedImage.width;
		image.h = unresizedImage.height;
		unresizedImage = null;

		// Check source image format. Get image height minus reflection height!
		switch (image.w + 1 > image.h / (conf_reflection_p + 1)) 
		{
		case true:
			// Landscape format
			image.pc = 118;
			break;

		default:
			// Portrait and square format
			image.pc = 100;
			break;
		}
	}
*/

	function cacheImageProperties(image)
	{
/*
		// Create a temporary copy that we know will be unresized (because we don't place it in the
		// DOM); it should load fast, because at this point it ought to be in the cache
		unresizedImage = new Image();
		unresizedImage.load = function(image, unresizedImage) {
			ff(image, unresizedImage);
		};
		unresizedImage.src = image.src;
*/

		if (image.naturalWidth &&
			image.naturalWidth <= 1 ||
			image.naturalHeight <= 1 ||
			image.src.length < 12 ||
			image.width == undefined ||
			image.height == undefined ||
			(image.width <= 1 &&
			image.height <= 1))
		{
			// Load a 'no cover supplied' image
			image.src = "static/images/icons/noCover.png";
			// A new 'load' event will trigger
			return;
		}

		image.w = image.width;
		image.h = image.height;

		// Check source image format. Get image height minus reflection height!
		switch (image.w + 1 > image.h / (conf_reflection_p + 1)) 
		{
		case true:
			/* Landscape format */
			image.pc = 118;
			break;

		default:
			/* Portrait and square format */
			image.pc = 100;
			break;
		}
	}
  
  /* Main function */
  function refresh(onload, showImg)
  {
  	/* Cache document objects in global variables */
  	imageflow_div = document.getElementById(conf_imageflow);
  	img_div = document.getElementById(conf_images);
  	
// VZ - No longer used
//  	var scrollbar_div = document.getElementById(conf_scrollbar);

//  	slider_div = document.getElementById(conf_slider);
//  	caption_div = document.getElementById(conf_captions);
  
  	/* Cache global variables, that only change on refresh */
  	images_width = img_div.offsetWidth;
  	// INFO.NL EDIT - not necessary when setting position:relative to conf_images
  	images_top = 0;//imageflow_div.offsetTop;
  	images_left = 0;//imageflow_div.offsetLeft;
  	max_conf_focus = conf_focus * xstep;
  	size = images_width * 0.5;
//  	scrollbar_width = $('#'+ conf_scrollbar).width() - $('#'+ conf_slider).width(); // INFO.NL EDIT - was: images_width * 0.6;
//  	conf_slider_width = conf_slider_width * 0.5;
  	max_height = images_width * 0.51;
  
  	/* Change imageflow div properties */
  	// INFO.NL EDIT .toFixed en -10
  	imageflow_div.style.height = (max_height-10).toFixed(0) + 'px';
  
  	/* Change images div properties */
  	img_div.style.height = images_width * 0.338 + 'px';
  
  	/* Change captions div properties */
//  	caption_div.style.width = images_width + 'px';
//  	caption_div.style.marginTop = images_width * 0.03 + 'px';
  
  	/* Change scrollbar div properties */
  	// INFO.NL EDIT - not needed
  //	scrollbar_div.style.marginTop = images_width * 0.02 + 'px';
  //	scrollbar_div.style.marginLeft = images_width * 0.2 + 'px';
  //	scrollbar_div.style.width = scrollbar_width + 'px';
  	
  	/* Set slider attributes */
//  	slider_div.onmousedown = function () { dragstart(this); };
//  	slider_div.style.cursor = conf_slider_cursor;
  
  	/* Cache EVERYTHING! */
  	max = img_div.childNodes.length;
  	var i = 0;
  	for (var index = 0; index < max; index++)
  	{
  		var image = img_div.childNodes.item(index);
  		if (image.nodeType == 1)
  		{
  			array_images[i] = index;
  			
  			/* Set image onclick by adding i and x_pos as attributes! */
  			image.onclick = function() { glideTo(this.x_pos, this.i); }
  			image.x_pos = (-i * xstep);
  			image.i = i;
  			
  			/* Add width and height as attributes ONLY once onload */
  			if (onload == true)
  			{
  				// VZ: Ensure more robust image resizing
  				// Set default value to prevent illegal access
  				image.pc = 100;
  				image.h = 160;
  				image.w = 110;
  				$(image).bind("load", function(eventObject) {
  					cacheImageProperties(this);
  				});
  				// In case the image has already been loaded the 'load' event will not fire
  				// again, so make sure 'cacheImageProperties()' still runs
  				if (image.complete)
  				{
  					cacheImageProperties(image);
  				}
  			}
    
  			/* Set ondblclick event */
  			// INFO.NL EDIT - linking is now configurable
  			if (conf_image_links)
  			{
//				image.url = image.getAttribute('detailURL');
				image.ondblclick = function()
				{
					window.location = image.getAttribute('detailURL');
				}
  			}
  
  			/* Set image cursor type */
  			image.style.cursor = conf_images_cursor;
  
  			i++;
  		}
  	}
  	max = array_images.length;
    
  	/* Display images in current order */
//  	moveTo(current);
//  	glideTo(current, caption_id);
  }
  
	/* Show/hide element functions */
	function show(id)
	{
		$("#" + id).show();
//  	var element = document.getElementById(id);
//  	element.style.visibility = 'visible';
	}
	
	function hide(id)
	{
		$("#" + id).hide();
/*		var element = document.getElementById(id);
		element.style.visibility = 'hidden';
		element.style.display = 'none';*/
	}
  
  /* Refresh ImageFlow on window resize */
  window.onresize = function()
  {
  	if (document.getElementById(conf_imageflow))
  	{
  		refresh();
  	}
  }
  
  /* Fixes the back button issue */
//  window.onunload = function()
//  {
//  	// INFO.NL EDIT
//  	// gives error in ie7. Base included in html head
//  	if( Base.ieVersion == 8 || ! Base.ieVersion)
//  	 document = null;
//  }
  
  
	// Handle the wheel angle change (delta) of the mouse wheel
	function handle(delta)
	{
		var change = false;
		switch (delta > 0)
		{
			case true:
				if (caption_id >= 1)
				{
					target = target + xstep;
					new_caption_id = caption_id - 1;
					change = true;
				}
				break;
	
			default:
				if (caption_id < max - 1)
				{
					target = target - xstep;
					new_caption_id = caption_id + 1;
					change = true;
				}
				break;
		}

		// Glide to next (mouse wheel down) / previous (mouse wheel up) image
		if (change == true)
		{
			glideTo(target, new_caption_id);
		}
	}
  
  /* Event handler for mouse wheel event */
  function wheel(event)
  {
  	var delta = 0;
  	if (!event)
  	{
  		event = window.event;
  	}
  	if (event.wheelDelta)
  	{
  		delta = event.wheelDelta / 120;
  	}
  	else if (event.detail)
  	{
  		delta = -event.detail / 3;
  	}
  	if (delta)
  	{
  		handle(delta);
  	}
  	if (event.preventDefault)
  	{
  		event.preventDefault();
  	}
  	event.returnValue = false;
  }
  
	// Initialize mouse wheel event listener
	function initMouseWheel()
	{
		if (window.addEventListener)
		{
			imageflow_div.addEventListener('DOMMouseScroll', wheel, false);
		}
		// TODO: Make sure this shouldn't happen only on 'else'
		imageflow_div.onmousewheel = wheel;
	}

/*
  // This function is called to drag an object (= slider div)
	function dragstart(element)
	{
		dragobject = element;
		dragx = posx - dragobject.offsetLeft + new_slider_pos;
	}

  // This function is called to stop dragging an object
	function dragstop()
	{
		dragobject = null;
		dragging = false;
	}

  // This function is called on mouse movement and moves an object (= slider div) on user action
  function drag(e)
  {
  	posx = document.all ? window.event.clientX : e.pageX;
  	if(dragobject != null)
  	{
  		dragging = true;
  		new_posx = (posx - dragx) + conf_slider_width;
  
  		// Make sure, that the slider is moved in proper relation to previous movements by the glideTo function
  		if(new_posx < ( - new_slider_pos)) new_posx = - new_slider_pos;
  		if(new_posx > (scrollbar_width - new_slider_pos)) new_posx = scrollbar_width - new_slider_pos;
  		
  		var slider_pos = (new_posx + new_slider_pos);
  		var step_width = slider_pos / ((scrollbar_width) / (max-1));
  		var image_number = Math.round(step_width);
  		var new_target = (image_number) * -xstep;
  		var new_caption_id = image_number;
  
  		dragobject.style.left = new_posx + 'px';
  		glideTo(new_target, new_caption_id);
  	}
  }
  
  // Initialize mouse event listener
  function initMouseDrag()
  {
  	document.onmousemove = drag;
  	document.onmouseup = dragstop;
  
  	// Avoid text and image selection while dragging
  	document.onselectstart = function () 
  	{
		return !dragging;
  	}
  }
  
	function deinitMouseDrag()
	{
		document.onmousemove = null;
		document.onmouseup = null;

		// Avoid text and image selection while dragging
		document.onselectstart = null;
	}
*/
  
  function getKeyCode(event)
  {
  	event = event || window.event;
  	return event.keyCode;
  }
  
  document.onkeydown = function(event)
  {
  	var charCode  = getKeyCode(event);
  	switch (charCode)
  	{
  		/* Right arrow key */
  		case 39:
  			handle(-1);
  			break;
  		
  		/* Left arrow key */
  		case 37:
  			handle(1);
  			break;
  	}
  }

	function doStartCoverFlow()
	{
		var coverFlowImagesDiv = $("#" + conf_images);
// DEBUG:
if (coverFlowImagesDiv.length <= 0)
{
	BaseTemplate.Common.logToConsole("Div with ID 'cflow-images' not found!");
}

		var numberOfCoverFlowImages = coverFlowImagesDiv.children("img").length;
// DEBUG:
if (numberOfCoverFlowImages <= 0)
{
	//BaseTemplate.Common.logToConsole("No images in div with ID 'cflow-images'!");
}
		for (var i = 0; i < 8 && i < numberOfCoverFlowImages; i++)
		{
			var image = coverFlowImagesDiv.children("img").eq(i).get(0);

			if (!image.complete)
			{
				setTimeout(doStartCoverFlow, 200);

				return;
			}
		}

   		hide(conf_loading);
		show(conf_images);
//		show(conf_scrollbar);

//		initMouseDrag();
		initMouseWheel();

		$('#cflow-sb-left').click(function() { handle(1); });
		$('#cflow-sb-right').click(function() { handle(-1); });

		glideTo(-conf_start_image * xstep, conf_start_image);
	}

	return {
		refresh: function(onload, showImg) {
			refresh(onload, showImg);
			doStartCoverFlow();
			refresh(true, conf_start_image);
		},
		deinit: function() {
			if (window.removeEventListener)
			{
				imageflow_div.removeEventListener('DOMMouseScroll', wheel, false);
			}
//			deinitMouseDrag();
			$('#cflow-sb-left').unbind("click");
			$('#cflow-sb-right').unbind("click");
//			$("#" + conf_slider).css("left", "0px");
		}
	};
}
