/************************************************/
/* Plugin: Gallery								*/
/* Author: Brandon Drake						*/
/* Copyright: Tech Media Network 2011			*/
/* Version: 1.1.1     							*/
/* Date: Nov 14, 2011							*/
/* Requires:                                    */
/*  jCarousel                                   */
/* NOTES: Only works with element ID			*/
/*  This is a branch of the original            */
/*  jQuery.imgSlider.js                         */
/************************************************/

(function ($) {
    var defaults = {
        path: '',
        thumbPath: '',
        fullPath: '',
        columns: 3,
        imgHeight: 50,
        imgWidth: 75,
        jsonScript: '',
        jsonObject: null,
        ajaxData: {},
        cssClass: 'jcarousel-skin-tango',
        onComplete: $.noop,
        showCount: false,
        imgEvent: 'mouseenter',
        afterEvent: $.noop,
        imgEventOverride: $.noop,
        showButtons: false,
        sliderEvent: $.noop,
        sponsored: false,
        sponsorHref: '',
        sponsorSrc: ''
    },
	methods = {
	    _init: function (options) {
	        return this.each(function () {
	            var $this = $(this),
					data = $this.data('gallery');

	            if (!data) {
	                if (options) {
	                    options = $.extend({}, defaults, options)
	                }

	                var elementID = $this.attr('id'),
						sliderID = elementID + '_slider',
						counterID = elementID + '_ct',
						targetID = elementID + "_target",
						data = {
						    element: $this,
						    elementID: elementID,
						    sliderID: sliderID,
						    counterID: counterID,
						    targetID: targetID,
						    options: options,
						    imageCache: null,
						    total: 0
						};

	                if (options.jsonObject === null) {
	                    methods._processAjax(data);
	                } else {
	                    methods._process(data);

	                    if (options.onComplete !== $.noop) {
	                        options.onComplete.call();
	                    }
	                }
	            }
	        });
	    },
	    _carousel_initCallBack: function (carousel, data) {
	        // Previous Button Click
	        $("#" + data.elementID + " .big_img .prev").bind('click', function (e) {
	            var slider = '#' + data.sliderID,
                    target = $("#" + data.targetID),
                    num = target.data("num") - 1;

	            num = num > 0 ? num : data.total;

	            carousel.scroll($.jcarousel.intval(num));
	            data.caller = "prev";
	            methods._changeImage(num, data);
	        });

	        // Nav Previous Button Click
	        $("#" + data.elementID + " .nav_prev").bind('click', function (e) {
	            e.preventDefault();

	            var slider = '#' + data.sliderID,
                    target = $("#" + data.targetID),
                    num = target.data("num") - 1;

	            num = num > 0 ? num : data.total;

	            carousel.scroll($.jcarousel.intval(num));
	            data.caller = "nav_prev";
	            methods._changeImage(num, data);
	        });

	        // Next Button Click
	        $("#" + data.elementID + " .big_img .next").bind('click', function (e) {
	            data.caller = "next";
	            methods._next(carousel, data);
	        });

	        // Nav Next Button Click
	        $("#" + data.elementID + " .nav_next").bind('click', function (e) {
	            e.preventDefault();
	            data.caller = "nav_next";
	            methods._next(carousel, data);
	        });

	        // Main Image Click
	        $("#" + data.elementID + "_target").bind('click', function () {
	            data.caller = "large_image";
	            methods._next(carousel, data);
	        });
	    },
	    _changeImage: function (num, data, stop_afterevent) {
	        var options = data.options,
				target = $("#" + data.targetID),
				bigImg = $("#" + data.elementID + " .big_img"),
	            pos = bigImg.offset(),
                obj = options.jsonObject[num - 1],
				e = {
				    pageX: (pos.left - 10) + (bigImg.width() / 2),
				    pageY: (pos.top - 10) + (bigImg.height() / 2)
				},
				imgSrc = (options.path + obj.img),
                imgTxt = obj.name;

	        $("#" + data.elementID + " .gallery_header_right").text(imgTxt);
	        methods._setActive(num, data);

	        $('#gallery_loading').css({
	            "top": (e.pageY) + "px",
	            "left": (e.pageX) + "px"
	        }).show();

	        target.attr('src', imgSrc);
	        target.data('num', num);

	        if (options.showCount === true) {
	            $('#' + data.counterID).text('IMAGE ' + num + ' of ' + data.total.toString());
	        }

	        if (typeof stop_afterevent == 'undefined' || !stop_afterevent) {
	            if (options.afterEvent !== $.noop) {
	                options.afterEvent.call(this, data.caller);
	            }
	        }
	    },
	    _next: function (carousel, data) {
	        var target = $("#" + data.targetID),
                num = parseInt(target.data("num")) + 1;

	        num = (num <= data.total ? num : 1);

	        carousel.scroll($.jcarousel.intval(num));
	        methods._changeImage(num, data);
	    },
	    next: function () {
	        var data = $(this).data("gallery");
	        methods._next($("#" + data.sliderID).data("jcarousel"), data);
	    },
	    _process: function (data) {
	        var jsonData = data.options.jsonObject;

	        if (jsonData.length > 0) {
	            var options = data.options,
					total = data.total = jsonData.length,
					imgSrc,
					imgNum,
					html = '<div id="ad_g01"></div>\n' +
                        '<div class="gallery_header">\n' +
							'<div class="gallery_header_left">\n' +
								'<ul id="' + data.sliderID + '" class=" ' + options.cssClass + '" >\n',
                    loader = '<div id="gallery_loading" ><p><img src="http://www.laptopmag.com/images/loading.gif" /></p></div>',
                    sponsorImg = '<img src="' + options.sponsorSrc + '" alt="" />',
                    sponsorLink = '<a href="' + options.sponsorHref + '" rel="">' + sponsorImg + '</a>',
					sponsor = ((options.sponsored === true) ? '<div class="gallery_sponsor">' + ((options.sponsorHref !== '') ? sponsorLink : sponsorImg) + '</div>\n' : ''),
					counter = '<span id="' + data.counterID + '">IMAGE 1 of ' + total + '</span>',
	                galleryBody =
						'<div class="gallery_body">' +
							'<div class="gallery_left">' +
								'<div class="big_img">' +
									((options.showButtons === true) ? '<div class="prev"><div class="arrow prev_arrow" /></div>\n' : '') +
									'<img id="' + data.elementID + '_target" src="" alt="" />\n' +
									((options.showButtons === true) ? '<div class="next"><div class="arrow next_arrow" /></div>\n' : '') +
								'</div>\n' +
							'</div>\n' +
							'<div class="gallery_right">' +
								sponsor +
								'<div id="ad_g02"></div> ' +
							'</div>\n' +
						'</div>\n',
	                tempImg = [],
					tempCt = 1;

	            // Generate Thumbnail images HTML
	            for (var i = 0; i < total; i++) {
	                //Has to be done this way to make IE6 and IE7 happy
	                var imgType = jsonData[i].img.match(/\.(\w+)$/);

	                if (imgType) {
	                    imgType = imgType[1];
	                }
	                else {
	                    imgType = 'jpg';
	                }

	                html += '<li ' + ((i === 0) ? 'class="active"' : '') + '><img src="' + options.path + options.thumbsPath + jsonData[i].image_id + '.' + imgType +
					'" alt="' + jsonData[i].name +
					'" height="' + options.imgHeight + 'px" width="' + options.imgWidth + 'px" /><p>' + jsonData[i].name + '</p></li>';

	                // Set the first image as the image to display
	                if (i === 0) {
	                    imgSrc = (options.path + jsonData[0].img);
	                    imgNum = 1;
	                    imgTxt = jsonData[0].name;
	                }
	            }

	            html += '</ul>\n' +
						'<div class="gallery_header_nav">' +
							'<span class="nav_prev">&lt; previous image</span>' + counter + '<span class="nav_next">next image &gt;</span>' +
						'</div>\n' +
					'</div>' +
					'<div class="gallery_header_right">\n' +
						imgTxt +
					'</div>\n' +
				'</div>\n' +
				galleryBody;

	            data.element.html(html); // Added in this manner to make IE6 & 7 happy

	            var slider = $('#' + data.sliderID),    // Set it here so we only look for it once
					target = $('#' + data.targetID);    // Set it here so we only look for it once;

	            slider.find('li img').each(function () {
	                $(this).data('num', tempCt)
	                tempCt++;
	            });

	            // Set the initial main image information
	            target.attr('src', imgSrc);
	            target.data('num', imgNum);

	            slider.jcarousel({
	                scroll: options.columns,
	                initCallback: function (carousel) {
	                    methods._carousel_initCallBack(carousel, data);
	                }
	            });

	            if (options.sliderEvent !== $.noop) {
	                $("#" + data.elementID + " .jcarousel-prev").click(function () {
	                    options.sliderEvent.call(this, "prev");
	                });

	                $("#" + data.elementID + " .jcarousel-next").click(function () {
	                    options.sliderEvent.call(this, "next");
	                });
	            }

	            if (options.imgEventOverride === $.noop) {
	                $('#' + data.sliderID + ' .jcarousel-item').bind(options.imgEvent, function () {
	                    var me = $(this),
                            num = me.attr('jcarouselindex');

	                    if (!me.hasClass("active")) {
	                        data.caller = "thumbnail";
	                        methods._changeImage(num, data);
	                    }
	                });
	            } else {
	                options.imgEventOverride.call();
	            }

	            if (options.showButtons === true) {
	                $("#" + data.elementID + " .big_img .prev, #" + data.elementID + " .big_img .next").hover(function () {
	                    $(this).find('.arrow').stop(true, false).fadeTo("fast", 1.0);
	                }, function () {
	                    $(this).find('.arrow').stop(true, false).fadeTo("slow", 0);
	                }).find('.arrow').css("opacity", 0);
	            }

	            // Add the loading image to the bottom of the page
	            $(function () {
	                if (document.getElementById('gallery_loading') == null) {
	                    $('body').append(loader);
	                }
	            });

	            // AJAX Load the image
	            target.load(function () {
	                //console.log("Loading");
	                $('#gallery_loading').hide();
	            })
				.error(function () {
				    //console.log("Loading Failed");
				    $('#gallery_loading').hide();
				});

	            $("#" + data.elementID).data('gallery', data);
	        }
	    },
	    _processAjax: function (data) {
	        var options = data.options;

	        $.ajax({
	            url: options.jsonScript,
	            type: 'GET',
	            data: options.ajaxData,
	            dataType: 'json',
	            success: function (jsonData) {
	                options.jsonObject = jsonData;
	                methods._process(data);
	            },
	            complete: function (jqXHR, textStatus) {
	                if (options.onComplete !== $.noop) {
	                    options.onComplete.call();
	                }
	            }
	        });
	    },
	    _setActive: function (num, data) {
	        var liElems = $("#" + data.sliderID + " li"),
	            nthChild = $(liElems[num - 1]);

	        liElems.removeClass("active");
	        nthChild.addClass("active");
	    }
	}

    $.fn.gallery = function (method) {
        if (methods[method]) {
            return methods[method].apply(this, Array.prototype.slice.call(arguments, 1));
        } else if (typeof method === 'object' || !method) {
            return methods._init.apply(this, arguments);
        } else {
            $.error('Method ' + method + ' does not exist on jQuery.gallery');
        }
    };
})(jQuery);
