

(function($){
    
  /*  $.expr[':'].linkingToImage = function(elem, index, match){
        // This will return true if the specified attribute contains a valid link to an image:
        return !! ($(elem).attr(match[3]) && $(elem).attr(match[3]).match(/\.(gif|jpe?g|png|bmp)$/i));
    };
    */
  
    $.fn.gallerize = function(userDefinedSettings){
        
        var s = $.extend({
            /* DEFAULTS */
            onShow: function(){},
            onHide: function(){},
            onLoad: function(){},
            blackout: {
                fadeIn: 250, //in ms, 'slow', 'fast'
                fadeOut: 100, 
                opacity: 0.9
                },
            containerID: 'imgPreviewContainer',
            containerLoadingText: 'Loading...',
            theme: 'default', //not used yet
            transitionType: 'fadeIn',
            relAttr: 'fullsize',
			minViewerWidth: 800,
			navPanels: {
				bgColor: '#fff',
				hoverOpacity: 50 // percentage / 100
			},
            topOffSet: 0, //not used yet
			maxImageHeight: 90, // per cent / clientHeight
			paddings: {
				top: 0,
				right: 0,
				bottom: 0,
				left: 0
			},
			imageReducedNotice: {
				en_gb: "This image has been resized to fit your browser. Click here for the full size image.",
				en_us: "This image has been resized to fit your browser. Click here for the full size image.",
				de_de: "Dieses Bild wurde verkleinert, um eurem Browser zu entsprechen. Klickt hier, um das Bild in voller Größe zu sehen.",
				fr_fr: "Cette image a été redimensionnée pour s'afficher complètement dans votre navigateur. Cliquez ici pour rétablir sa taille originale.",
				es_es: "Se ha ajustado el tamaño de esta imagen para que puedas verla en tu navegador. Haz clic aquí para verla imagen a tamaño completo.",
				ru_ru: "Изображение было уменьшено для удобства просмотра. Щелкните здесь, чтобы увидеть изображение в исходном размере."
			},
            lang: 'en_gb'
		}, userDefinedSettings)


        var blackout = {
            toggle : function () {
                $blackout = $('#blackout');
                $blackout.css({
                    height: document.documentElement.scrollHeight + "px",
                    opacity: 0
                })
                .animate({
                    opacity: s.blackout.opacity
                }, s.blackout.fadeIn, "swing", function () {
					$('#blackout').click(function () { 
						blackout.close();
					})
				})
				.hover(function() {
						$('#v_button-close').stop().animate({ opacity: 0}, 300)
					}, function () {
						$('#v_button-close').stop().animate({ opacity: 1}, 300)
					});
			},
	    close: function () {
			$('#v_container').fadeOut();
			$('#v_screenshot img').remove();
			$blackout.unbind().animate({ opacity: 0 }, s.blackout.fadeOut, "swing", function () { $blackout.height(1); s.onHide(); }  )
		
	    },
        createLayer: function () {
			var blackout = createElement('div', {id : "blackout"}, document)
			document.getElementsByTagName('body')[0].appendChild(blackout)
            }
        }

        var screenshots = {
            createHolder: function () {
				var scroll = screenshots._getScrollPosition(),
				//creating DOM elements the old fashioned was to support troublesome XSL/XML setups
				v_container = createElement('div', { "id" : "v_container" }),
				v_t = createElement('div', { "id" : "v_t" }),
				v_tl = createElement('div', { "id" : "v_tl" }),
				v_tr = createElement('div', { "id" : "v_tr" }),
				v_l = createElement('div', { "id" : "v_l" }),
				v_r = createElement('div', { "id" : "v_r" }),
				v_b = createElement('div', { "id" : "v_b" }),
				v_bl = createElement('div', { "id" : "v_bl" }),
				v_br = createElement('div', { "id" : "v_br" }),
				v_screenshot = createElement('div', { "id": "v_screenshot" }),
				v_caption = createElement('div', { "id": "v_caption" }),
				v_caption_text = createElement('span'),
				v_panel_prev = createElement('span', { "id": "v_panel-prev" }),
				v_button_prev = createElement('a', { "id": "v_button-prev" }),
				v_panel_next = createElement('span', { "id": "v_panel-next" }),
				v_button_next = createElement('a', { "id": "v_button-next" }), 
				v_button_close = createElement('a', { "id": "v_button-close" }),
				v_button_close_hook = createElement('div', { "id": "v_button-close_hook" });
				v_button_maximize = createElement('a', { "id": "v_button-maximize" });
	
				/* Top */
				v_container.appendChild(v_t);
				v_container.appendChild(v_tl);
				v_container.appendChild(v_tr);
				/* Middle */
				v_container.appendChild(v_l);
				v_container.appendChild(v_screenshot);
				v_container.appendChild(v_r);
				/* Bottom*/
				v_container.appendChild(v_b);
				v_container.appendChild(v_br);
				v_container.appendChild(v_bl);
				
				/*left/right panels*/
				v_screenshot.appendChild(v_panel_prev);
				v_screenshot.appendChild(v_panel_next);
				
				/*Caption container*/
				v_caption.appendChild(v_caption_text);
				v_container.appendChild(v_caption);
	
				if(multipleImages) {
					var v_pager = createElement('div', { "id" : "v_pager" }),
					//v_pager_prev = createElement('span', { "class" : "prev" }),
					v_pager_cur = createElement('span');
					//v_pager_next = createElement('span', { "class" : "next" })
					
					//v_pager.appendChild(v_pager_prev);
					v_pager.appendChild(v_pager_cur);
					//v_pager.appendChild(v_pager_next);
					
					v_container.appendChild(v_pager);
				}
				
				v_container.appendChild(v_button_next);
				v_container.appendChild(v_button_prev);
				v_container.appendChild(v_button_close);
				v_container.appendChild(v_button_close_hook);
				v_container.appendChild(v_button_maximize);
			   
				var body = document.getElementsByTagName("body")[0];
                body.appendChild(v_container);
	
                $(body).addClass(s.theme);
                
                s.paddings.top = $('#v_t').height(),
				s.paddings.right = $('#v_r').width(),
				s.paddings.bottom = $('#v_b').height()
				s.paddings.left = $('#v_l').width()
                
                $('#v_container').css({ display: 'none', visibility: 'visible' })
                
                //checking for CSS definitions if custom theme defined
                if((s.paddings.left == 0) && (s.paddings.right == 0) && (s.paddings.top == 0) && (s.paddings.bottom == 0)) {

                    $(body).removeClass(s.theme).addClass('default');
                    s.theme = 'default';
                    
                    s.paddings.top = 10,
                    s.paddings.right = 20,
                    s.paddings.bottom = 40,
                    s.paddings.left = 0;
                    
                    $('#v_t').height(s.paddings.top)
                    $('#v_b').height(s.paddings.bottom)
                    
                    $('#v_button-next').text('> >')
                    $('#v_button-prev').text('< <')
                    
                    $('#v_container').css({
                        'backgroundColor' : '#fff'
                        })

                    //throw new Error('Lightbox: theme defined but no CSS definitions found (#v_t, #v_r, #v_b, #v_l)! Trying "default"...');
                }
                
                if(!$.browser.msie) { $("#v_panel-next, #v_panel-prev").css({ backgroundColor: s.navPanels.bgColor, opacity: 0 }); } else {
					$("#v_panel-next, #v_panel-prev").css( "z-index", "2200"); 
				}
		
                /*fades in nav panels left & right and hightlight next/prev arrows*/
				$("#v_panel-prev").hover(
					function() { 
						if($.browser.msie) {
						$(this).css({
							"filter": "Alpha(opacity=" + s.navPanels.hoverOpacity + ")",
							"backgroundColor": s.navPanels.bgColor
							});
						} else $(this).stop().animate({ opacity : s.navPanels.hoverOpacity / 100 }, 200)
                        
					}, function () {
						if($.browser.msie) {
						$(this).css({
							filter: "",
							backgroundColor: ""
							});
						} else $(this).stop().animate({opacity : 0}, 200)
					}
				)
				
                //fadeout next/previous buttons on panel hover
				$("#v_panel-next, #v_panel-prev").hover(
                    function() { 
						$('#' + ($(this)[0].id.replace("panel", "button"))).stop().animate({ opacity: 0}, 300)
					}, function () {
						$('#' + ($(this)[0].id.replace("panel", "button"))).stop().animate({ opacity: 1}, 300)
					}
				)
				
				$('#v_button-close, #v_button-next, #v_button-prev, #v_button-maximize')
					.hover(function () { $(this).css("background-position", "0 -" + $(this).height() + "px") }, function () { $(this).css("background-position", "0 0") });

				$('#v_button-close').click(function () { blackout.close() });
				$('#v_pager span').addClass('count');
				//$('#v_l, #v_r').css("margin-top", -(s.paddings.top)); //weird but works, only with theme
				
			},
            
            initImage: function (image, imgIndex) {
                blackout.toggle();
                var $image = $(image);
                setTimeout( function () {
                    screenshots._populateImg(image, imgIndex); // start loading image
                }, s.blackout.fadeIn + 100)
                
            },
            
            centerContainer: function () {
                var scroll = screenshots._getScrollPosition(),
				topValue = ((document.documentElement.clientHeight - $('#v_container').height()) / 2) + scroll.scrollTop,
				leftValue = (document.documentElement.clientWidth - $('#v_container').width()) / 2;
				$('#v_container').css({
				    top: topValue,
				    left: leftValue
				})
            },
            
            _getScrollPosition: function (){
                scrollTop = window.pageYOffset || document.documentElement.scrollTop || 0,
    			scrollLeft = window.pageXOffset || document.documentElement.scrollLeft || 0;
                return {scrollTop: scrollTop, scrollLeft: scrollLeft};
            },
            
            _populateImg: function (image, imgIndex) {

                var $image = $(image),
                nextImgIndex = (imgIndex + 1 < imagesCount) ? imgIndex + 1 : 0,
                prevImgIndex = (imgIndex - 1 < 0) ? imagesCount - 1: imgIndex - 1,
                nextImgObj = collection[nextImgIndex],
                prevImgObj = collection[prevImgIndex],
                scroll = screenshots._getScrollPosition(), //todo: move
				reducedByPercent, imgWidth, imgHeight, minViewerWidth, windowHeight, windowWidth;
                
				if($.browser.opera) {
					windowHeight = window.innerHeight;
					windowWidth = window.innerWidth;
				} else {
					windowHeight = document.documentElement.clientHeight;
					windowWidth = document.documentElement.clientWidth;
                };
		
				var maxAllowedHeight = Math.floor(windowHeight * (s.maxImageHeight / 100))
		
                //resetting
                //$('#v_container .controlElement').css("opacity", "0");
				$('#v_screenshot').hide();
				$('#v_screenshot img').remove();
                
                preLoadImage = new Image();
                preLoadImage.onload = function () {
					
					if (this.height > maxAllowedHeight) {
						reducedByPercent = Math.floor( (maxAllowedHeight * 100) / this.height ) / 100, 
						this.width = this.width * reducedByPercent,
						this.height = this.height * reducedByPercent;
						$('#v_button-maximize') 
							.attr('title', s.imageReducedNotice[s.lang.replace("-", "_")]) 
							.attr('href', $image.attr(s.relAttr))
							.attr('target', '_blank')
							.show();
					} else { $('#v_button-maximize').hide(); }
					
					imgWidth = this.width,
					imgHeight = this.height,
					minViewerWidth = ((imgWidth > s.minViewerWidth) ? imgWidth : s.minViewerWidth) + (s.paddings.left + s.paddings.right),
					outerContainerHeight = imgHeight + (s.paddings.top + s.paddings.bottom), //25 = caption height, TODO: make dynamic
					outerContainerWidth = imgWidth + (s.paddings.left + s.paddings.right);
				
                    
                
					$('#v_caption').find('span').text(($image.attr("alt") ? $image.attr("alt") : " ")); //fill caption
					
					$('#v_panel-prev').height(imgHeight).width("20%")
					.unbind('click').click(function () {
						screenshots._populateImg(prevImgObj, prevImgIndex)
					})
					$('#v_button-prev').unbind('click').click(function () {
						screenshots._populateImg(prevImgObj, prevImgIndex)
					});
					$('#v_panel-next').height(imgHeight).width("80%")
					.unbind('click').click(function () {
						screenshots._populateImg(nextImgObj, nextImgIndex)
					});
					$('#v_button-next').unbind('click').click(function () {
						screenshots._populateImg(nextImgObj, nextImgIndex)
					});
					
					if(multipleImages) {
						$('#v_pager .count').text((imgIndex + 1)+ "/" + imagesCount);
						/*$('#v_pager .prev')
							.unbind('click')
							.click(function () {
							screenshots._populateImg(prevImgObj, prevImgIndex) 
							})
							.text(prevImgIndex);
						$('#v_pager .next')
							.unbind('click')
							.click(function () {
							screenshots._populateImg(nextImgObj, nextImgIndex)
							})
							.text(nextImgIndex);*/
					}
					
					$('#v_container').animate({
						height: outerContainerHeight, 
						width: minViewerWidth, 
						top: ((windowHeight - outerContainerHeight) / 2) + scroll.scrollTop + "px",
						left: (windowWidth - minViewerWidth) / 2 + "px"
					}, 250, "linear", function () {
						//add support for different transition effects via setting
						$('#v_screenshot').css({
                     width: imgWidth,
							left: ((minViewerWidth - imgWidth) / 2) - s.paddings.left
						})
						.append(preLoadImage).fadeIn(300);
					})
				}
	            preLoadImage.src = $image.attr(s.relAttr); //needs to be defined after .onload
            }
        }
            
        var collection = this.filter("[" + s.relAttr + "]"), //todo: scan for attr, scan for rel value, scan for <a> with img
             imagesCount = collection.length,
             multipleImages = (collection.length > 1);
				
        collection.each(function (i) {
           var $img = $(this);
           
           $img.parent('a').removeAttr('href');
           $img.click(function () {
               screenshots.initImage($img, i);
           }).css("cursor", "pointer")
        })
        
        
        //append blackout & screenshots viewer to the DOM TODO: make that happen during runtime
        blackout.createLayer();
        screenshots.createHolder();
       
        $(window)
            .resize(function () { screenshots.centerContainer() })
	    //.scroll(function () { screenshots.centerContainer() })
        
	//ESC closes lightbox
	document.onkeydown = function(e){ 
		e = window.event || e,
		keycode = e.keyCode || e.which;

          if(keycode == 27){ 
              blackout.close();
          } 
        };
	
        return this;
        
    };
    
})(jQuery);


// Insert preloaded image after it finishes loading
//$('<img />')
//    .attr('src', 'imageURL.jpg')
//    .load(function(){
//        $('.profile').append( $(this) );
//        // Your other custom code
//    });


