// Copyright ©2009 Aaron Vanderzwan, by Aaron Vanderzwan
// Thanks to Skye Giordano for the suggestion of the resizeMsg option.
//
// LICENSE
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.




(function($) {
// The maxImages plugin resizes an image dynamically, according to the width of the browser.
jQuery.fn.maxImage = function(options) {

 var resizeMsgDefaults = {show: false, location: 'before', message: 'Original: ([w]w x [h]h)'};

 // var opts = $.extend({}, $.fn.maxImage.defaults, options);
 var opts = jQuery.extend({
 wait: true,
 imageArray: [],
 maxFollows: 'both', // Options: width, height, both
 verticalOffset: 0,
 horizontalOffset: 0,
 leftSpace: 0,
 topSpace: 0,
 rightSpace: 0,
 bottomSpace: 0,
 overflow: 'hidden',
 position: 'absolute',
 isBackground: false,
 zIndex: -10,
 verticalAlign: 'bottom',
 horizontalAlign: 'left',
 maxAtOrigImageSize: false,
 slideShow: false,
 slideDelay: 5,
 slideShowTitle: true,
 loaderClass: 'loader',
 resizeMsg: resizeMsgDefaults
 }, options);

 // var resizeDefaults = {show: false, location: 'before', message: '(resized)'};
 opts.resizeMsg = jQuery.extend(resizeMsgDefaults, options.resizeMsg)

 // Cache jQuery object
 var jQueryMatchedObj = this;

 function _initialize() {
 _start(this,jQueryMatchedObj);
 return false;
 }

 function _start(image,jQueryMatchedObj) {
 if( opts.slideShow ){
 _setup_slideshow(jQueryMatchedObj);
 } else if ( opts.isBackground ){
 Background._setup_background(image);
 } else {
 Others._setup_others(image,opts);
 }
 }

 Others = {
 _setup_others: function(image,opts){
 $this = $(image);

 $(window).load(function(){
 _get_orig_data($this);
 _size_image($this);
 Others._configure_css(image,opts);

 $(window).resize(function(){
 _size_image($this);
 });
 });
 },
 _configure_css: function(image,opts){
 if(opts.position == 'absolute') {

 $(image).css({
 'overflow': 'hidden',
 'left': opts.leftSpace,
 'top': opts.topSpace,
 'position': 'absolute'
 });

 if(opts.verticalAlign == 'bottom'){
 $(image).css({'bottom':opts.bottomSpace});
 }
 if(opts.horizontalAlign == 'right'){
 $(image).css({'right':opts.rightSpace});
 }
 } else {
 $(image).css({
 'margin-top': opts.topSpace,
 'margin-right': opts.rightSpace,
 'margin-bottom': opts.bottomSpace,
 'margin-left': opts.leftSpace,
 'position': 'relative'
 });
 }
 }
 }

 Background = {
 _setup_background: function(image){
 $this = $(image);
 $this.hide();

 Background._configure_css(image);
 $(window).load(function(){
 _get_orig_data($this);
 _size_image($this);
 $this.show();

 $(window).resize(function(){
 _size_image($this);
 });
 });

 },
 _configure_css: function(image){
 // If position is set to absolute (or if isBackground)
 $(image).css({
 'z-index': opts.zIndex
 });
 if(opts.position == 'absolute') {
 $(image).css({
 'overflow': 'hidden',
 'left': opts.leftSpace,
 'top': opts.topSpace,
 'position': 'absolute'
 });

 $('html').css({'overflow-y':opts.overflow});

 if(opts.verticalAlign == 'bottom'){
 $(image).css({'bottom':opts.bottomSpace});
 }
 if(opts.horizontalAlign == 'right'){
 $(image).css({'right':opts.rightSpace});
 }
 } else {
 $(image).css({
 'margin-top': opts.topSpace,
 'margin-right': opts.rightSpace,
 'margin-bottom': opts.bottomSpace,
 'margin-left': opts.leftSpace,
 'position': 'relative'
 });
 }
 }
 }


 // SLIDESHOW FUNCTIONS
 function _setup_slideshow (jQueryMatchedObj){
 _build_slideshow_structure(jQueryMatchedObj);

 opts.imageArray.length = 0;

 if( jQueryMatchedObj.length == 1){
 opts.imageArray.push(new Array(objClicked.getAttribute('src'),objClicked.getAttribute('title')));
 } else {
 for ( var i = 0; i < jQueryMatchedObj.length; i++ ) {
 opts.imageArray.push(new Array(jQueryMatchedObj[i].getAttribute('src'),jQueryMatchedObj[i].getAttribute('title')));
 $(jQueryMatchedObj[i]).attr('original',$(jQueryMatchedObj[i]).attr('src')).attr('src','');
 }
 }
 _loads_image(0);
 _configure_css();
 }

 function _build_slideshow_structure() {
 for ( var i = 0; i < jQueryMatchedObj.length; i++ ) {
 $(jQueryMatchedObj[i]).addClass('slides slide-'+i).after('<div class="slideTitle">'+$(jQueryMatchedObj[i]).attr('title')+'</div>');
 }
 $('.slideTitle').hide().css({
 'padding':'10px',
 'background':'#e0e0e0',
 'position':'absolute',
 'bottom':'0',
 'right':'5%',
 'opacity':'0.8'
 });
 }


 function _loads_image(nums){

 var currentImage = nums;

 var objImagePreloader = new Image();
 objImagePreloader.onload = function() {
 $('.slide-'+currentImage).attr('src',opts.imageArray[currentImage][0]);
 _get_orig_data($('.slide-'+currentImage));
 _size_image($('.slide-'+currentImage));

 $(window).resize(function(){
 _size_image($('.slide-'+currentImage));
 });

 if(currentImage==0){
 _start_timer();
 }

 if(currentImage < opts.imageArray.length-1){
 currentImage++;
 _loads_image(currentImage);
 }

 }
 objImagePreloader.src = opts.imageArray[currentImage][0];
 }

 function _start_timer() {
 var currentSlide = 0;

 _configure_css();

 // Hide the loading graphic
 $('.'+opts.loaderClass).hide();

 // Fade in first image
 $('.slide-'+currentSlide).css({'z-index':opts.zIndex}).fadeIn();

 // If user wants to show titles, use this option
 if(opts.slideShowTitle){
 $('.slide-'+currentSlide).next('.slideTitle').css({'z-index':opts.zIndex+1}).fadeIn();
 }

 // Start timer for slideshow
 var slideInterval = setInterval(function(){
 if(currentSlide < opts.imageArray.length-1){
 currentSlide++;
 lastSlide = currentSlide-1;
 } else {
 currentSlide=0;
 lastSlide = opts.imageArray.length-1;
 }

 $('.slide-'+lastSlide).css({'z-index':opts.zIndex-1}).fadeOut('slow');
 $('.slide-'+currentSlide).css({'z-index':opts.zIndex}).fadeIn('slow');
 if(opts.slideShowTitle){
 next_title(currentSlide,lastSlide);
 }
 }, (opts.slideDelay*1000));
 }

 function _configure_css(){
 for(i=0;i<opts.imageArray.length;i++){
 // Style the slide
 if(opts.position == 'absolute') {
 $('.slide-'+i).css({
 'position': 'absolute',
 'overflow': 'hidden'
 });

 $('html').css({'overflow-y':opts.overflow});

 if(opts.verticalAlign == 'bottom'){
 $('.slide-'+i).css({'bottom':opts.bottomSpace});
 }else{
 $('.slide-'+i).css({'top':opts.topSpace});
 }

 if(opts.horizontalAlign == 'right'){
 $('.slide-'+i).css({'right':opts.rightSpace});
 }else{
 $('.slide-'+i).css({'left':opts.leftSpace});
 }

 } else {
 $('.slide-'+i).css({
 'margin-top': opts.topSpace,
 'margin-right': opts.rightSpace,
 'margin-bottom': opts.bottomSpace,
 'margin-left': opts.leftSpace,
 'position': 'relative'
 });
 }


 // Style the title
 $('.slide-'+i).next('.slideTitle').css({
 'position':'absolute',
 'bottom':0,
 'right':'5%'
 });
 }
 }


 function next_title(currentSlide,lastSlide){
 $('.slide-'+lastSlide).next('.slideTitle').fadeOut();
 $('.slide-'+currentSlide).next('.slideTitle').fadeIn();
 }


 // BROAD FUNCTIONS - FOR EACH SECTION
 function _get_orig_data(image){
 $this = image;

 $this.attr('origWidth', $this.width());
 $this.attr('origHeight', $this.height());
 $this.attr('ratio', find_ratio($this.width(),$this.height()));
 }

 function _size_image(image){
 $this = image;

 var originalWidth = to_i($this.attr('origWidth'));
 var originalHeight = to_i($this.attr('origHeight'));
 var ratio = $this.attr('ratio');

 if(originalWidth == 0 || originalHeight == 0){
 setTimeout(function(){
 _get_orig_data(image);
 _size_image(image);
 }, 100);
 return;
 }

 var width_and_height = [];
 width_and_height = find_width_and_height(originalWidth,originalHeight,ratio);

 $this.width( width_and_height[0] );
 $this.height( width_and_height[1] );

 _show_resize_message(originalWidth,originalHeight,image);
 }

 function _show_resize_message(originalWidth,originalHeight,image){
 if( (to_i($this.width()) != originalWidth || to_i($this.height()) != originalHeight) && opts.resizeMsg.show){
 $(".maximage_resized").remove();

 // Replace [w] and [h] with their respective width or height
 opts.resizeMsg.message = opts.resizeMsg.message.replace('[w]',originalWidth).replace('[h]',originalHeight);

 var insertStr = '<div class="maximage_resized">' + opts.resizeMsg.message + '</div>';
 if(opts.resizeMsg.location.toLowerCase() == "before"){
 $this.before(insertStr);
 } else {
 $this.after(insertStr);
 }
 }
 }

 function find_width_and_height(originalWidth,originalHeight,ratio) {
 var pageWidth = $(window).width() - opts.horizontalOffset;
 var pageHeight = $(window).height() - opts.verticalOffset;

 if(!opts.isBackground){
 if(opts.maxFollows=='both'){
 max_follows_width(pageWidth,ratio);

 if( height > pageHeight ){
 max_follows_height(pageHeight,ratio);
 }
 } else if (opts.maxFollows == 'width'){
 max_follows_width(pageWidth,ratio);
 } else if (opts.maxFollows == 'height'){
 max_follows_height(pageHeight,ratio);
 }
 }else{
 width = pageWidth + 40;
 height = width/ratio;

 if( height < pageHeight ){
 height = pageHeight - (opts.topSpace + opts.bottomSpace);
 width = height*ratio;
 }
 }

 // If maxAtRatio == true and your new width is larger than originalWidth, size to originalWidth
 if ( opts.maxAtOrigImageSize && width > originalWidth){
 arrayImageSize = new Array(originalWidth,originalHeight);
 }else{
 arrayImageSize = new Array(width,height);
 }
 return arrayImageSize;
 }

 function max_follows_height(pageHeight,ratio){
 height = pageHeight - (opts.topSpace + opts.bottomSpace); // Page Height minus topSpace and bottomSpace
 width = height*ratio;
 }

 function max_follows_width(pageWidth,ratio){
 width = pageWidth - (opts.leftSpace + opts.rightSpace); // Page Width minus leftSpace and rightSpace
 height = width/ratio;
 }

 function find_ratio(width,height) {
 width = to_i(width);
 height = to_i(height);
 var ratio = width/height;
 ratio = ratio.toFixed(2);
 return ratio;
 }

 function to_i(i){
 last = parseInt(i);
 return last;
 }

 // private function for debugging
 function debug($obj) {
 if (window.console && window.console.log) {
 window.console.log($obj);
 }
 }

 return this.each(_initialize);
};


})(jQuery);
