/**
 * @author Jakob Steinmann
 * @version 1
 * @requires prototype.js
 * @fileoverview funktionen fuer viewer + minireader
 */

/**
 * 
 * seite fertig geladen, js init
 */
document.observe("dom:loaded", function() 
{
	if (document.location.href.indexOf('viewer') > -1) 
	{
		viewer_main.init();
	}
	else if (document.location.href.indexOf('reader') > -1) 
	{
		reader_main.init();
	}
});

var prototype_extension =
{
	init: function()
	{
		Prototype.Browser.IE6 = Prototype.Browser.IE && parseInt(navigator.userAgent.substring(navigator.userAgent.indexOf("MSIE")+5)) == 6;
		Prototype.Browser.IE7 = Prototype.Browser.IE && parseInt(navigator.userAgent.substring(navigator.userAgent.indexOf("MSIE")+5)) == 7;
		Prototype.Browser.IE8 = Prototype.Browser.IE && !Prototype.Browser.IE6 && !Prototype.Browser.IE7;
	}
}

var viewer_main = 
{
	init: function(enabled, icon)
	{
		prototype_extension.init();
		// init + session auf djangoseite zerschossen - keine ahnung warum
		// deshalb: rausgeworfen, stattdessen in dta_viewer_show.html initdata definiert,
		// da sind auch alle daten drin
		// funktionen fuer ansicht (einzel, doppel, id's)
		view_manager.init(viewer_initdata.view);
		// konstanten, tools
		config_manager.init(viewer_initdata);
		// drag + scroll
		drag_manager.init();
		// image crop
		crop_manager.init();
		// in/out/grow
		zoom_manager.init();
		// umblaettern
		page_turn_manager.init(viewer_initdata.current_page);
		//
		menu_manager.init();
		//
		annotation_manager.init();
		
		Event.observe($(config_manager.constants.goto_page_id), 'keydown', keyDown);
		Event.observe(window, 'keydown', keyDown);

	}
}

var reader_main =
{
	init: function()
	{
		prototype_extension.init();
		view_manager.init(viewer_initdata.view);
		config_manager.init(viewer_initdata);
		zoom_manager.initReader();
		page_turn_manager.initReader(viewer_initdata.current_page);
	}
}
/**
 * 
 * msg out debug
 */
// try { console.log('init console... done'); } catch(e) { console = { log: function() {} } }
function log(msg)
{
	if (typeof console != "undefined")
		console.log(msg);
		
	if (typeof opera != "undefined")
		opera.postError(msg);
}

/**
 * 
 * callstack ausgeben
 */

// cs=>callstack
function cs()
{
	if (typeof console != "undefined")
		console.trace();
}

/**
 * 
 * dummy debug
 */

function d()
{
	log('d()');
}

/**
 * 
 * config objekt
 * lauter variablen für den viewer (seitengrösse, - anzahl etc.)
 * und ein paar utilities (aktuelle seite / auflösung setzten/lesen
 */
var config_manager = 
{
	// hoehe einer seite
	page_height: 0,
	// gesamtanzahl seiten
	page_count: 0,
	//
	root_url: '',
	// url zum nachladen der bilder
	request_url: '',
	// url fuer das ladeindikator image
	loader_url: '',
	//
	media_url : '',
	// aktuelle seite 
	current_book_id: 0,
	//
	book_author: '',
	book_title: '',
	// aktuelle seite 
	current_page: 1,
	// vorher sichtbare seite
	prev_page: 1,
	// auflsung
	current_resolution: 40,
	// scroll speed mausrad
	scrollwheel_offset: -180,
	
	pages: [],
	
	// konstanten
	constants:
	{
		// erste seite
		page_min: 1,
		// id des divs fuer das image (div_image1, div_image2, ...)
		img_div_id: 'div_image',
		// id des divs mit dem scrollbalken 
		scroll_div_id: 'container',
		// image container
		images_container_div_id: 'images',
		// id der divs fuer doppelansicht
		images_double_div : 'images_double',
		// id des eingabefeldes fuer "gehe zu seite"
		goto_page_id: 'viewer_goto_page',
		// um soviel wird gescrollt bei pgUp/pgDown (alt, im moment wird geblaettert => nextPage())
		pgUpDown_scroll_amount: 530,
		// um soviel wird gescrollt bei pfiel hoch/runter
		arrowUpDown_scroll_amount: 15,
		// hoehe des pfeilbuttons im scrollbalken
		scrollbutton_height: 18,
		// bei seitenhoehe - page_wrap springt die aktuelle seite 
		page_wrap: 380,
		// grenze fuer "schnelles scrollen" => weniger laden
		fast_scroll_cap: 5000,
		// scrollrichtungen,
		scrollDirections:
		{
			up: "up",
			down: "down"
		}
	},
	
	// info ueber aktuelle scrollzustand
	scrollInfo:
	{
		scrollpos: 0,
		srcoll_direction: "",
		fast_scroll: false
	},
	
	// gibt die ID des divs eines bildes zurueck
	getImgDivId: function (img_number)
	{
		return this.constants.img_div_id + (parseInt(img_number));
	},
	
	// gibt den div-tag eines bildes zurueck
	getImgDiv:function  (img_number)
	{
		return $(this.getImgDivId(img_number));
	},
	
	/**
	 * setScrollDir
	 * setzen des scrollrichtung
	 * @param int current_scroll_pos aktuelle scrollposition
	 * @return scrollrichtung als constants.scrollDirections
	 */
	setScrollDir: function (current_scroll_pos)
	{
		// scroll runter
//		var scroll_diff = current_scroll_pos - this.scrollInfo.scrollpos;
//		this.scrollInfo.fast_scroll = (scroll_diff > this.constants.fast_scroll_cap || scroll_diff < -this.constants.fast_scroll_cap);
//		if(this.scrollInfo.fast_scroll)
//			new PeriodicalExecuter(function(pe)
//			{
//				var scroll_diff = $(config_manager.constants.scroll_div_id).scrollTop - config_manager.scrollInfo.scrollpos;
//				config_manager.scrollInfo.fast_scroll = (scroll_diff > config_manager.constants.fast_scroll_cap || scroll_diff < -config_manager.constants.fast_scroll_cap);
//				log(config_manager.scrollInfo.scrollpos);
//				config_manager.scrollInfo.scrollpos = $(config_manager.constants.scroll_div_id).scrollTop;
//				if(!config_manager.scrollInfo.fast_scroll)
//					pe.stop();				
//					nextImage();
//			}, 0.3);

		if(current_scroll_pos >= this.scrollInfo.scrollpos)
			this.scrollInfo.srcoll_direction = this.constants.scrollDirections.down;
		else
			this.scrollInfo.srcoll_direction = this.constants.scrollDirections.up;

		this.scrollInfo.scrollpos = current_scroll_pos;
		
		return this.getScrollDir();
	},
	
	/**
	 * resetFastScroll => wird nicht benutzt
	 * @param {Object} event mouseevent
	 */	
	resetFastScroll: function(event)
	{
		this.scrollInfo.fast_scroll = false;
		image_load_manager.nextImage();
	},
	/**
	 * getScrollDir
	 * @return scrollrichtung als constants.scrollDirections
	 */
	getScrollDir: function ()
	{
		return this.scrollInfo.srcoll_direction;
	},
	
	getScrollPos: function ()
	{
		return this.scrollInfo.scrollpos;
	},
	
	/**
	 * isUp
	 * @return boolan scrollrichtung hoch?
	 */
	isUp: function ()
	{
		return this.getScrollDir() == this.constants.scrollDirections.up;
	},

	/**
	 * isDown
	 * @return boolan scrollrichtung runter?
	 */
	isDown: function ()
	{
		return this.getScrollDir() == this.constants.scrollDirections.down;
	},
	
	/**
	 * setCurrentPage
	 * @param int page aktuelle seite 
	 */
	setCurrentPage: function (page)
	{
		page = parseInt(page);
		cookie_manager.setCookie('{"book":'+this.current_book_id+', "page":"'+page+'"}');
		
		this.prev_page = this.current_page;
		this.current_page = page;
		
		if($F(this.constants.goto_page_id) != page)
			$(this.constants.goto_page_id).value = page; 
			
		page_turn_manager.manageIcons(page);
	},
	
	/**
	 * getCurrentPage
	 * @return int aktuelle seite
	 */
	getCurrentPage: function ()
	{
		return this.current_page;
	},
	
	/**
	 * getPrevPage
	 * @return int vorherige seite
	 */
	getPrevPage: function ()
	{
		return this.prev_page;
	},
	
	/**
	 * init
	 * @param {Object} json return vom init/ request
	 */
	init: function(json)
	{
		this.scrollInfo.srcoll_direction = this.constants.scrollDirections.up;
		page_height = 0;
		page_count = 0;
		request_url = '';
		img_url = '';
		
		this.page_count = json.page_count;
		if (view_manager.isSingleView()) // sigleview
		{
			
			var pages = $(this.constants.images_container_div_id).select('div.page');
			if (pages.length == 0) 
			{
				return;
			}
			var margin = parseInt(pages[0].getStyle('margin-top'));
			
			pages.each(
			function(page, idx)
			{
				if (idx == 0) 
					config_manager.pages[idx] = 
					{
						'top': 0,
						'bottom': page.getHeight()
					};
				else 
					config_manager.pages[idx] = 
					{
						'top': config_manager.pages[idx - 1].bottom + margin + (config_manager.constants.scrollbutton_height * idx),
						'bottom': page.getHeight() + config_manager.pages[idx - 1].bottom
					};
			});
		}

		this.root_url = json.root_url; 
		this.request_url = json.request_url;
		this.loader_url = json.media_url+'img/';
		this.media_url = json.media_url;
		this.current_book_id = json.book_id;
		this.current_resolution = parseInt(json.current_resolution);
		this.book_author = json.book_author;
		this.book_title = json.book_title;

		if(this.current_resolution < 30)
			this.constants.page_wrap = 600;
		// bei opera geht die scrollrichtung andersrum beim mausrad
		if(Prototype.Browser.Opera)
			this.scrollwheel_offset *= -1;
			
	}	
};

/**
 * page_turn_manager
 * functionen / konstanten zum blättern
 */
var page_turn_manager = 
{
	/**
	 * konstanten
	 * icons, id's, pfade
	 */
	prev_page_icon_id: 'viewer_prev_page_icon',
	next_page_icon_id: 'viewer_next_page_icon',
	
	icon_left: 'arrow-left.gif',
	icon_right: 'arrow-right.gif',

	first_page_icon_id: 'viewer_first_page_icon',
	last_page_icon_id: 'viewer_last_page_icon',

	icon_up: 'skip-back.gif',
	icon_down: 'skip.gif',

	thumb_selected_class: 'viewer_thumb_selected',
	thumb_selected_element: 'img',
	
	/**
	 * @return element aktuell markiertes thumbnail
	 */
	getSelectedThumb: function()
	{
		return $(config_manager.constants.scroll_div_id).select(this.thumb_selected_element + '.' + this.thumb_selected_class)[0];
	},
	
	/**
	 * umblättern zur nächsten seite 
	 */
	nextPage: function ()
	{
		var page = config_manager.getCurrentPage()+1;
		if(view_manager.current_view == view_manager.views.imageimage && (page % 2))
			page++;

		this.setPageVisible(page);
	},
	
	/**
	 * umblättern zur vorigen seite 
	 */
	prevPage: function ()
	{
		var page = config_manager.getCurrentPage()-1;
		if(view_manager.current_view == view_manager.views.imageimage && (page % 2))
			page--;

		this.setPageVisible(page);	
	},
	
	/**
	 * gehe zu seite im eingabefeld 
	 */
	gotoPage: function ()
	{
		var page_number = parseInt($F(config_manager.constants.goto_page_id));
		if(!Object.isNumber(page_number))
			return;
		
		this.setPageVisible(page_number);
		
//		$(config_manager.constants.goto_page_id).focus();
//		$(config_manager.constants.goto_page_id).clear();
	},
	
	/**
	 * zur seite scrollen - laden - anzeigen
	 * @param {Object} page_number
	 */
	setPageVisible: function (page_number)
	{
		if (page_number > config_manager.page_count) 
			page_number = config_manager.page_count;
		else if (page_number < 1) 
			page_number = 1;
		
		if( page_number == config_manager.getCurrentPage())
			return;

		if(view_manager.isSingleView())
		{
			$(config_manager.constants.scroll_div_id).scrollTop = config_manager.pages[page_number - 1].top;
			// ??
			// auskommentieren um blättern im IE 7 auszuschalten :o
			var ie_dumm_hack = $(config_manager.constants.scroll_div_id).scrollTop;
		}
		else if (view_manager.isDoubleView())
		{
			config_manager.setCurrentPage(page_number);
			image_load_manager.nextImage();
		}
		else if (view_manager.current_view == view_manager.views.thumbs)
		{
			this.toggleActiveThumb(page_number);
			var element = this.getSelectedThumb();
			var offset = element.viewportOffset()[1] - config_manager.constants.page_wrap + 50;
			$(config_manager.constants.scroll_div_id).scrollTop += offset;		
		}
		
		this.manageIcons(page_number);
		config_manager.setCurrentPage(page_number);
	},
	
	/**
	 * neues thumbnail aktiviert markieren
	 * @param {Object} page_number zu aktivierendes thumb seitennummer
	 */
	toggleActiveThumb: function(page_number)
	{
		var active_element = this.getSelectedThumb();
		active_element.removeClassName(this.thumb_selected_class);
		var new_id = 'img_' + config_manager.constants.img_div_id + page_number;
		$(new_id).addClassName(this.thumb_selected_class);
	},
	
	manageIcons: function (page_number)
	{
		// strg+c strg+v :o
		if(page_number == 1)
		{
			$(this.prev_page_icon_id).src = toggle_icon_manager.makeIconPath(false, this.icon_left);
			$(this.next_page_icon_id).src = toggle_icon_manager.makeIconPath(true, this.icon_right);
			$(this.first_page_icon_id).src = toggle_icon_manager.makeIconPath(false, this.icon_up);
			$(this.last_page_icon_id).src = toggle_icon_manager.makeIconPath(true, this.icon_down);
		}
		else if((page_number == config_manager.page_count) ||
				(view_manager.current_view == view_manager.views.imageimage && (page_number + 1) == config_manager.page_count))
		{
			$(this.prev_page_icon_id).src = toggle_icon_manager.makeIconPath(true, this.icon_left);
			$(this.next_page_icon_id).src = toggle_icon_manager.makeIconPath(false, this.icon_right);
			$(this.first_page_icon_id).src = toggle_icon_manager.makeIconPath(true, this.icon_up);
			$(this.last_page_icon_id).src = toggle_icon_manager.makeIconPath(false, this.icon_down);
		}
		else
		{
			$(this.prev_page_icon_id).src = toggle_icon_manager.makeIconPath(true, this.icon_left);
			$(this.next_page_icon_id).src = toggle_icon_manager.makeIconPath(true, this.icon_right);			
			$(this.first_page_icon_id).src = toggle_icon_manager.makeIconPath(true, this.icon_up);
			$(this.last_page_icon_id).src = toggle_icon_manager.makeIconPath(true, this.icon_down);			
		}
	},
	
	// scrollbuttonbar
	bar_top_id: 'viewer_scrollbuttonbar_top',
	bar_top_display_at: 0,
	bar_bottom_id: 'viewer_scrollbuttonbar_bottom',
	bar_bottom_display_at: 0,
	bar_display_offset: 30,
	bar_class: 'scrollbuttonbar',
	bar_visible: false,
	engine_header_id: 'engine_header',
	scrollbutton_events_set: false,
	
	/**
	 * 
	 * @param {Object} e mousemove event
	 */	
	toggleScrollButtonBars: function(e)
	{
		if(menu_manager.hasVisibleMenus())
			return;
		if(crop_manager.active == crop_manager.cut) 
			return;
		if(view_manager.current_view == view_manager.views.thumbs) 
			return;
		this.bar_bottom_display_at = $(config_manager.constants.scroll_div_id).getHeight() + this.bar_top_display_at - (2*this.bar_display_offset);

		if(e.clientY <= this.bar_top_display_at)
		{
			$(this.bar_top_id).show();
			this.bar_visible = true;
		}
		else if(e.clientY >= this.bar_bottom_display_at)
		{
			$(this.bar_bottom_id).show();
			this.bar_visible = true;
		}
		else if(this.bar_visible)
		{
			$$('div.'+ this.bar_class).each(function(e)
			{
				e.hide();
			});
			view_manager.bar_visible = false;
		}		
	},
	
	initScrollbuttonsbars: function()
	{
		if(Prototype.Browser.IE8) return;
		
		$(this.bar_top_id).setOpacity(0.5);
		$(this.bar_bottom_id).setOpacity(0.5);
		
		this.bar_top_display_at = parseInt($(config_manager.constants.scroll_div_id).getStyle('top')) + this.bar_display_offset;
		this.bar_bottom_display_at = $(config_manager.constants.scroll_div_id).getHeight() + this.bar_top_display_at - this.bar_display_offset;
		
		// scrollbar!
		if($(config_manager.constants.scroll_div_id).scrollWidth  > $(config_manager.constants.scroll_div_id).clientWidth )
		{
			this.bar_bottom_display_at -= 17;
			$(this.bar_bottom_id).setStyle({bottom:'17px'});
		}
		
		if(this.scrollbutton_events_set) return;
		
		Event.observe(config_manager.constants.scroll_div_id, 'mousemove', page_turn_manager.toggleScrollButtonBars.bindAsEventListener(page_turn_manager));

		Event.observe(this.bar_top_id, 'click', page_turn_manager.prevPage.bindAsEventListener(page_turn_manager));
		Event.observe(this.bar_bottom_id, 'click', page_turn_manager.nextPage.bindAsEventListener(page_turn_manager));

		Event.observe(this.bar_top_id, 'mouseout', function(e){ $(page_turn_manager.bar_top_id).hide(); });
		Event.observe(this.bar_bottom_id, 'mouseout', function(e){ $(page_turn_manager.bar_bottom_id).hide(); });
		
		// kein mouseout im IE wenn nach oben raus?!
		if(Prototype.Browser.IE)
			Event.observe(this.engine_header_id, 'mouseover', function(e){ $(page_turn_manager.bar_top_id).hide(); });
		
		this.scrollbutton_events_set = true;
		
	},
		
	init: function(page_number)
	{
		this.initScrollbuttonsbars();
		this.initReader(page_number);
	},
	
	initReader: function(page_number)
	{
		if (page_number > 1) 
			this.setPageVisible(page_number);
		else 
			image_load_manager.nextImage();
	}
}

var cookie_manager = 
{
	setCookie: function (value)
	{
		return;
		var name = 'dta_viewer', expires = 30, path = false, domain = false, secure = false;
		// set time, it's in milliseconds
		var today = new Date();
		today.setTime( today.getTime() );
		
		/*
		if the expires variable is set, make the correct
		expires time, the current script below will set
		it for x number of days, to make it for hours,
		delete * 24, for minutes, delete * 60 * 24
		*/
		if ( expires )
		{
			expires = expires * 1000 * 60 * 60 * 24;
		}
		var expires_date = new Date( today.getTime() + (expires) );
		
		document.cookie = name + "=" +escape( value ) +
		( ( expires ) ? ";expires=" + expires_date.toGMTString() : "" ) +
		( ( path ) ? ";path=" + path : "" ) +
		( ( domain ) ? ";domain=" + domain : "" ) +
		( ( secure ) ? ";secure" : "" );
	},
		
	getCookie: function (  ) 
	{
		return null;
		var check_name = 'dta_viewer';
		// first we'll split this cookie up into name/value pairs
		// note: document.cookie only returns name=value, not the other components
		var a_all_cookies = document.cookie.split( ';' );
		var a_temp_cookie = '';
		var cookie_name = '';
		var cookie_value = '';
		var b_cookie_found = false; // set boolean t/f default f
	
		for ( i = 0; i < a_all_cookies.length; i++ )
		{
			// now we'll split apart each name=value pair
			a_temp_cookie = a_all_cookies[i].split( '=' );
	
	
			// and trim left/right whitespace while we're at it
			cookie_name = a_temp_cookie[0].replace(/^\s+|\s+$/g, '');
	
			// if the extracted name matches passed check_name
			if ( cookie_name == check_name )
			{
				b_cookie_found = true;
				// we need to handle case where cookie has no value but exists (no = sign, that is):
				if ( a_temp_cookie.length > 1 )
				{
					cookie_value = unescape( a_temp_cookie[1].replace(/^\s+|\s+$/g, '') );
				}
				// note that in cases where cookie is initialized but no value, null is returned
				return cookie_value;
				break;
			}
			a_temp_cookie = null;
			cookie_name = '';
		}
		if ( !b_cookie_found )
		{
			return null;
		}
	}
}
// drag ops helper
var drag_manager = 
{
	// y pos vorheriger onDrag aufruf
	prev_y : 0,
	// scrollspeed
	speed : 1,
	
	handle: 'container',
	dummy: 'drag_dummy',
	
	draggable: null,
	
	disableDrag: function()
	{
		if (this.draggable) 
		{
			this.draggable.destroy();
			this.draggable = null;
		}
	},

	enableDrag: function()
	{
		if (this.draggable) 
		{
			this.draggable.destroy();
			this.draggable = null;
		}
		this.draggable = new Draggable(this.dummy, { 	handle: this.handle,
		                                constraint: 'vertical',
		                                onStart: function(object, event)
		                                {
		                                	drag_manager.start(event);
										},
		                                onDrag: function (object, event)
										{
//											var e = Event.element(event); 
//											if (e) 
//											{
//												if (e.id == 'image_1' ||
//												e.id == 'image_2' ||
//												getAncestorById(e, 'image_1') ||
//												getAncestorById(e, 'image_2') ||
//												(view_manager.isSingleView() && getAncestorByClassName(Event.element(event), 'page'))) 
//												{
//													Event.stop(event);
//													return;
//												}
//											}
											$(config_manager.constants.scroll_div_id).scrollTop += drag_manager.calcScrollAmount(event);
										},
		                                onEnd: function(object, event)
		                                {
		                                }
		                            });		
	},

	// initialisieren
	init : function ()
	{
		this.enableDrag();
	},
	
	/**
	 * start
	 * drag starten/initialisieren
	 * @param mouse event
	 */
	start : function (event)
	{
		this.prev_y = event.clientY;
	},
	
	/**
	 * calcScrollAmount
	 * ermitteln um wieviel gescrollt werden soll
	 * @param mouse event
	 * @return int um wieviel gescrollt werden soll inkl gescwindigkeit
	 */
	calcScrollAmount : function(event)
	{
		if(event.ctrlKey) return 0;
	    y = this.prev_y - event.clientY;
	    this.prev_y = event.clientY;
	    return y*this.speed;
	}
}

/**
 * @class load_manager
 * kapselt die ladelogik fuer bilder (laed grad, schon geladen etc.)
 * @requires config_manager
 */

var load_manager = 
{
	currently_loading: {},
	ok: true,
	loading: false,

	loaded_conatiner_id: 'images_double_loaded_conatiner',
	image_postfix: '_image',
	page_1_container_id: 'image_1',
	page_2_container_id: 'image_2',
	page_1_id: 'img_image_1',
	page_2_id: 'img_image_2',

	/**
	 * init
	 * initialisieren loadmanager
	 */

	init: function ()
	{
		currently_loading = {};
	},

	displayLoading: function(show)
	{
		
	},

	/**
	 * setLoading
	 * setze status von img_nr auf true
	 * @param img_nr int img/page nummer
	 */
	setLoading: function (img_nr)
	{
		// es werden immer 3 bilder geladen
		// aktuelles bild +- 1
		if(img_nr-1 > 0 && !this.isLoaded(img_nr-1))
			this.currently_loading[img_nr-1] = true;
		if(!this.isLoaded(img_nr))
			this.currently_loading[img_nr] = true;
		if(img_nr+1 < config_manager.page_count && !this.isLoaded(img_nr+1))
			this.currently_loading[img_nr+1] = true;
			
	},
	
	/**
	 * isLoading
	 * prï¿½ft status von img_nr auf loading == true
	 * @param img_nr int img/page nummer
	 */
	isLoading: function (img_nr)
	{
		return this.currently_loading[img_nr] == true;
	},
	
	/**
	 * finishedLoading
	 * setze status von img_nr auf loading = false
	 * @param img_nr int img/page nummer
	 */
	finishedLoading: function(img_nr)
	{
		if(!this.currently_loading[img_nr])
			return;
		this.currently_loading[img_nr] = false;
	},
	
	/**
	 * isLoaded
	 * prï¿½ft ob img_nr schonmal gesetzt wurde
	 * @param img_nr int img/page nummer
	 */
	isLoaded: function(img_nr)
	{
		return this.currently_loading[img_nr] == false;
	},
	
	// view - gesplitteter teil, d.h. nut text, xml, image etc
	// var views = view_manager.splitCurrentView();
	saveImage: function(img_nr, view)
	{
		//log('saving:' + img_nr + ' ' +  view);
		var id = view + this.image_postfix + img_nr;
		// noch nicht da/ falsche view o.ae.
		if(!$(id)) return;
		// schon gespeichert
		if(view == view_manager.views.image)
			var loaded_item = $(this.loaded_conatiner_id).select('img#' + id)[0];
		else
			var loaded_item = $(this.loaded_conatiner_id).select('div#' + id)[0];
		if (loaded_item)
		{
			// log((id)+' schon gespeichert');
			return;
		}
		// speichern
		viewer_Move.copy(id, this.loaded_conatiner_id);
	},
	
	/**
	 * 
	 * @param int img_nr
	 * @return	false 	bilder konnten nicht geladen werden
	 * 			true	bilder wurden geladen
	 */
	loadDoubleContent: function(img_nr)
	{
		var views = view_manager.splitCurrentView();
		var id1 = views.view1 + this.image_postfix + img_nr;
		var prev_img_2 = config_manager.getPrevPage();
		if (view_manager.current_view == view_manager.views.imageimage) 
		{
			img_nr += 1;
			prev_img_2 += 1;
		}
		var id2 = views.view2 + this.image_postfix + img_nr;

		// check ob bild schon gespeichert wurde
		if($(id1) == null || $(id2) == null)
			return false;
		// check ob bild pfad sauber ist
		var error = false;
		if($(id1).src && $(id1).src.indexOf('undefined') > 0)
		{
			$(id1).remove();
			error = true;
		}
		
		if ($(id2).src && $(id2).src.indexOf('undefined') > 0)
		{
			$(id2).remove();
			error = true;
		}
		
		if(error) return false;
		
		// vorigen stand speichern
		var views = view_manager.splitCurrentView();	
		this.saveImage(config_manager.getPrevPage(), views.view1);
		this.saveImage(prev_img_2, views.view2);
		
		// aktuelle seite laden
		$('image_1').update($(id1));
		$('image_2').update($(id2));
		
		// ok bilder geladen, nicht neu laden
		return true;
	},
	
	/**
	 * checkLoadingStatus
	 * ladestatus eines bildes prï¿½fen
	 * @param img_nr int img/page nummer
	 * @return geladen: geladen oder bereits geladen: load_manager.loading 
	 * 						=> muss nicht mehr geladen werden
	 * 					noch nicht geladen: load_manager.ok 
	 * 						=> muss geladen werden
	 */
	checkLoadingStatus: function(img_nr)
	{
		var img_nr_offset = 0;
		if(config_manager.isDown() && img_nr < config_manager.page_count)
		{
			img_nr_offset = 1;
		}
		else if(config_manager.isUp() && img_nr > 1)
		{
			img_nr_offset = -1;
		}
		if(	(this.isLoading(img_nr) || this.isLoaded(img_nr))
			 && (this.isLoading(img_nr+img_nr_offset) || this.isLoaded(img_nr+img_nr_offset)))
			return this.loading;
		
		return this.ok;
		
	}
};

/*
This script is copyright (c) 2006 Elliot Swan under the
Creative Commons Attribution-ShareAlike 2.5 license:
http://creativecommons.org/licenses/by-sa/2.5/

More information on this script can be found at:
http://www.elliotswan.com/2006/04/12/move-and-copy/
*/

var viewer_Move =	
{
	copy:   function(e, target)	
	{
		var eId      = $(e);
		var copyE    = eId.cloneNode(true);
		var cLength  = copyE.childNodes.length -1;
		for(var i = 0; cLength >= i;  i++)	
		{
			if(copyE.childNodes[i].id) 
			{
				var cNode   = copyE.childNodes[i];
				var firstId = cNode.id;
			}
		}
		$(target).appendChild(copyE);
	},
	
	element:  function(e, target, type)	
	{
		var eId =  $(e);
		if(type == 'move') 
		{
			$(target).appendChild(eId);
		}
	
		else if(type == 'copy')	
		{
			this.copy(e, target);
		}
	}
}

var menu_manager =
{
	menuitem_class: '.viewer_menu_item',
	menucontainers:
	[
		'viewer_leftmenu_menu_container',	
		'viewer_usermenu_menu_container',
		'viewer_contents_menu_container'
	],

	contents_id: 'viewer_contents_div',
	leftmenu_id: 'viewer_leftmenu_div',
	usermenu_id: 'viewer_usermenu_div',

	menu_content_ids:
	[
		'viewer_contents_div',
		'viewer_leftmenu_div',
		'viewer_usermenu_div'
	],
	
	usermenu_data_id: 'viewer_usermenu_data',
	/**
	 * onclick window
	 * @param {Object} event mouseklick
	 */
	hideMenu: function(event)
	{
		if(!this.hasVisibleMenus())
			return;
		var element = Event.element(event);
		var p = this.menucontainers.find(function(e)
		{
			var x = getAncestorById(element, e); 
			if(x)
				return x;
			return false;
		});
		
		if(p)
			return;
	
		$$(this.menuitem_class).invoke('hide');
	},
	
	hasVisibleMenus: function()
	{
		return this.menu_content_ids.find(function(e)
		{
			if($(e))
				return $(e).getStyle('display') == 'block';	
		});
	},
	
	toggleContents: function()
	{
		$(this.contents_id).toggle();
		if($(this.usermenu_id))
			$(this.usermenu_id).hide();
		$(this.leftmenu_id).hide();
	},

	toggleLeftmenu: function()
	{
		$(this.leftmenu_id).toggle();
		if($(this.usermenu_id))
			$(this.usermenu_id).hide();
		$(this.contents_id).hide();
	},

	toggleUsermenu: function()
	{
		console.log('A');
		if ($(this.usermenu_id)) 
		{
			if (!$(this.usermenu_id).visible()) 
				this.loadContents();
			$(this.usermenu_id).toggle();
		}
		$(this.leftmenu_id).hide();
		$(this.contents_id).hide();
	},
	
	loadContents: function(tag_id)
	{
		var url = config_manager.root_url + 'useractions/annotation/' + config_manager.current_book_id + '/';

		if(tag_id)
		{
			url += tag_id + '/';
		}

		new Ajax.Updater(this.usermenu_data_id, url,
						{
							method: 'get'
						});
	},
	
	init: function()
	{
		Event.observe(window, 'click', menu_manager.hideMenu.bindAsEventListener(menu_manager));
	}
}
/**
 * @requires config_manager, drag_manager, load_manager
*/
var view_manager = 
{
	/**
	 * sets view
	 * @param {Object} view this.views.single_page || .this.views.double_page || view == this.views.matrix_page
	 * 						default: this.views.single_page
	 */
	
	view_prefix:'viewer_',
	current_view: '',
	current_view_splitted: {},
	
	views:
	{
		image:'image',
		text:'text',
		xml:'xml',
		imageimage:'imageimage',
		imagetext:'imagetext',
		imagexml: 'imagexml',
		textxml:'textxml',
		thumbs:'thumbs'
	},

	contents_button_id: 'viewer_contents',
	contents_id: 'viewer_contents_div',
	contents_visible: false,
		
	leftmenu_button_id: 'viewer_leftmenu',
	leftmenu_id: 'viewer_leftmenu_div',
	leftmenu_visible: false,

	usermenu_button_id: 'viewer_usermenu',
	usermenu_id: 'viewer_usermenu_div',
	usermenu_visible: false,

	thumbs_overlay_menu_id: 'thumbs_overlay_links',
	
	thumbsOverlayMenu_in: function(e)
	{
		if(!$(this.thumbs_overlay_menu_id)) 
			return;
		var top = Event.element(e).viewportOffset()[1] + Event.element(e).getHeight() - 100;
		var left = Event.element(e).viewportOffset()[0];
		$(this.thumbs_overlay_menu_id).setStyle({top: top + 'px', left: left + 'px'});
		$(this.thumbs_overlay_menu_id).show();	
	},
	
	thumbsOverlayMenu_out: function(e)
	{
		$(this.thumbs_overlay_menu_id).hide();
	},
	
	toggleContents: function()
	{
		$(this.contents_id).toggle();
		this.contents_visible = !this.contents_visible; 
	},

	toggleLeftmenu: function()
	{
		$(this.leftmenu_id).toggle();
		this.leftmenu_visible = !this.leftmenu_visible; 
	},

	toggleUsermenu: function()
	{
		$(this.usermenu_id).toggle();
		this.usermenu_visible = !this.usermenu_visible; 
	},

	splitCurrentView: function()
	{
		return this.current_view_splitted;
	},
	
	/**
	 * ansicht wechseln
	 * @param {Object} view => view_manager.views
	 * wichtig: $(this.view_prefix + view).readAttribute('link');
	 * attribut 'link' nicht vergessen
	 */
	switchView: function(view)
	{
		var url = $(this.view_prefix + view).readAttribute('link');
		url += config_manager.current_resolution + '/';
		url += config_manager.getCurrentPage() + '/';

		document.location.href = url;
	},

	/**
	 * check ob einzelansicht
	 */
	isSingleView: function()
	{
		return 	this.current_view == this.views.image || 
				this.current_view == this.views.text || 
				this.current_view == this.views.xml; 
	
	},

	/**
	 * check ob doppelansicht
	 */
	isDoubleView: function()
	{
		return 	this.current_view == this.views.imageimage || 
				this.current_view == this.views.imagetext || 
				this.current_view == this.views.imagexml ||
				this.current_view == this.views.textxml; 
	
	},
	
	/**
	 * onclick window
	 * @param {Object} event mouseklick
	 */
	hideMenu: function(event)
	{
		var element = Event.element(e);
		if (element.id != this.contents_button_id &&
			element.id != this.contents_id &&
			!getAncestorById(element, this.contents_id)) 
		{
			$(this.contents_id).hide();
		}
		else if (element.id != this.usermenu_button_id &&
			element.id != this.usermenu_id &&
			!getAncestorById(element, this.usermenu_id)) 
		{
			$(this.usermenu_id).hide();
		}
	},
	
	setCurrentView: function(view)
	{
		this.current_view = view;
		if(this.current_view == this.views.imageimage)
			this.current_view_splitted = {view1: this.views.image, view2:this.views.image};	
		if(this.current_view == this.views.imagetext)
			this.current_view_splitted = {view1:this.views.image, view2:this.views.text};	
		if(this.current_view == this.views.imagexml)
			this.current_view_splitted = {view1:this.views.image, view2:this.views.xml};	
		if(this.current_view == this.views.textxml)
			this.current_view_splitted = {view1:this.views.text, view2:this.views.xml};	
	},
	/**
	 * init();
	 */
	init: function(view)
	{
		var hide_items_class = '.hide_view_' + view;
//		$$(hide_items_class).invoke('hide');
		$$(hide_items_class).each(function(e){e.hide();});
		
		this.setCurrentView(view);
		$(config_manager.constants.scroll_div_id).scrollTop = 0;
		// singleview
		if (this.isSingleView())
		{
			$(config_manager.constants.images_container_div_id).scrollTop = 0;
			Event.observe($(config_manager.constants.scroll_div_id), 'scroll', image_load_manager.nextImage.bindAsEventListener(image_load_manager));
		}
		// doubleview
		else if (this.isDoubleView())
		{
			if (this.current_view == this.views.textxml) 
			{
				Event.observe('image_1', 'mouseout', drag_manager.enableDrag.bindAsEventListener(drag_manager));
				Event.observe('image_1', 'mouseover', drag_manager.disableDrag.bindAsEventListener(drag_manager));
				Event.observe('image_2', 'mouseout', drag_manager.enableDrag.bindAsEventListener(drag_manager));
				Event.observe('image_2', 'mouseover', drag_manager.disableDrag.bindAsEventListener(drag_manager));
			}
			else if (this.current_view == this.views.imagetext || this.current_view == this.views.imagexml) 
			{
				Event.observe('image_2', 'mouseout', drag_manager.enableDrag.bindAsEventListener(drag_manager));
				Event.observe('image_2', 'mouseover', drag_manager.disableDrag.bindAsEventListener(drag_manager));
			}
		}
		else if (view == 'thumbs')
		{
		}
	}
}

// scroll manuell mit mausrad, wegen mousemove layer
// damit kommt kein scrollwheel => layer
function handle(delta) 
{
	$('images').scrollTop += delta * (-40);
}

function wheel(event)
{
	var delta = 0;
	if (!event) event = window.event;
	if (event.wheelDelta) {
		delta = event.wheelDelta/120; 
		if (window.opera) delta = -delta;
	} else if (event.detail) {
		delta = -event.detail/3;
	}
	if (delta)
		handle(delta);
        if (event.preventDefault)
                event.preventDefault();
        event.returnValue = false;
}

var crop_manager =
{
	cropper : null,
	grab : 'grab',
	cut : 'cut',
	active : 'grab',
	crop_on_page : 0,
	window: null,
	crop_icon: 'viewer_crop_icon',
	
	cursor_class_grab: 'cursor_hand',
	cursor_class_cut: 'cursor_crosshair',
	
	toggle : function()
	{
		$(drag_manager.handle).select('div.'+this.cursor_class_grab).each(function(e)
		{
			e.toggleClassName(crop_manager.cursor_class_cut);
		});
		
		if (this.active == this.grab) 
		{
			this.active = this.cut;
			$(this.crop_icon).setOpacity(1);
			
		}
		else 
		{
			this.active = this.grab;
			$(this.crop_icon).setOpacity(0.5);
			this.remove();
		}
	},
	
	remove: function()
	{
		if(this.cropper)
		{
			this.cropper.remove();
			$('viewer_image_crop_container').hide();
		}
	},

	/**
	 * startet das cropping
	 * @param {Object} e mouseklick event
	 */
	cropImage : function(e)
	{
// nicht mehr benoetigt
//		imageFromYPos(Event.pointerY(e));
		this.remove();
		if(this.active == this.grab || !Event.isLeftClick(e))
			return;
			
		var img = Event.element(e);
		if(view_manager.isSingleView())
			this.crop_on_page = parseInt(img.id.replace('img_div_image', ''));
		else
			this.crop_on_page = parseInt(img.id.replace('image_image', ''));
			
		if(!Object.isNumber(this.crop_on_page))
			return;
			
		this.cropper = new Cropper.Img(
				img,
				{
					captureKeys: false,
					minWidth: 20,
					minHeight: 20,
					onEndCrop: crop_manager.onEndCrop.bindAsEventListener(crop_manager)
				}
		);
		this.cropper.startDrag(e);
	},
	
	// dimensions None ??
	onEndCrop : function( coords, dimensions ) 
	{
//		this.remove();
		c = Object.toJSON(coords);

		params = 'coords='+c+'&book='+config_manager.current_book_id+'&page_num='+this.crop_on_page+'&resolution='+config_manager.current_resolution;
		
		annotation_manager.updateAddForm();
		$('viewer_image_crop_container').show();
	},
	
	init : function()
	{
		$(this.crop_icon).setOpacity(0.5);
	}
}

var toggle_icon_manager = 
{
	disabled_icon_path: 'img/beige/',
	enabled_icon_path: 'img/green/',
	
	makeIconPath: function(enabled, icon)
	{
		var path = config_manager.media_url;
		path += (enabled ? this.enabled_icon_path : this.disabled_icon_path);
		path += icon
		return path;
	}
}

/**
 * alle zoom funktionen + konstanten (id's, icons, etc)
 * 
 */
var zoom_manager = 
{
	/**
	 * min-max zoom
	 */
	min_zoom: 10,
	max_zoom: 100,
	default_zoom: 40,
	
	resolution_font_size:
	{
		10: '60%',
		20: '80%',
		30: '100%',
		40: '120%',
		50: '140%',
		60: '160%',
		70: '180%',
		80: '200%',
		90: '220%',
		100: '240%'
	},
	
	/**
	 * icons + id's
	 */
	zoom_in_icon_id: 'viewer_zoom_in_icon',
	zoom_out_icon_id: 'viewer_zoom_out_icon',
	zoom_default_icon_id: 'viewer_zoom_default_icon',
	
	icon_zoom_in: 'zoom-in.gif',
	icon_zoom_out: 'zoom-out.gif',
	icon_zoom_default: 'news.gif',

	grow_icon_id: 'viewer_grow_icon',
	icon_grow: 'grow.gif',
	icon_grow_small: 'grow_small.gif',


	current_grow_status: false,
	
	containers: {},

	/**
	 * vergroessern
	 */
	zoomIn: function()
	{
		if(config_manager.current_resolution == this.max_zoom)
			return;
			
		config_manager.current_resolution += 10;
		view_manager.switchView(view_manager.current_view);
	},
	
	/**
	 * verkleinern
	 */
	zoomOut: function()
	{
		if(config_manager.current_resolution == this.min_zoom)
			return;		
		
		config_manager.current_resolution -= 10;
		view_manager.switchView(view_manager.current_view);
	},
	
	zoomDefault: function()
	{
		if(config_manager.current_resolution == this.default_zoom)
			return;		
			
		config_manager.current_resolution = this.default_zoom;
		view_manager.switchView(view_manager.current_view);
	},
	
	setFontSize: function(element)
	{
		element.setStyle({fontSize: this.resolution_font_size[config_manager.current_resolution]});
	},
		
	/**
	 * vollbild
	 */
	grow: function()
	{
		if(!this.current_grow_status)
		{
			$(this.grow_icon_id).src = toggle_icon_manager.makeIconPath(true, this.icon_grow_small);
			this.toggleContainer(false);
		}
		else
		{
			$(this.grow_icon_id).src = toggle_icon_manager.makeIconPath(true, this.icon_grow);
			this.toggleContainer(true);
		}
		
		page_turn_manager.initScrollbuttonsbars();
		
		this.current_grow_status = !this.current_grow_status;
		$$('div.viewer_toolbar').each(function(e)
		{
			e.toggle();
			
		});
		
	},

	/**
	 * elemente ein/ausblenden fuer vollbild
	 * @param bool collapse
	 */	
	toggleContainer: function(collapse)
	{
		for(i in this.containers)
		{
			if(collapse)
				var styles = this.containers[i].small;
			else
				var styles = this.containers[i].big;

			if($(this.containers[i].id))
				$(this.containers[i].id).setStyle(styles);
		}
	},
	
	/**
	 * koordinaten der sichtbaren elemente bei voll/normalansicht
	 * (big/small)
	 */
	initContainers: function()
	{
		this.containers['0'] = 
		{
			id: 'container',
			big:
			{
				top: '36px',
				left: '0'
			},
			small:
			{
				top: $(config_manager.constants.scroll_div_id).getStyle('top'),
				left: $(config_manager.constants.scroll_div_id).getStyle('left')	
			}			
		};
		this.containers['1'] = 
		{
			id: 'engine_header',
			big:
			{
				marginLeft: 0				
			},
			small:
			{
				marginLeft: $(config_manager.constants.scroll_div_id).getStyle('left')
			}
		};
		this.containers['2'] = 
		{
			id: page_turn_manager.bar_top_id,
			big:
			{
				left: 0,
				marginTop: '36px',
				top: 0
			},
			small:
			{
				left: $(config_manager.constants.scroll_div_id).getStyle('left'),
				marginTop: 0,
				top: (parseInt($(config_manager.constants.scroll_div_id).getStyle('top')) +1)+ 'px'
			}
		};
		this.containers['3'] = 
		{
			id: page_turn_manager.bar_bottom_id,
			big:
			{
				left: 0
			},
			small:
			{
				left: $(config_manager.constants.scroll_div_id).getStyle('left')
			}
		};
	},

	/**
	 * init
	 */
	init: function()
	{
		this.initContainers();
		this.toggleContainer(true);
		
		this.initReader();
		
		if(view_manager.isSingleView())
		{
			$('images').setStyle({
				width: '' + config_manager.current_resolution + '%'
			})
		}
		else
		if(view_manager.isDoubleView())
		{
			this.setFontSize($(load_manager.page_2_container_id));
			if(view_manager.current_view == view_manager.views.textxml)
			{
				this.setFontSize($(load_manager.page_1_container_id));
			}
		}
	},
	
	initReader: function()
	{
		if(config_manager.current_resolution == this.max_zoom)
		{
			$(this.zoom_in_icon_id).src = toggle_icon_manager.makeIconPath(false, this.icon_zoom_in) 	
		}
		else if(config_manager.current_resolution == this.min_zoom)
		{
			$(this.zoom_out_icon_id).src = toggle_icon_manager.makeIconPath(false, this.icon_zoom_out)
		}
		else if(config_manager.current_resolution == this.default_zoom)
		{
			$(this.zoom_default_icon_id).src = toggle_icon_manager.makeIconPath(false, this.icon_zoom_default)
		}
		else
		{
			$(this.zoom_in_icon_id).src = toggle_icon_manager.makeIconPath(true, this.icon_zoom_in)
			$(this.zoom_out_icon_id).src = toggle_icon_manager.makeIconPath(true, this.icon_zoom_out)
		}
	}
}

var image_load_manager =
{
	single_page_request: null,
	
	calcImageNumberFromScrollPos: function()
	{
		if(!$(config_manager.constants.images_container_div_id))
			return NaN;
		var scrollpos = $(config_manager.constants.scroll_div_id).scrollTop;
		var scroll_direction = config_manager.setScrollDir(scrollpos);

		var current_page = $(config_manager.constants.images_container_div_id).childElements().find(
		function(element)
		{

			if(Prototype.Browser.Opera)
				return element.viewportOffset()[1] - 167 >= scrollpos - config_manager.constants.page_wrap;
			else
				return element.viewportOffset()[1] + (element.getHeight() - config_manager.constants.page_wrap) > 0;
		});
		
		var img = parseInt(current_page.id.substring(9, 20));
		

		// img darf nicht auuserhalb der grenzen sein			
		if(img > config_manager.page_count)
			img = config_manager.page_count;
		else if(img < config_manager.constants.page_min)
			img = config_manager.constants.page_min;

		config_manager.setCurrentPage(img);
		
		return img;
	},
	
	/**
	 * bilder nachladen
	 * @param {Object} e scroll event
	 */
	nextImage_image: function(e)
	{
		var img_number = this.calcImageNumberFromScrollPos();
		if (load_manager.checkLoadingStatus(img_number) == load_manager.loading) 
			return;
		this.single_page_request = new Ajax.Request(config_manager.request_url, 
									{ 	method: 'get', 
										onComplete: image_load_manager.imageRequestLoaded_image.bindAsEventListener(image_load_manager), 								
										parameters: { book: config_manager.current_book_id, img_number: img_number, view: 'image' }
									}
								);
	},
	
	/**
	 * text/xml nachladen
	 * @param {Object} e scroll event
	 */
	nextImage_text_xml: function(e)
	{
		var img_number = this.calcImageNumberFromScrollPos();
		if (load_manager.checkLoadingStatus(img_number) == load_manager.loading) 
			return;
		load_manager.setLoading(img_number);
		
		for(var item in load_manager.currently_loading)
		{
			if(load_manager.currently_loading[item] == false) continue;
			new Ajax.Updater(config_manager.getImgDivId(item), config_manager.request_url, 
									{ 	method: 'get', 
										parameters: { book: config_manager.current_book_id, img_number: item },
										onSuccess: function(r)
										{
											
										}
									});
			load_manager.finishedLoading(item);
		}		
	},

	/**
	 * bilder nachladen (doppelansicht)
	 */
	nextImage_imageimage: function()
	{
		load_manager.saveImage(config_manager.getPrevPage()+1, views.view1);
		// schon geladen? dann laden, wenns geht...
		if(load_manager.isLoaded(img_number) && load_manager.loadDoubleContent(img_number))
			return;	
		
		var img_number = config_manager.getCurrentPage();
		this.single_page_request = new Ajax.Request(config_manager.request_url, 
					{ 	method: 'get', 
						onComplete: image_load_manager.imageRequestLoaded_imageimage.bindAsEventListener(image_load_manager), 								
						parameters: { book: config_manager.current_book_id, img_number: img_number, view: 'image' }
					}
				);
	},

	/**
	 * bilde/text und bild/xml nachladen (doppelansicht)
	 */
	nextImage_imagetext_imagexml_textxml: function(e)
	{
		
	},

	/**
	 * text/xml nachladen (doppelansicht)
	 */
	nextImage_imagetext_textxml: function(e)
	{
		
	},
	
	loadImage_1: function()
	{
		new Ajax.Updater('image_1', config_manager.request_url, 
		{
			method: 'get',
			parameters: 
			{
				book: config_manager.current_book_id,
				img_number: img_number,
				view: views.view1
			},
			onComplete: image_load_manager.imageRequestLoaded_textxml.bindAsEventListener(image_load_manager)
		});
	
	},

	loadImage_2: function()
	{
		// image_2 => nie bild
		new Ajax.Updater('image_2', config_manager.request_url, 
		{
			method: 'get',
			parameters: 
			{
				book: config_manager.current_book_id,
				img_number: img_number,
				view: views.view2
			}
		});		
	},

	nextImage: function(e)
	{
		var img_number = 0;
		// callback fuer bild laden request
		var imageRequestLoaded_cbFunc = null;
		var singleview = view_manager.isSingleView();
		
		if (view_manager.current_view == view_manager.views.image)
		{
			img_number = this.calcImageNumberFromScrollPos();
			if (load_manager.checkLoadingStatus(img_number) == load_manager.loading) 
				return;
			imageRequestLoaded_cbFunc = image_load_manager.imageRequestLoaded_image.bindAsEventListener(image_load_manager);
		}
		else if (singleview)
		{
			if(config_manager.scrollInfo.fast_scroll) return;
			img_number = this.calcImageNumberFromScrollPos();
			if (load_manager.checkLoadingStatus(img_number) == load_manager.loading) 
				return;
			load_manager.setLoading(img_number);
			
			for(var item in load_manager.currently_loading)
			{
				
				if(load_manager.currently_loading[item] == false) continue;
				var element_id = config_manager.getImgDivId(item);
				new Ajax.Updater(element_id, config_manager.request_url, 
										{ 	method: 'get', 
											parameters: { book: config_manager.current_book_id, img_number: item, view: view_manager.current_view },
											onSuccess: function(r)
											{
												
											}
										});
				zoom_manager.setFontSize($(element_id));
				load_manager.finishedLoading(item);
			}		
			return;
		}
		else if (view_manager.isDoubleView())
		{
			img_number = config_manager.getCurrentPage();
			$(config_manager.constants.scroll_div_id).scrollTop = 0;
			// zb. views = { view1:'image', view2:'image'}
			var views = view_manager.splitCurrentView();
			load_manager.saveImage(config_manager.getPrevPage(), views.view1);
	
			if (view_manager.current_view == view_manager.views.imageimage) 
			{
				load_manager.saveImage(config_manager.getPrevPage()+1, views.view1);
				// schon geladen? dann laden, wenns geht...
				if(load_manager.isLoaded(img_number) && load_manager.loadDoubleContent(img_number))
					return;	
				
				// ... sonst holen
				img_number = config_manager.getCurrentPage();
				imageRequestLoaded_cbFunc = image_load_manager.imageRequestLoaded_imageimage.bindAsEventListener(image_load_manager);
			}
			else 
			{
				if(load_manager.loadDoubleContent(img_number))
					return;
				// image_2 => nie bild
				new Ajax.Updater('image_2', config_manager.request_url, 
				{
					method: 'get',
					parameters: 
					{
						book: config_manager.current_book_id,
						img_number: img_number,
						view: views.view2
					}
				});
				// image_1 auch kein bild?
				if (view_manager.current_view == view_manager.views.textxml) 
				{
					new Ajax.Updater('image_1', config_manager.request_url, 
					{
						method: 'get',
						parameters: 
						{
							book: config_manager.current_book_id,
							img_number: img_number,
							view: views.view1
						},
						onComplete: image_load_manager.imageRequestLoaded_textxml.bindAsEventListener(image_load_manager)
					});
					return;
				}
				// sonst bild
				else 
				{
					imageRequestLoaded_cbFunc = image_load_manager.imageRequestLoaded_image_plus_x.bindAsEventListener(image_load_manager);
				}
			}
		}
		
	
		crop_manager.remove();
		load_manager.setLoading(img_number);
		
//		if(this.single_page_request)
//		{
//			this.single_page_request.transport.abort();
//		}
		this.single_page_request = new Ajax.Request(config_manager.request_url, 
									{ 	method: 'get', 
										onComplete: imageRequestLoaded_cbFunc, 								
										parameters: { book: config_manager.current_book_id, img_number: img_number, view: 'image' }
									}
								);
							
		
	},
	
	//laedt ein bild
	//	img_name:	pfad zum bild (http://localhost/django/loader/media/img/img_a4.JPG)
	//	img_number:	nummer des bildes bzw. div-tags, in den das bild geladen werden soll
	// laedt ein bild
	//	img_name:	pfad zum bild (http://localhost/django/loader/media/img/img_a4.JPG)
	//	img_number:	nummer des bildes bzw. div-tags, in den das bild geladen werden soll
	loadImage: function(img_src, img_div, img_nr, img_tag_id)
	{
		load_manager.displayLoading(true);
		if(img_tag_id != undefined)
			var img_id = img_tag_id + img_nr;
		else
			var img_id = 'img_' + img_div;
			
//		$(img_div).update('<img id = "'+ img_id+'" class="cursor_crosshair" src="'+ img_src +'" />');
//		loading(false);
		
		var theImage = new Image();
		theImage.id = img_id;
		
		// laed schneller
		if (view_manager.isSingleView()) 
		{
			theImage.height = $(img_div).getHeight();
			theImage.width = $(img_div).getWidth();
		}
		theImage.onload = function () 
		{
			Event.observe(img_id, 'mousedown', crop_manager.cropImage.bindAsEventListener(crop_manager));
			$(img_div).addClassName("cursor_hand");
			load_manager.displayLoading(false);
			return true;
		}
	
		theImage.src = img_src;
		if($(img_div))
			$(img_div).update(theImage);
	},
	
	imageFromYPos: function(ypos)
	{
		var current_page = $(config_manager.constants.images_container_div_id).childElements().find(
		function(element)
		{
			return 	element.viewportOffset()[1] + (element.getHeight()) > ypos && 
					element.viewportOffset()[1] + (element.getHeight()) < ypos + element.getHeight();
		});
		
		return current_page == "undefined" ? null : current_page;
	},
		// callback fuer ajax onComplete - mehrere bilder im response
	//	erwartet in response.responseJSON:
	//	{
	//		images:
	//			{
	//				img_div_number: http://localhost/django/loader/media/img/img_a1.JPG,
	//				img_div_number: http://localhost/django/loader/media/img/img_a2.JPG,
	//				...
	//			}
	//	}
	
	imageRequestLoaded_image: function(response)
	{
		for (var i in response.responseJSON.images)
		{
			this.loadImage(response.responseJSON.images[i], config_manager.getImgDivId(i), i);
			load_manager.finishedLoading(i);
		}
	},
	
	imageRequestLoaded_imageimage: function(response)
	{
		var img1 = response.responseJSON.images[config_manager.getCurrentPage()];
		var img2 = response.responseJSON.images[config_manager.getCurrentPage()+1];
			
		this.loadImage(img1, 'image_1', config_manager.getCurrentPage(), 'image_image');
		this.loadImage(img2, 'image_2', config_manager.getCurrentPage()+1, 'image_image');
		
		load_manager.finishedLoading(config_manager.getCurrentPage());
		load_manager.finishedLoading(config_manager.getCurrentPage()+1);
	
		var views = view_manager.splitCurrentView();	
		load_manager.saveImage(config_manager.getCurrentPage(), views.view1);
		load_manager.saveImage(config_manager.getCurrentPage()+1, views.view2);
	},
	
	imageRequestLoaded_textxml: function(response)
	{
		var views = view_manager.splitCurrentView();	
		load_manager.saveImage(config_manager.getCurrentPage(), views.view1);
		load_manager.saveImage(config_manager.getCurrentPage(), views.view2);
	},
	
	imageRequestLoaded_image_plus_x: function (response)
	{
		var img1 = response.responseJSON.images[config_manager.getCurrentPage()];
		this.loadImage(img1, 'image_1', config_manager.getCurrentPage(), 'image_image');
		load_manager.finishedLoading(config_manager.getCurrentPage());
		
		var views = view_manager.splitCurrentView();	
		load_manager.saveImage(config_manager.getCurrentPage(), views.view1);
		load_manager.saveImage(config_manager.getCurrentPage(), views.view2);
	}
}

var annotation_manager = 
{
	add_url: 'useractions/annotation/add/',
	edit_url: 'useractions/annotation/edit/',
	delete_url: 'useractions/annotation/delete/',
	
	add_div_id: 'viewer_annotation_add_container',
	edit_div_id: 'viewer_annotation_edit_container',
	
	filter_menu_buttons_id: 'viewer_user_annotation_image_tag',
	filter_menu_buttons_selected_class: 'viewer_selected',
	
	current_filter_id: 0,
	
	filter: function(tag_id)
	{
		this.current_filter_id = tag_id;
		menu_manager.loadContents(tag_id);
		$(menu_manager.usermenu_data_id).select('.viewer_selected').invoke('removeClassName', 'viewer_selected');
		$(this.filter_menu_buttons_id + tag_id).addClassName(this.filter_menu_buttons_selected_class);
	},
	
	addNew: function(link)
	{
		url = config_manager.root_url + this.add_url;
		new Ajax.Updater(this.add_div_id, url,
						{ 	
							method: 'get', 
							parameters: { link: link, bookid: config_manager.current_book_id, pagenum: config_manager.current_page  }
						});
		$(this.add_div_id).show();
	},
	
	save: function(form)
	{
		$(form).request({ onSuccess: function(response) { menu_manager.loadContents();}});
		crop_manager.remove();
		$(form).reset();
	},
	
	editAnnotation: function(annotation_id)
	{
		url = config_manager.root_url + this.edit_url + annotation_id + '/';
		div_id = this.edit_div_id + annotation_id; 
		new Ajax.Updater(div_id, url,
						{ 	
							method: 'get', 
							onSuccess: function(response)
							{
								$(div_id).show();
							}
						});
	},
	
	deleteAnnotation: function(annotation_id, commit)
	{
		url = config_manager.root_url + this.delete_url + annotation_id + '/';
		var update_element = this.edit_div_id + annotation_id;
		if (commit) 
		{
			new Ajax.Updater(update_element, url,
							{ 	
								method: 'post', 
								onSuccess: function(response)
								{
									menu_manager.loadContents(annotation_manager.current_filter_id);
								}
							});
		}
		else 
		{
			new Ajax.Updater(update_element, url,
							{ 	
								method: 'get', 
								onSuccess: function(response)
								{
									$(update_element).show();
								}
							});
		}
	},
	
	cancelDelete: function(annotation_id)
	{
		$(this.edit_div_id + annotation_id).hide();
	},

	makeLink: function()
	{
		var url = config_manager.root_url + 'image_crop/image/'
		url += '?coords=' + Object.toJSON(crop_manager.cropper.areaCoords);
		url += '&book=' + config_manager.current_book_id
		url += '&page_num=' + config_manager.getCurrentPage();
		url += '&resolution=' + config_manager.current_resolution;
		return url;
	},
	
	updateAddForm: function()
	{
		var link = this.makeLink();
		$('input_link').value = link; 
		$('input_link_ref').value = "<a href = '" + link + "'>" + config_manager.book_author + ", " + config_manager.book_title + ", Seite " + config_manager.getCurrentPage() + "</a>";
		
		if ($('id_link')) 
		{
			$('id_link').value = link;
		}
	},
	
	hideEdit: function(annotation_id)
	{
		$('viewer_annotation_edit_container'+annotation_id).hide();
	},
	
	hideAdd: function()
	{
		$('viewer_annotation_add_container').hide();
	},

	init: function()
	{
	}
}

var bookmark_manager = 
{
	addBookmark: function()
	{
		
	},
	
	init: function()
	{
		
	}
}

function toggleLayer(id, effect)
{
	if(!$(id))
		return;
	if(!effect)
		effect = 'slide';
	
	$(id).toggle();
	//Effect.toggle($(id), effect, {duration:0.6});
}

/**
 *
 * 	berechnet die nummer des zu ladenden bildes anhand der scrollpos
 *	ermittelt ausserdem die scrollrichtung und speichert diese in config_manager
 */

// funktion, die onScroll aufgerufen wird - fuer mehrere bilder


function getKeynum(e)
{
	var keynum;
	if(window.event) // IE
	{
		keynum = e.keyCode;
	}
	else if(e.which) // Netscape/Firefox/Opera
	{
		keynum = e.which;
	}
	return keynum;
}

// eventhandler fuer keyDown mesages
// behandelt pgUp, pgDown, Pos1, End, pfeil hoch, pfeil runter
function keyDown(e)
{
	switch(getKeynum(e))
	{
		case Event.KEY_ESC:
			crop_manager.remove();
			break;
		case Event.KEY_RETURN:
			page_turn_manager.gotoPage();
			break;
		case Event.KEY_UP:
			scrollIt(-config_manager.constants.arrowUpDown_scroll_amount);
			break;
		case Event.KEY_DOWN:
			scrollIt(config_manager.constants.arrowUpDown_scroll_amount);
			break;
		case Event.KEY_HOME:
//			scrollIt(config_manager.constants.scrollDirections.up);
			break;
		case Event.KEY_END:
//			scrollIt(config_manager.constants.scrollDirections.down);
			break;
		case Event.KEY_PAGEUP:
			page_turn_manager.prevPage();
			break;
		case Event.KEY_PAGEDOWN:
			page_turn_manager.nextPage();
			break;
		//ctrl
		case 17:
			break;
		default:
			break;
	}	
}

function keyUp(e)
{
	switch (getKeynum(e))
	{
		//ctrl => cursor action
		case 17:
			break;
		default:
			break;
	}
}

function mouseDown(e)
{	
	crop_manager.remove();
}
// scrollt um amount_to_add
// ganz nach oben:
// amount_to_add == config_manager.constants.scrollDirections.up ==> scrollpos = 0
// ganz nach unten:
// amount_to_add == config_manager.constants.scrollDirections.down ==> scrollpos = max
function scrollIt(amount_to_add)
{
	var element = document.getElementById(config_manager.constants.images_container_div_id);
	
	if(amount_to_add == config_manager.constants.scrollDirections.up)
	{
		element.scrollTop = 0;
	}
	else if(amount_to_add == config_manager.constants.scrollDirections.down)
	{
		element.scrollTop = 99999999;
	}
	else
	{
		element.scrollTop += parseInt(amount_to_add);
	}
}

function getAncestorById(element, ancestor_id)
{
	if (element) 
	{
		var e = element.ancestors().find(function(e)
		{
			return e.id == ancestor_id;
		})
		if (e) 
			return e;
	}
	return false;	
}

function getAncestorByClassName(element, ancestor_class)
{
	var e = element.ancestors().find(function(e)
				{
					return e.hasClassName(ancestor_class);
				}
	)
	if(e)
		return e;
	return false;	
}

