
// set Debugging Mode
var DEBUG = false;

String.prototype.trim = function() {
	var str = this;
	return str.replace(/^\s\s*/, '').replace(/\s\s*$/, '');
}

// Class SlideshowController
function SlideshowController() {
	
	this.PLAY = 0;
	this.PAUSE = 1;
	this.REWIND = 2;
	
	var _this = this;
	var interval = 4000;
	var intervalHover = 1000;
	
	var box = null;
	var img = null;
	var imgTemp = null;
	var title1 = null;
	var title2 = null;
	var infoWindow = null;
	
	var data = null;
	var currentIndex = 0;
	var pendingIndexChange = 0;
	
	var slideshowTimer = null;
	var slideshowTimer2 = null;
	var changingImage = false;
	this.mode = this.PAUSE;
	
	var NONE = -2;
	var LEFT = -1;
	var MIDDLE = 0;
	var RIGHT = 1;
	var hovering = NONE;
	
	var htmlBody = document.getElementsByTagName('body')[0];
	
	var imgOffsetLeft = 0;
	var imgOffsetTop = 0;
	
	this.init = function(xmlSrc, boxT, imageT, imageTempT, title1T, title2T, pos) {
		document.preloader = new Array();
		if(boxT == null || imageT == null || title1T == null || title2T == null) { 
			if(DEBUG) alert("At least on element is null");
			return false; 
		}
		if(boxT.tagName.toLowerCase() != 'div') {
			if(DEBUG) alert("Div-Element must be given to SlideshowController, " + box.tagName + " given.");
			return false;
		}
		box = boxT;
		img = imageT;
		img.useMap = '';
		imgTemp = imageTempT;
		imgTemp.style.backgroundRepeat = 'no-repeat';
		title1 = title1T;
		title2 = title2T;
		
		imgOffsetLeft = img.offsetLeft;
		imgOffsetTop = img.offsetTop;
		
		data = new SlideshowModel();
		currentIndex = pos;
		data.init(xmlSrc, this.dataLoaded);
		return true;
	};
	this.dataLoaded = function() {
		if(DEBUG) alert("Data Model loaded and Controller informed.");
		updateImage();
		
		$("img#slideshowImage").click(function(e) { _this.click(e); });
		//$("img#slideshowImage").mousemove(function(e) { _this.mouseover(e); });
		//$("img#slideshowImage").mouseout(function(e) { _this.mouseout(e); });
		
		
		_this.startSlideshow(2500);
	};
	this.startSlideshow = function(customStartInterval) {
		this.pauseSlideshow();
		this.mode = this.PLAY;
		
		if(typeof(customStartInterval) != undefined && customStartInterval > 0) {
			slideshowTimer2 = setTimeout(function() { _this.next(); _this.startSlideshow(); }, customStartInterval);
		} else {
			slideshowTimer = setInterval(function() { _this.next(); }, interval);
		}
	};
	
	this.rewindSlideshow = function() {
		this.mode = this.REWIND;
		clearInterval(slideshowTimer);
		clearTimeout(slideshowTimer2);
		slideshowTimer = setInterval(function() { _this.previous(); }, interval);
	}
	this.pauseSlideshow = function() {
		this.mode = this.PAUSE;
		clearInterval(slideshowTimer);
		clearTimeout(slideshowTimer2);
	};
	this.setInterval = function(intervalT) {
		interval = intervalT;
	};
	this.setInfoWindow = function(window) {
		infoWindow = window;
		//infoWindow.onmouseover = function() { infoWindow.style.display = 'none'; };
		infoWindow.style.left = title1.offsetLeft + img.width - 225;
		infoWindow.style.top = title1.offsetTop;
		infoWindow.style.display = 'block';
	};
	this.next = function(e) {
//		if(DEBUG) alert("Next image.");
		if(changingImage) { 
			pendingIndexChange++; 
		} else {
			currentIndex = (currentIndex + 1) % data.getItemCount();
			updateImage();
		}
	};
	this.previous = function() {
		if(changingImage) { 
			pendingIndexChange--; 
		} else {
			currentIndex = (data.getItemCount() + (currentIndex - 1)) % data.getItemCount(); // assert always >0
			updateImage();
		}
	};
	this.jump = function(i) {
		pendingIndexChange = 0;
		currentIndex = (i) % data.getItemCount();
		updateImage();
	};
	this.first = function() {
		pendingIndexChange = 0;
		currentIndex = 0;
		updateImage();
	};
	this.last = function() {
		pendingIndexChange = 0;
		currentIndex = data.getItemCount();
		updateImage();
	};
	this.click = function(e) {
		if(inLeftArea(e.pageX - imgOffsetLeft)) {
			this.pauseSlideshow();
			this.previous();
		} else if(inRightArea(e.pageX - imgOffsetLeft)) {
			this.pauseSlideshow();
			this.next();
			this.startSlideshow();
		}
	}
	function inLeftArea(x) {
		//if(92 <= x && x < 330) return true;
		if(92 <= x && x < 430) return true;
		//if(x < img.width / 10 * 2) return true;
		return false;
			
	}
	function inRightArea(x) {
		//if(534 < x  && x <= 772) return true;
		if(434 < x  && x <= 772) return true;
		//if (x > (img.width / 10 * 8)) return true;
		return false;
		
	}
	function inMiddleArea(x) {
		if(330 <= x && x <= 534) return true;
		//if(img.width/10 * 2 + 1<= x <= img.width / 10 *8 - 1) return true;
		return false;
	}
	this.mouseover = function(e) {
		imgOffsetLeft = img.offsetLeft;
		imgOffsetTop = img.offsetTop;
		if(infoWindow != null) {
			infoWindow.style.left = (e.pageX-23) + 'px';
			
			infoWindow.style.top = img.offsetTop + img.offsetHeight - 15 + 'px';
			if(typeof(img.y) != 'undefined') {
				infoWindow.style.top = img.y + img.offsetHeight - 15 + 'px';
			}
			imgOffsetLeft = img.offsetLeft;
			
			if(inLeftArea(e.pageX - imgOffsetLeft) || inMiddleArea(e.pageX - imgOffsetLeft) || inRightArea(e.pageX - imgOffsetLeft)) {
				if(infoWindow != null && infoWindow.style.display != 'block') {
					infoWindow.style.display = 'block';
				}

				
				htmlBody.style.cursor = 'url(\'http://www.atelier522.com/image/invisible_cursor.png\'), url(\'http://www.atelier522.com/image/invisible_cursor.cur\'), auto';
			} else if(infoWindow != null){
				infoWindow.style.display = 'none';
				htmlBody.style.cursor = 'default';
			} else {
				htmlBody.style.cursor = 'default';
			}
			
			if(inLeftArea(e.pageX - imgOffsetLeft)) {
				if(hovering != LEFT) {
					clearInterval(slideshowTimer);
					clearTimeout(slideshowTimer2);
					this.previous();
					slideshowTimer2 = setTimeout(function() { _this.rewindSlideshow(); }, 500);
					hovering = LEFT;
				} else {
					//this.rewindSlideshow();
				}
				infoWindow.innerHTML = " ";
				//infoWindow.style.backgroundImage = 'url(\'' + buttonLeft + '\')';
				infoWindow.style.backgroundPosition = '0px 0px';
			} else if(inRightArea(e.pageX - imgOffsetLeft)) {
				if(hovering != RIGHT) {
					clearInterval(slideshowTimer);
					clearTimeout(slideshowTimer2);
					this.next();
					slideshowTimer2 = setTimeout(function() { _this.startSlideshow(); }, 500);
					hovering = RIGHT;
				} else {
					//this.startSlideshow();
				}
				infoWindow.innerHTML = " ";
//				infoWindow.style.background = 'url(\'' + buttonRight + '\')';
				infoWindow.style.backgroundPosition = '0px -130px';
			} else if(inMiddleArea(e.pageX - imgOffsetLeft)) {
				if(hovering != MIDDLE) {
					hovering = MIDDLE;
				}
				this.pauseSlideshow();
				infoWindow.innerHTML = " ";
//				infoWindow.style.backgroundImage = 'url(\'' + buttonMiddle + '\')';
				infoWindow.style.backgroundPosition = '0px -65px';
			}
		}
	}
	this.mouseout = function(e) {
		if(0 < (e.pageY - imgOffsetTop) && (e.pageY - imgOffsetTop) < (img.offsetHeight)) {
			//alert('vertical left: ' + (e.pageY - imgOffsetTop));
			if(inLeftArea(e.pageX - imgOffsetLeft) || inMiddleArea(e.pageX - imgOffsetLeft) || inRightArea(e.pageX - imgOffsetLeft)) {
				// not left the image-area, so do nothing
				return;
			}
		}
		
		
		htmlBody.style.cursor = 'default';
		//alert((e.pageY - imgOffsetTop) + '-' + img.height + '-' + imgOffsetTop + '-' + imgOffsetLeft);
		if(infoWindow != null) {
			infoWindow.style.display = 'none';
			_this.pauseSlideshow();
			slideshowTimer2 = setTimeout(function() { _this.next(); _this.startSlideshow(); }, intervalHover);
		}
		hovering = NONE;
	}
	
	function updateImage() {
		if(DEBUG) alert("Update image.");
		var image = data.getItem(currentIndex);
		if(image.imageSrc != img.src) {
			changingImage = true;
			setTempImage(image);
		}
		
		// preload
		var prev = data.getItem((data.getItemCount() + currentIndex - 1) % data.getItemCount());
		var next = data.getItem((currentIndex + 1) % data.getItemCount());
		document.preloader[0] = new Image();
		document.preloader[0].src = prev.imageSrc;
		document.preloader[1] = new Image();
		document.preloader[1].src = next.imageSrc;
//		if(DEBUG) alert("Preloaded initialized.");
	}
	function setTempImage(image) {
		if(imgTemp.style.backgroundImage != 'url(\'' + img.src + '\')') {
			imgTemp.style.backgroundImage = 'url(\'' + img.src + '\')';
		}
		imgTemp.style.width = img.offsetWidth + 'px';
		imgTemp.style.height = img.offsetHeight +'px';
		
		
		setTimeout(function() { switchForeground(image); }, 150);
	}
	function switchForeground(image) {// todo: de/en/...
		if(DEBUG) alert("Foreground switch. " + img.src + ' - ' + image.imageSrc);
		$("img#slideshowImage").hide();
		var srcTemp = img.src;
		img.src = image.imageSrc;
		//img.title = image.title;
		img.alt = image.title;
		
		setTimeout(function() { switchFadeIn(image); }, 100);
//		img.onload = function() { switchFadeIn(image); }; // no onload-event in ie fired
	}
	function switchFadeIn(image) {
		$("img#slideshowImage").fadeIn(500, function() { switchComplete(image); });
		if(title1.innerHTML != image.title) {
			$("#untertitelText").fadeTo(300, 0.3, function() { switchTitle(image); });
		}
	}
	function switchTitle(image) {
		title1.innerHTML = image.title;
		title2.innerHTML = image.title;
		$("#untertitelText").fadeTo(400, 1.0);
	}
	function switchComplete(image) {
		imgTemp.style.backgroundImage = 'url(\'' + img.src + '\')';
		// todo
		pendingIndexChange = 0; // now toggle-proceeding
		if(pendingIndexChange != 0) {
			pendingIndexChange = pendingIndexChange % 2;
			if(pendingIndexChange > 0) {
				pendingIndexChange--;
				currentIndex = (currentIndex + 1) % data.getItemCount();
				updateImage();
			} else {
				pendingIndexChange++;
				currentIndex = (data.getItemCount() + (currentIndex - 1)) % data.getItemCount(); // assert always >0
				updateImage();
			}
		} else {
			if(DEBUG) alert("Switch finished.");
			changingImage = false;
		}
	}
}


// Class SlideshowModel
// usind jquery.ajax
// mediaRss
function SlideshowModel() {
	var _this = this;
	var items = new Array();
	var callBack = function() {};
	
	this.init = function(xmlSrc, callBackF) {
		if(DEBUG) alert("Init model with " + xmlSrc);
		
		this.items = new Array();
		callBack = callBackF;
		
		// load xml-file
		jQuery.ajax({
			url: xmlSrc,
			dataType: "xml",
			encoding:"UTF-8",
			beforeSend: xmlStart,
			success: xmlSuccess,
			error: xmlError,
			complete: xmlComplete
		});
		if(DEBUG) alert("after request launch");
	};
	
	this.getItem = function(i) {
		if(0 <= i < items.length) {
			return items[i];
		} else {
			return null;
		}
	}
	this.getItemCount = function() {
		return items.length;
	}
	
	// private functions
	function parseFeed(feed) {
		if(feed.getElementsByTagName("item").length == 0) { 
			this.items = null; 
		} else {
			if(DEBUG) alert("Items found.");
			var feedItems = feed.getElementsByTagName("item");
//			if(DEBUG) alert((new XMLSerializer()).serializeToString(feed)); // Error in IE
			for(var i = 0; i < feedItems.length; i++) {
				items[i] = new SlideshowItem(
							xmlGetValue(feedItems[i], "guid"),
							xmlGetValue(feedItems[i], "link"),
							xmlGetValue(feedItems[i], "title"),
							xmlGetAttribute(xmlGetItems(feedItems[i], "media:content")[0], "url")
						);
			}
		}
//		if(DEBUG) alert("Parsing finished.");
		
		// Inform SlideshowController
		callBack.call();
	}
	
	function xmlSuccess(xmlFeed, status) {
		if(DEBUG) alert("Feed loaded. Start parsing.");
		parseFeed(xmlFeed);
	}
	function xmlStart(xhrInstance) { 
		 if(DEBUG) alert('xmlStart');
	}
	function xmlComplete(xhrInstance, status) { 
		 if(DEBUG) alert('xmlComplete');
	}
	function xmlError(xhrInstance, message, optional) {
		if(DEBUG) alert("Error: " + message + ' - ' + optional);
	}
	
	function xmlGetElements(xmlDoc, tag) {
		return xmlDoc.getElementsByTagName(tag);
	}
	function xmlGetItems(xmlItem, tag) {
		var items = new Array();
		tag = tag.toLowerCase();
		for(var i = 0; i < xmlItem.childNodes.length; i++) {
			if(xmlItem.childNodes[i].nodeName != "#" && xmlItem.childNodes[i].nodeName == tag) {
//				if(DEBUG) alert("Tag found: " + tag);
				items[items.length] = xmlItem.childNodes[i];
			}
		}
		return items;
	}
	function xmlGetValue(xmlItem, tag) {
		if(tag != undefined) {
			return xmlGetValue((xmlGetItems(xmlItem, tag))[0]);
		} else {
			if(xmlItem.childNodes != undefined && xmlItem.childNodes[0] != undefined) {
//				if(DEBUG) alert("NodeInfo:\n" + xmlItem.nodeName+" "+ xmlItem.childNodes[0].nodeValue);
				return xmlItem.childNodes[0].nodeValue.trim();
			} else {
				return null;
			}
		}
	}
	function xmlGetAttribute(xmlItem, tag) {
//		if(DEBUG) alert("Attribute: " + xmlItem.attributes.getNamedItem(tag).value);
		return xmlItem.attributes.getNamedItem(tag).value;
	}
}

// ImageItem
function SlideshowItem(guid, link, title, imageSrc) {
	this.guid = guid;
	this.link = link;
	
	this.title = title;
	this.description = null;
	
	this.imageSrc = imageSrc;
	this.thumbnailSrc = null;
	
//	if(DEBUG) alert("Image:\n "+guid+"\n"+link+"\n"+title+"\n"+imageSrc);
}
