ImageZoomer = function(){
	
	var maskel;
	var images=[];
	var index=0;
	var info_visible=false;
	var imgel;
	
	function keyNavAction(ev) {
        var keyCode = ev.getKey();
        if(
            keyCode == 88 || // x
            keyCode == 67 || // c
            keyCode == 27
        ){
        	if(info_visible)
        		toggleImageInfo();
            else closeImage();
        }
        else if(keyCode==37)	// cursor left 
        	prevImage()	
        else if(keyCode==39)	// cursor right 
        	nextImage()
        else if(keyCode==73)	// i 
        	toggleImageInfo();
	}
	
	function closeImage(){
	
       	if(info_visible)
       		toggleImageInfo();
	
		var el=Ext.get("modal-image");	
		el.child(".img-wrap").hide();
		el.hide({
			callback: function(){
				imgel.hide();
				imgel.removeAllListeners();
				el.removeAllListeners();
				Ext.fly(document).removeAllListeners();
				maskBody(false);
				//imgel.remove();
				el.remove();
			}
		})
		index=-1;
		
		Ext.fly(document).un('keydown', keyNavAction, this);	
		//location.hash=""	
	}
	
	function maskBody(mask){
		if(!maskel){
			// create one
			maskel = Ext.getBody().createChild({tag:"div"});
			maskel.setStyle({
				position: "absolute",
				zIndex: 100,
				opacity: .7,
				top: Ext.getBody().getScroll().top+"px",
				left: 0,
				width: Ext.lib.Dom.getViewportWidth()+"px",
				height: Ext.lib.Dom.getViewportHeight()+"px",
				backgroundColor: "black",
				overflow: "hidden"
			})
		}
		
		if(mask){
			Ext.getBody().setStyle("overflow", "hidden");
		}
		else {
			Ext.getBody().setStyle("overflow", "auto")
			maskel.remove();
			maskel=null;
		}
	}
	
	function addHash(index){
		var img_id = images[index].id;
		if(img_id){
			//location.hash=img_id;
			//location.href="#"+img_id;
		}	
	}
	
	function showImage(url){
		
		maskBody(true);
		info_visible=false;
		
		var el=Ext.get("modal-image");
		if(el==null){
			// create div to show images in:
			el = Ext.getBody().createChild({tag:"div", id:"modal-image"});
		}
		el.hide();
		el.setStyle("zIndex", 30000);

		el.update("<div class='loading'>loading image ...</div>");
		el.setHeight(200)
		el.setWidth(200);

		//allign element:		
		el.setLeft((maskel.getWidth()-200)/2);
		el.setTop(maskel.getTop() + ((maskel.getHeight()-200)/2));
		
		el.show(true);		
		
		// find index:
		for(var i=0; i<images.length; i++){
			if(images[i].url==url){
				index=i;
				break;
			}
		}
		addHash(index)
		
		var imgdom = document.createElement("img");
		var img = imgel = Ext.get(imgdom);		
		
		if(images[index].posturl){
			img.setStyle("cursor", "pointer");
			img.dom.title="Click to open Post"
			img.on("click", function(){
				location.href=images[index].posturl;
			})
		}
		
		img.on("load", function(){
			img.hide();
			el.update("");
			el.appendChild(this.dom);
			scaleImg(this.dom);
			
			var t = new Ext.Template(
					'<div class="img-wrap" style="display:none;position:abslolute;margin-top:8px;">',
						'<div class="img-info"></div>',
					    '<div align="left" style="float:left" class="img-title">{title}</div>',
					    ImageZoomer.imageInfoURL?'<div style="float:right" class="img-info-link" title="show/hide more infos ..."></div>':'',
					    '<div style="clear:both"></div>',
					    '<div style="float:left">Image {index} of {count} ( <a class="prev" href="javascript:viod()">prev</a> | <a class="next" href="javascript:viod()">next</a> )</div>',
					    '<div style="float:right"><a href="javascript:viod()" class="close-img">ESC to close</a></div>',
				    '</div>'
				);
			t.append(el.dom, {title: images[index].title||'no title', index:index+1, count: images.length});

			var w = img.getWidth()+20;
			var h = img.getHeight()+55;
			var x = (Ext.lib.Dom.getViewportWidth()-w)/2
			var y = Ext.getBody().getScroll().top + (Ext.lib.Dom.getViewportHeight()-h)/2
						
			el.shift({
				duration: w==el.getWidth() ? .001 : .2,
				x: x,
				width: w
			}).shift({
				duration: h==el.getHeight() ? .001 : .2,
				y: y,
				height: h,
				callback: function(){
					img.show(true)
					el.child(".img-wrap").show(true);
				}
			});
			
			var next = el.child(".next");
			if(next){
				next.on("click", function(ev){
					nextImage()
					ev.stopEvent();
				})
			}
			var prev = el.child(".prev");
			if(prev){
				prev.on("click", function(ev){
					prevImage();
					ev.stopEvent();
				})
			}
			var close = el.child(".close-img");
			if(close){
				close.on("click", function(ev){
					closeImage();
					ev.stopEvent();
				})
			}
			var info = el.child(".img-info");
			var info_link = el.child(".img-info-link");
			if(info&&info_link){
				info_link.on("click", function(ev){
					toggleImageInfo()
					ev.stopEvent();
				})
			}
			
		});
		img.dom.src=url;
		Ext.fly(document).on('keydown', keyNavAction, img);
		
	}
	
	function toggleImageInfo(){
		var info = imgel.parent("div").child(".img-info");
		if(info && ImageZoomer.imageInfoURL){
			if(info.isVisible())
				info.slideOut();
			else{
				info.setTop(imgel.getTop(true)+10);
				info.setHeight(imgel.getHeight());
				info.setWidth(imgel.getWidth());
				info.setOpacity(.7);
				info.slideIn();
				info.load(ImageZoomer.imageInfoURL+"?id=" + images[index].id);
			}
			info_visible = !info_visible;
		}		 
	}

	function showNewImage(i){
		if(i)
			index=i;
		imgel.hide({
			callback: function(){
				Ext.get("modal-image").update("<div class='loading'>loading image ...</div>");
				imgel.dom.src=images[index].url;
				addHash(index)
			}
		});
	}

	function nextImage(){
		info_visible=false;
		index++;
		if(index>=images.length)
			index=0;
		showNewImage();
	}

	function prevImage(){
		info_visible=false;
		index--;
		if(index<0)
			index=images.length-1;
		showNewImage();
	}
	
	function scaleImg(img, size){
		img.removeAttribute("width");
		img.removeAttribute("height");

		var wMax = size || Ext.lib.Dom.getViewportWidth()-70;
		var hMax = size || Ext.lib.Dom.getViewportHeight()-70;
	
		if (Ext.isIE) {
			// drifferent padding/margin behaviour in IE
			wMax -= 2 * 3;
			hMax -= 2 * 3;
		}
		
		var ratio = img.height/img.width;

		if(img.height>hMax){
			var newW = Math.min(hMax / ratio, wMax);
			img.height = newW * ratio;
			img.width = newW;
			return;
		}		
		if(img.width>wMax){
			var newH = Math.min(ratio * wMax, hMax);
			img.height = newH;
			img.width = newH / ratio;
			return;
		}
	}

	function addImage(url, title, posturl, id){
		images.push({
			url: url,
			title: title,
			posturl: posturl,
			id: id
		})
	}
	
	/*
	window.onload=function(){
		// preload images:
		for(var i=0; i<images.length; i++){
			var imgobj = new Image();
			imgobj.src=images[i].url
		}
	}
	*/
	
	/*	
	// manage browser history
	var hash = location.hash;
	window.setInterval(function(){
		if(location.hash!=hash){
			hash = location.hash;
			if(hash=="#"||hash==""){
				closeImage(imgel);
				console.log("# removed: close image");
			}
			else {
				for(var i=0; i<images.length; i++){
					if(i==index){
						continue;
					}
					var img = images[i];
					if(location.hash == "#"+img.id){
						console.log("showNewImage(i)", i);
						showNewImage(i);
						break;
					}
				}
			}
		}
	}, 100)
	*/
		
	return{
		
		init: function(selector, title){
			Ext.select(selector || ".rtf a").each(function(el){
				var href = el.dom.href||el.dom.src;
				href=href.split(";")[0];	// ignore ;jsessiond-s
				var a = href.split(".");
				if(a.length>1){
					var ext = a.pop().toLowerCase();
					if(ext=="png" || ext=="jpg" || ext=="gif"){
						addImage(href, el.dom.title||title||"", null, el.dom.id);
						el.on("click", function(ev){
							ev.preventDefault();
							showImage(this.url);
						}, {url:href, title:el.dom.title})
					}
				}
			})
			if(location.hash){
				// find and show image
				for(var i=0; i<images.length; i++){
					var img = images[i];
					if(location.hash == "#"+img.id){
						showImage(img.url)
						break;
					}
				}			
			}
		},
		
		showImage: showImage,
		addImage: addImage,
		scaleImage: scaleImg
	}
	
}()