(function(jQuery) {
 
	jQuery.fn.interactiveTopList = function(o)
	{	
	    if (!o) {
	        o = {};
	    }
		return this.each(function() {
			window[this.id+"Inst"] = new jQuery.interactiveTopList(this, o);
		});
	};
	
	jQuery.interactiveTopList = function (e, o)
	{  
	    this.cont                  =   e;
	    this.templateID            =   o.templateID || "topListItemTeplate";
	    this.list                  =   o.list || [{src:"",name:"No List",details:"No List"}];
	    this.numPerPage            =   o.numPerPage     || 6;
	    this.smallWidth            =   o.smallWidth     || 100;
	    this.bigWidth              =   o.bigWidth       || 120;
	    this.currentPage           =   o.startPage      || 1;
	    this.numPages              =   Math.ceil(this.list.length / this.numPerPage);
	    this.animating             =   0;
	    this.slideDuration         =   1000;
	    this.slideEasing           =   "easeOutBack";
	    this.growDuration          =   80;
	    this.contractDuration      =   400;
	    this.disableAnimation      =   false;
		this.init();
	};
	
	jQuery.interactiveTopList.fn = jQuery.interactiveTopList.prototype;
	
 	jQuery.interactiveTopList.fn.extend = jQuery.interactiveTopList.extend = jQuery.extend;
	
	jQuery.interactiveTopList.fn.extend({
	    init: function(){
	        this.pageHasLoaded();
	    },
	    length: function() {
	        return $(this.list).find("li").length;
	    },
	    onItemMouseOver: function(e) {
	        if (this.disableAnimation) {
	            return false;
	        }
	        /*if ($(e).attr("growing") == 2) {
	            //in the middle of a shrink animation so don't make it bigger again
                return false;
	        }*/
	    
	        var im = $(e).find("img").get(0);
	        if ($(im).attr("smHeight") === undefined) {
	           $(im).attr("smHeight", $(im).height());
	        }
	        $(e).attr("growing", 1);
	        $(e).css({height: "200px"});
	        $(this.cont).css({overflow: "visible"}).parent().css({overflow: "visible"});
	        
	        var self = this;
	        
	        $(e).animate({
	            width: this.bigWidth
	        }, this.growDuration, function(){
	            if ($(e).attr("growing") == 1) {
    	            $(e).find(".topListDetails").css({display: "block"});
    	            $(e).find(".topListDetailsCont").css({
                                                            width: (self.bigWidth - 6)+"px",
                                                            position: 'absolute',
                                                            color: "#000",
    	                                                    backgroundColor: '#fff',
    	                                                    borderRight: "1px solid #ddd",
    	                                                    borderLeft: "1px solid #ddd",
    	                                                    borderBottom: "1px solid #ddd"});
                    $(e).attr("growing", 0);
	            }
	        });
	    
	        $(im).animate({
	            width: this.bigWidth,
	            height: $(im).attr("smHeight") * (this.bigWidth / this.smallWidth),
	            opacity: 1.0
	        }, this.growDuration);
	    },
	    onItemMouseOut: function(e) {
	        if (this.disableAnimation) {
	            return false;
	        }
	        
	        if ($(e).attr("growing") === undefined) {
	            // if growing attr isn't set then this item hasn't been grown yet so don't do anything
	            return false;
	        }
	        
	        
	        var im = $(e).find("img").get(0);
	        
	        $(e).attr("growing", 2);
            $(e).find(".topListDetails").css({display: "none"});
            $(e).find(".topListDetailsCont").css({
                                                    position: 'relative',
                                                    width: "100%",
                                                    color: "#666",
                                                  backgroundColor: 'transparent',
    	                                          borderRight: "none",
                                                  borderLeft: "none",
                                                  borderBottom: "none"});
            $(e).css({height: ""});
            $(this.cont).css({overflow: "hidden"});
            
	        this.doAnimation(e, {
	            width: this.smallWidth
	        }, this.contractDuration, function(){
	            if ($(e).attr("growing") == 2) {
	                //if close animation hasn't been superceded by another open
	               $(e).attr("growing", 0);
	            }
	        });
	  
	        this.doAnimation(im, {
	            width: this.smallWidth,
	            height: $(im).attr("smHeight"),
	            opacity: 0.7
	        }, this.contractDuration);
	    },
	    showPage: function(pageNum, slideDirection) {
	        if (pageNum < 1 || pageNum > this.numPages) {
	            return false;
	        }
	        if (slideDirection && slideDirection !== "back" && slideDirection !== "forward") {
	            slideDirection = false;
	        }
	        var oldPage = $(this.cont).find(".topListCurrentPage").get(0);
	        var newPage = $(oldPage).clone();
	        //first item for the new page's arrray position
	        var itemNo = (pageNum - 1) * this.numPerPage;
	        //correction as items are NOT numerically ordered in source due to float positioning
	        var itemOrder = [2, 1, 0, 3, 4, 5];
	        
	        var self = this;
	        
	        $(newPage).find(".topListItem").each(function(i){
	            var data = self.list[itemNo + itemOrder[i]];
	            if (!data) {
	                $(this).css({visibility:"hidden"});
	            } else {
	                data = self.removeHtmlChars(data);
	                $(this).css({visibility:"visible"});
    	            $(this).find("img").attr("src", data.img);
    	            $(this).find("img").attr("alt", data.name+" Image");
    	            $(this).find("a").attr("href", data.url);
    	            $(this).find("a").attr("title", "See "+data.name+" Page");
    	            $(this).find(".topListNumber").text((itemNo + itemOrder[i]+1)+".");
    	            $(this).find(".topListName").text(data.name);
    	            $(this).find(".topListDetails").text(data.details);
	            }
	        });
	        
	        this.currentPage = pageNum;
	        
	        if (slideDirection) {
	           $(this.cont).css({overflow: "hidden"});
	            //remove current page class
	           $(oldPage).removeClass("topListCurrentPage");
	           if (slideDirection === "forward") {
	               $(newPage).css({
        	            left: $(oldPage).width()+"px"
        	        }).appendTo($(this.cont));
        	        
        	        this.doAnimation(oldPage, {left: "-"+$(oldPage).width()+"px"}, this.slideDuration,null, this.slideEasing);
        	        this.doAnimation(newPage, {left: "0px"}, this.slideDuration, function(){self.pageHasLoaded()}, this.slideEasing);
	           } else {
	               $(newPage).css({
        	            left: "-"+$(oldPage).width()+"px"
        	        }).appendTo($(this.cont));
        	        
        	        this.doAnimation(oldPage, {left: $(oldPage).width()+"px"}, this.slideDuration,null, this.slideEasing);
        	        this.doAnimation(newPage, {left: "0px"}, this.slideDuration, function(){self.pageHasLoaded()}, this.slideEasing);
	           }
	        } else {
	           $(oldPage).remove();
	           $(newPage).appendTo($(this.cont));
	           this.pageHasLoaded;
	        }
	    },
	    nextPage: function() {
	        if (this.disableAnimation) {
	            return false;
	        }
	        this.showPage(this.currentPage+1, "forward");	        
	    },
	    prevPage: function() {
	        if (this.disableAnimation) {
	            return false;
	        }
	        this.showPage(this.currentPage-1, "back");
	    },
	    pageHasLoaded: function() {
	        var self = this;
	        $(this.cont).css({overflow: "hidden"});
	        
	        $(this.cont).parent().parent().find(".topListThumb").find("a").each(function(){
	            $(this).attr("title", "").click(function(){
	                return false;
	            });
	        });
	        
	        $(this.cont).find(".topListPage").each(function(){
	            if ($(this).hasClass('topListCurrentPage')) {
	                $(this).find(".topListItem").each(function(){
	                    $(this).hover(function(){
	                        return self.onItemMouseOver(this);
	                    },function(){
	                        return self.onItemMouseOut(this);
	                    }).find("img").css({opacity: 0.7});
	                });
	            } else {
	                $(this).remove();
	            }
	        });
	        
            $(this.cont).parent().find(".topListNextButton").each(function(){
                if (self.currentPage == self.numPages) {
                    $(this).hide();
                } else {
                    $(this).show();
                }
                $(this).unbind("click").click(function(){
                    self.nextPage();
                    return false;
                });
                
            });
            $(this.cont).parent().find(".topListPrevButton").each(function(){
                if (self.currentPage == 1) {
                    $(this).hide();
                } else {
                    $(this).show();
                }
                $(this).unbind("click").click(function(){
                    self.prevPage();
                    return false;
                });
            });
	    },
	    doAnimation: function(e, css, dur, cb, easing) {
	        if (!easing) {
	            easing = "jswing";
	        }
	        this.animating++;
	        var self = this;
	        $(e).animate(css, dur, easing, function(){
	            self.animating--;
	            if (cb) {
	                cb();
	            }
	        });
	    },
	    removeHtmlChars: function(obj) {
	        switch (typeof obj) {
	            case "string":
	               return obj.replace(/&amp;/g, '&' );
	               break;
                case "object":
                   for (var k in obj) {
                       obj[k] = this.removeHtmlChars(obj[k]);
                   }
                   return obj;
                   break;
                default:
                    return obj;
                    break;
	        }
	    }
    });
    
})(jQuery);
