
/*


	Simple Gallery - jQuery plug-in
	
	-----------------------------------------------------------------------------------------------------------------------------
	
	Sample mark up:
	
	
	<div id="fallback"></div> - Fallback used as transparent background to window
	
	<div class="overlay">
		<div class="content">
			<img />
			<div class="legend"></div>
		</div>
		<a class="close"></a>
		<a class="next"></a>
		<a class="previous"></a>
	</div>
	
	
		All classes can be changed via the api paramenters (read listing bellow)
	
	-----------------------------------------------------------------------------------------------------------------------------
	
	Properties that can be set:
	
	selectedAnchorClass: [string], - class for the current anchor tag
	fallbackBkgColor: [hexadecimal color code],  -  color code for the fallback 
	overlay: [jQuery selector query], - selector query for the overlay
	loadIcon: [string],  -  path to loding icon in the overlay
	imageLoadTimeout: [integer],  -  maximum amount of time for image to load  
	overlayClass: [string],  - string representing class of overlay (not query)
	contentClass: [string],  -  string representing class of content element (not query)
	overlayResizeEffect: [string], - name of effect used in the resizing step of the overlay animation
	legendClass: [string],  - string representing the class of the legend element (not query)
	closeBtnClass: [string], - string representing the class of the close button (not query)
	closeBtnText: [string], - text of close button
	navButtonsPos: [string], - position where navigation buttons are inserted ('before' or 'after' the legeng) 
	nextBtnClass: [string], - string representing the class name of the next button (not query)
	previousBtnClass: [string], - string representing the class name of the previous button (not query)
	nextBtnText: [string],  -  text of the next button
	previousBtnText: [string], - text of the previous button
	overlayOuterMargin: [integer], - margin for the overlay
	reLoadIcon: [string] - path to the re-loading icon image
	
	
	
	P.S. (not query) means that the paramenter is set with a normal string and not a query string, which can be used with jQuery 
	in order to look for a particular selector.
	
	

	-----------------------------------------------------------------------------------------------------------------------------

*/

(function($) {

    function isIE6() {
        if (jQuery.browser.msie) {
            if (jQuery.browser.version && jQuery.browser.version.toString().indexOf('6.') != -1) return true;
        }
        return false;
    }

    function SimpleGallery() {
        if (typeof SimpleGallery._initialized == 'undefined')//If prototype has not been defined yet
        {
            SimpleGallery.prototype.load = function()//Load overlay for the first time
            {
                this.attachFallback();
            };

            SimpleGallery.prototype.attachImage = function()//Load image before loading the overlay
            {
                var sg = this;
                //Set timeout in order to display error if the image does not load in the length if time pre-set
                this.timeout = setTimeout(function() { sg.imageLoadError(); }, settings.imageLoadTimeout);

                this.imgLoading = $('<img />', {//Create image

            }).load(function() {
                clearTimeout(sg.timeout); //Clear timeout
                sg.timeout = null;
                sg.removeFirstTimeLoadIcon(); //Remove loading icon
                sg.attachOverlay(); //Attach overlay
            }).attr('src', this.getImagePath()); //Start loading

        };

        SimpleGallery.prototype.attachOverlay = function()//Attach overlay for the first time
        {
            var sg = this;
            this.overlay = $('<div></div>', {//Create and set the properties of the overlay
                css: {
                    opacity: 0,
                    position: 'absolute',
                    top: '0',
                    left: '0',
                    float: 'left',
                    overflow: 'hidden'
                }
            }).addClass(settings.overlayClass).appendTo(document.body); //Add the class name specified and attach overlay to the document

            $(this.createContents()).appendTo(this.overlay); //Attach the image, legend and navigation buttons to the overlay
            $(this.attachCloseButton()).appendTo(this.overlay); //Attach the close button to the overlay

            this.reviewImgDimensions(); //Review image dimensions. If image is too big it will be resized here
            this.reviewContentDimensions(); //Review content dimensions including the legend

            $(this.overlay).css({//Update the overlay's dimensions and position according to nested updated contents
                top: this.getOverlayPosition().top,
                left: this.getOverlayPosition().left,
                width: $(this.overlay).width(),
                height: $(this.overlay).height()
            }).animate({//Fade overlay into page
                opacity: 1
            }, 300, 'linear', function() {
                sg.refreshOverlayFunction = function() { sg.refreshOverlay(); }; //listen to window resizes in order to update the position of the overlay on the page
                $(window).resize(sg.refreshOverlayFunction);
            });


        };

        SimpleGallery.prototype.refreshOverlay = function()//Update the position of the overlay on the page
        {
            $('.' + settings.overlayClass).css({
                top: this.getOverlayPosition().top,
                left: this.getOverlayPosition().left
            });
        };

        SimpleGallery.prototype.removeOverlay = function()//Remove overlay from the page
        {
            $(window).unbind('resize', this.refreshOverlayFunction); //Detach resize function from the window
            $('.' + settings.overlayClass).animate({//Fade overlay out
                opacity: 0
            }, 200, function() {
                $(this).remove(); //Remove overlay
            });
        };

        SimpleGallery.prototype.getOverlayPosition = function()//Calculate the position of the overlay according to the dimensions of the window
        {
            var top = Math.round($(window).scrollTop() + (($(window).height() / 2) - (this.overlayHeight() / 2)));
            //If the overlay's calculated top position is above the scrollTop position of the window move it to the viewable area
            if (top < $(window).scrollTop()) top = $(window).scrollTop() + settings.overlayOuterMargin;
            var left = Math.round(($(window).width() / 2) - (this.overlayWidth() / 2));
            //If the overlay's calculated left position is smaller than 0 move it to the viewable area
            if (left < 0) left = 0;
            return { top: top, left: left }; //Return calcuated position
        };

        SimpleGallery.prototype.reviewContentDimensions = function()//Resize the content holder accordin to the image width
        {
            $('.' + settings.overlayClass + ' .' + settings.contentClass).css('width', this.imgWidth());
        };

        SimpleGallery.prototype.reviewImgDimensions = function()//Calculate dimensions of the image in the overlay according to the dimensions of the window
        {
            var width = this.imgWidth();
            var height = this.imgHeight();

            while ((height > this.maxAcceptableImgHeight()) || (width > this.maxAcceptableImgWidth()))//do this until the image dimensions are within the boundaries
            {
                if (height > this.maxAcceptableImgHeight())//If height is big
                {
                    var dims = this.getNewImgDimensions('height', width, height);
                } else {//If width is big
                    var dims = this.getNewImgDimensions('width', width, height);
                }
                height = dims.height;
                width = dims.width;
            }

            $('.' + settings.overlayClass + ' .' + settings.contentClass).find('img').css({//Set the height and width of the content holder
                width: width,
                height: height
            });
        };

        SimpleGallery.prototype.getNewImgDimensions = function(p, width, height)//Calculate dimensions of image according to one of its parameters
        {
            if (p == 'height')//if the proportion to be used is the height
            {
                var percentage = (this.maxAcceptableImgHeight() * 100) / height;
            } else {
                var percentage = (this.maxAcceptableImgWidth() * 100) / width;
            }
            return { width: Math.round((percentage * width) / 100), height: Math.round((percentage * height) / 100) };
        };

        SimpleGallery.prototype.maxAcceptableImgHeight = function()//Calculate the maximum height allowed for the image
        {
            return Math.round($(window).height() - ((settings.overlayOuterMargin * 2) + (this.overlayHeight() - $(this.overlay).height())));
        };

        SimpleGallery.prototype.maxAcceptableImgWidth = function()//Calculate the maximum width allowed for the image
        {
            return Math.round($(window).width() - ((settings.overlayOuterMargin * 2) + (this.overlayWidth() - $(this.overlay).width())));
        };

        SimpleGallery.prototype.imgHeight = function()//Retrieve the height of the current image
        {
            return $('.' + settings.overlayClass + ' .' + settings.contentClass).find('img').outerHeight();
        };

        SimpleGallery.prototype.imgWidth = function()//Retrieve the width of the current image
        {
            return $('.' + settings.overlayClass + ' .' + settings.contentClass).find('img').outerWidth();
        };

        SimpleGallery.prototype.pHeight = function()//Retrieve the height of the legend
        {
            return $('.' + settings.overlayClass + ' .' + settings.contentClass).find('p').outerHeight();
        };

        SimpleGallery.prototype.pWidth = function()//retrieve the width of the legend
        {
            return $('.' + settings.overlayClass + ' .' + settings.contentClass).find('p').outerWidth();
        };

        SimpleGallery.prototype.contentHeight = function()//Retriece the height of the content holder
        {
            return $('.' + settings.overlayClass + ' .' + settings.contentClass).outerHeight();
        };

        SimpleGallery.prototype.contentWidth = function()//Retrieve the width of the content holder
        {
            return $('.' + settings.overlayClass + ' .' + settings.contentClass).outerWidth();
        };

        SimpleGallery.prototype.overlayHeight = function()//Retrieve the height of the overlay
        {
            return $('.' + settings.overlayClass).outerHeight();
        };

        SimpleGallery.prototype.overlayWidth = function()//Retrieve the width of the overlay
        {
            return $('.' + settings.overlayClass).outerWidth();
        };


        SimpleGallery.prototype.slide = function()//Move to the next image
        {
            var sg = this;
            this.hideCloseButton(); //Fade out the close button
            $('.' + settings.overlayClass + ' .' + settings.contentClass).animate({//fade out the content area
                opacity: 0
            }, 100, 'linear', function() {
                sg.attachReLoadIcon(function() {  //Attach the re-load icon

                    //Set timeout in order to detect whether there been an error loding the image
                    sg.timeout = setTimeout(function() { sg.imageLoadError(); }, settings.imageLoadTimeout);
                    sg.imgLoading = $('<img />', {//Create image element in order to load next image

                }).load(function() {
                    clearTimeout(sg.timeout); //Clear timaout
                    sg.timeout = null;
                    sg.removeReLoadIcon(); //Remove loading icon
                    sg.updateContents(this); //display all other elements
                }).attr('src', sg.getImagePath()); //Load next image

            });
        });

    };

    SimpleGallery.prototype.updateContents = function(img)//Update the other elements in the overlay according to the new image
    {
        var sg = this;
        this.setImg(img); //Update image
        this.setContentHolder(); //Update content holder	
        this.setText(); //update legend

        this.reviewImgDimensions(); //Review image dimensions according to the dimensions of the window
        this.reviewContentDimensions(); //REview the content dimensions according to the new image dimensions

        var overlayFullHeight = (this.overlayHeight() - $(this.overlay).height()) + this.contentHeight(); //Reference to the full height of the overlay once loaded
        var overlayFullWidth = (this.overlayWidth() - $(this.overlay).width()) + this.contentWidth(); //Reference to the full width of the overlay once loaded

        //Reference to the top position of the overlay once loaded
        var top = Math.round($(window).scrollTop() + (($(window).height() / 2) - (overlayFullHeight / 2)));
        if (top < $(window).scrollTop()) top = $(window).scrollTop() + settings.overlayOuterMargin;
        //Reference to the left position of the overlay once loaded
        var left = Math.round(($(window).width() / 2) - (overlayFullWidth / 2));
        if (left < 0) left = 0;

        $('.' + settings.overlayClass).animate({//Resize and reposition overlay
            top: top,
            left: left,
            width: this.contentWidth(),
            height: this.contentHeight()
        }, 700, settings.overlayResizeEffect, function() {
            $('.' + settings.overlayClass + ' .' + settings.contentClass).animate({//Fade in content
                opacity: 1
            }, 200, 'linear', function() {
                sg.updateTextForIE6();
                sg.showCloseButton(); //Hide close button	
            });
        });
    };

    SimpleGallery.prototype.updateTextForIE6 = function() {

    };

    SimpleGallery.prototype.setImg = function(img)//Set image element in overlay with a new image
    {
        $('.' + settings.overlayClass + ' .' + settings.contentClass + ' img').attr({
            src: this.getImagePath(),
            alt: ''
        }).css({
            width: img.width,
            height: img.height
        });
    };

    SimpleGallery.prototype.setContentHolder = function()//Set content holder
    {
        $('.' + settings.overlayClass + ' .' + settings.contentClass).css({
            width: 'auto'
        });
    };

    SimpleGallery.prototype.setText = function()//Set text of legend
    {
        var text = (this.getImageAltText()) ? decodeURIComponent(this.getImageAltText()) : '';
        $('.' + settings.overlayClass + ' .' + settings.legendClass).html(text);

    };

    SimpleGallery.prototype.createContents = function()//Create image, legend and navigation buttons
    {
        var content = $('<div></div>', {//Create content element and attach class name

    }).addClass(settings.contentClass);

    $('<img />', {//Create image element
        alt: this.getImageAltText() ? this.getImageAltText() : '',
        src: this.getImagePath()
    }).appendTo(content); //Attach image element to content

    if (settings.navButtonsPos == 'before')//if navigation buttons are to be placed before legend, do so
    {
        $(this.attachPreviousButton()).appendTo(content); //Attach previous button to content
        $(this.attachNextButton()).appendTo(content); //Attach next button to content
    }

    if (this.getImageAltText())//If there is text to be added to the legend
    {
        var oDiv = $('<div></div>', {}).addClass(settings.legendClass).appendTo(content); //Create legend and attach it to the content
        $('<p></p>', {//Create paragraph and attach legend text to it
            html: decodeURIComponent(this.getImageAltText())
        }).appendTo(oDiv); //Attach paragraph to legend
    }

    if (settings.navButtonsPos == 'after')//if navigation buttons are to be placed after legend, do so
    {
        $(this.attachPreviousButton()).appendTo(content); //Attach previous button to content
        $(this.attachNextButton()).appendTo(content); //Attach next button to content
    }

    return content; //Return content with 
};

SimpleGallery.prototype.attachCloseButton = function()//create close button
{
    var sg = this;
    var a = $('<a></a>', {//Create anchor tag
        css: {

    },
    text: settings.closeBtnText,
    href: '#'
}).addClass(settings.closeBtnClass).click(function($e) {//Attach click event
    $e.preventDefault();
    sg.remove();
});
return a;
};

SimpleGallery.prototype.hideCloseButton = function()//Fade out close button
{
    $('.' + settings.overlayClass + ' .' + settings.closeBtnClass).animate({
        opacity: 0
    }, 100, 'linear');
};

SimpleGallery.prototype.showCloseButton = function()//Fade in close button
{
    $('.' + settings.overlayClass + ' .' + settings.closeBtnClass).animate({
        opacity: 1
    }, 100, 'linear');
};

SimpleGallery.prototype.attachNextButton = function()//Create next button
{
    var sg = this;
    var a = $('<a></a>', {//Create anchor tag
        css: {

    },
    text: settings.nextBtnText,
    href: '#'
}).addClass(settings.nextBtnClass).click(function($e) {//Attach click event
    $e.preventDefault();
    sg.next();
    sg.slide();
});
return a;
};

SimpleGallery.prototype.hideNextButton = function()//Fade out next button
{
    $('.' + settings.overlayClass + ' .' + settings.nextBtnClass).animate({
        opacity: 0
    }, 100, 'linear');
};

SimpleGallery.prototype.showNextButton = function()//Fade in next button
{
    $('.' + settings.overlayClass + ' .' + settings.nextBtnClass).animate({
        opacity: 1
    }, 100, 'linear');
};

SimpleGallery.prototype.attachPreviousButton = function()//Create previous button
{
    var sg = this;
    var a = $('<a></a>', {//Create anchor tag
        css: {

    },
    text: settings.previousBtnText,
    href: '#'
}).addClass(settings.previousBtnClass).click(function($e) {//Attach click event
    $e.preventDefault();
    sg.previous(); //Set previous anchor as current
    sg.slide(); //update overlay with new image
});
return a;
};

SimpleGallery.prototype.hidePreviousButton = function()//Fade out previous button
{
    $('.' + settings.overlayClass + ' .' + settings.previousBtnClass).animate({
        opacity: 0
    }, 100, 'linear');
};

SimpleGallery.prototype.showPreviousButton = function()//Fade in previous button
{
    $('.' + settings.overlayClass + ' .' + settings.previousBtnClass).animate({
        opacity: 1
    }, 100, 'linear');
};

SimpleGallery.prototype.imageLoadError = function()//Alert user of error when image does not load in a length of time
{
    this.imgLoading = null;
    alert('Error loading image');
    this.remove();
};

SimpleGallery.prototype.attachFallback = function()//Attach fallback to document
{
    var sg = this;
    $('<div id="sg-fallback"></div>').css({//Create element
        position: 'absolute',
        top: 0,
        left: 0,
        'background-color': settings.fallbackBkgColor,
        height: $(document.body).height(),
        width: $(document.body).width(),
        opacity: 0
    }).click(function($e) {//Attach click function
        $e.preventDefault();
        sg.remove();
    }).appendTo(document.body).animate({//Attach fallback to document
        opacity: 0.8
    }, 150, 'linear', function() {
        sg.attachFirstTimeLoadIcon(); //After fallback is attached proceed to attach the load progress icon
        //Attach event to listen the window resize event in order to refresh fallback
        sg.refreshFallbackFunction = function() { sg.refreshFallback(); };
        $(window).resize(sg.refreshFallbackFunction);
    });


};


SimpleGallery.prototype.refreshFallback = function()//Refresh fallback
{
    $('#sg-fallback').css({
        height: $(document.body).height(),
        width: $(document.body).width()
    });
};

SimpleGallery.prototype.removeFallback = function()//remove fallback
{
    this.removeFirstTimeLoadIcon(); //Remove load progress icon
    $(window).unbind('resize', this.refreshFallbackFunction); //Remove listener from window resize event
    $('#sg-fallback').animate({//Fade out fallback
        opacity: 0
    }, 100, function() {
        $(this).remove(); //Remove fallback after it has been faded out
    });
};

SimpleGallery.prototype.attachFirstTimeLoadIcon = function()//Attach load progress icon to document
{
    var sg = this;
    $('<img />', {//Create image element for icon
        css: {
            position: 'absolute',
            top: '0',
            left: '0',
            opacity: '0'
        },
        id: 'sg-firstTimeLoadIcon'
    }).addClass('sg-firstTimeLoadIcon').load(function() {//Add class to element and attach load event
        $(this).css({
            top: Math.round($(window).scrollTop() + (($(window).height() / 2) - (this.height / 2))),
            left: Math.round(($(window).width() / 2) - (this.width / 2))
        }).appendTo(document.body).animate({//Attach load icon to document and fade it in
            opacity: 1
        }, '50', 'linear', function() {//Once icon is loaded
            //Attach function to listen the window resize event in order to refresh icon
            sg.refreshFirstTimeLoadIconFunction = function() { sg.refreshFirstTimeLoadIcon(); };
            $(window).resize(sg.refreshFirstTimeLoadIconFunction);
            sg.attachImage(); //Attach image
        });
    }).attr('src', settings.loadIcon);
};

SimpleGallery.prototype.refreshFirstTimeLoadIcon = function()//Refresh progress load icon
{
    $('#sg-firstTimeLoadIcon').css({
        top: Math.round($(window).scrollTop() + (($(window).height() / 2) - ($('#sg-firstTimeLoadIcon').height() / 2))),
        left: Math.round(($(window).width() / 2) - ($('#sg-firstTimeLoadIcon').width() / 2))
    });
};

SimpleGallery.prototype.removeFirstTimeLoadIcon = function()// Remove load icon
{
    $(window).unbind('resize', this.refreshFirstTimeLoadIconFunction);
    $('#sg-firstTimeLoadIcon').remove();
};

SimpleGallery.prototype.attachReLoadIcon = function(func) {
    var sg = this;
    $('<img />', {
        css: {
            position: 'absolute',
            top: '0',
            left: '0',
            opacity: '0'
        },
        id: 'sg-ReLoadIcon'
    }).addClass('sg-ReLoadIcon').load(function() {

        $(this).css({
            top: Math.round((sg.overlayHeight() / 2) - (this.height / 2)),
            left: Math.round((sg.overlayWidth() / 2) - (this.width / 2))
        }).appendTo($('.' + settings.overlayClass)).animate({
            opacity: 1
        }, '50', 'linear', function() {
            func();
        });
    }).attr('src', settings.reLoadIcon);
};

SimpleGallery.prototype.removeReLoadIcon = function() {
    $('#sg-ReLoadIcon').remove();
};

SimpleGallery.prototype.firstTimeError = function() {

};

SimpleGallery.prototype.remove = function() {
    this.imgLoading = null;
    this.removeFallback();
    this.removeOverlay();
};

SimpleGallery.prototype.next = function() {
    var index = (this.getCurIndex() + 1);
    if (index == $(settings.anchors).length) index = 0;
    this.resetAnchors();
    $(settings.anchors).eq(index).addClass(settings.selectedAnchorClass);
};

SimpleGallery.prototype.previous = function() {
    var index = (this.getCurIndex() - 1);
    if (index < 0) index = ($(settings.anchors).length - 1);
    this.resetAnchors();
    $(settings.anchors).eq(index).addClass(settings.selectedAnchorClass);
};

SimpleGallery.prototype.getCurIndex = function() {
    var index = 0;
    $(settings.anchors).each(function($key, $value) {
        if ($(this).hasClass(settings.selectedAnchorClass)) {
            index = $key;
        }
    });
    return index;
};

SimpleGallery.prototype.getImagePath = function() {
    var oAnchor = '';
    $(settings.anchors).each(function() {
        if ($(this).hasClass(settings.selectedAnchorClass)) {
            oAnchor = $(this).attr('href');
        }
    });
    return oAnchor;
};

SimpleGallery.prototype.getImageAltText = function() {
    var oTitle = null;
    $(settings.anchors).each(function() {
        if ($(this).hasClass(settings.selectedAnchorClass)) {
            if ($(this).attr('rel') && $(this).attr('rel').length > 0) {
                oTitle = $(this).attr('rel');
            } else {
                oTitle = ($(this).attr('title') && $(this).attr('title').length > 0) ? $(this).attr('title') : null;
            }
        }
    });
    return oTitle;
};

SimpleGallery.prototype.resetAnchors = function() {
    $(settings.anchors).removeClass(settings.selectedAcnhorClass);
};

SimpleGallery.prototype.init = function() {
    if (this.anchor)//If overlay has not been loaded
    {
        this.resetAnchors();
        $(this.anchor).addClass(settings.selectedAnchorClass);
        this.load();
    }
};
}
SimpleGallery._initialized = true;

//If reference to anchor element has been passed in, set it
this.anchor = (typeof arguments[0] != 'undefined') ? arguments[0] : null;
this.init(); //Initiate
}

$.fn.SimpleGallery = function(options) {

    settings = jQuery.extend({
        anchors: this,
        selectedAnchorClass: 'sg-current',
        fallbackBkgColor: '#1a1a1a',
        overlay: '.overlay',
        loadIcon: '/asset/img/layout/ajax-loader-1a1a1a.gif',
        imageLoadTimeout: 30000,
        overlayClass: 'overlay',
        contentClass: 'content',
        overlayResizeEffect: 'easeOutQuad',
        legendClass: 'legend',
        closeBtnClass: 'close',
        closeBtnText: 'x',
        navButtonsPos: 'after', //before || after
        nextBtnClass: 'next',
        previousBtnClass: 'previous',
        nextBtnText: 'next',
        previousBtnText: 'previous',
        overlayOuterMargin: 10,
        reLoadIcon: '/asset/img/layout/overlay-ajax-loader.gif'
    }, options);

    return this.each(function() {
        $(this).click(function($e) {
            $e.preventDefault();
            var sg = new SimpleGallery(this);
        });
    });
};

})(jQuery);



