(function($) {      
	$.fn.showhide = function(options) {
		
		var opts = $.extend({}, $.fn.showhide.defaults, options);
		//example of expected HTML for a given target element
		var markup = '\r\n\r\n<div class="{item:\'X\'}">\r\n\</div>';
		// markup for dragable element added to the top of each dragable item
		var draggable_div = '<div id="dragger" style="width:100%;height:15px;cursor:move;"></div>';


		if(opts.closer != null){
			if(opts.closer_img != null){
				var closer = '<div class="closer" style="cursor:pointer;position:absolute;"><img src="'+opts.closer_img+'" alt="close" /></div>';
			}else{
				var closer = '<div class="closer" style="cursor:pointer;position:absolute;">Hide [X]</div>';
			}
		}
		
		this.each(function(e) {
			
			 // To avoid scope issues, use 'base' instead of 'this'
			// to reference this class from internal events and functions.
			base = $(this);			
			
			//if the first occurance of the # in attr('href') is greater than zero then it is due to IE bug
			if($(this).attr('href').indexOf("#") > 0){
				//bug fix for IE miss hadnling of attr('href')
				// indexOf returns position of first #
				//substing returns the attr('href') string from the position of first #
				this.target_id = $($(this).attr('href').substring($(this).attr('href').indexOf("#")));				
			}else if($(this).attr('href').indexOf("#") == 0){
				this.target_id = $($(this).attr('href'));
			}else{
				//get the link extension to see if it's a valid img format
				link_extension = $(this).attr('href').substring($(this).attr('href').lastIndexOf(".")+1,$(this).attr('href').length);

				//get the number of img in the target id to generate a new id
				switch(link_extension.toLowerCase()){
					case "jpg":
					case "gif":
					case "png":
					case "bmp":			
						//count the number of image and then add one to use in a unique ID
						current_cnt = ($(opts.target+' img').length + 1);
						//create unique ID
						current_id = 'img-' + current_cnt;						
						
						//create an img with with the unique id
						//the img src is the href of the targeting link
						//add on meta data to show the image order and set the first img as visible
						$(document.createElement("img")).attr({ src: $(this).attr('href'), alt: $(this).attr('href'), id: current_id }).addClass("{item:'"+current_cnt+"'}").appendTo(opts.target);   
						
						//preload the image into the page
						preloadImages($(this).attr('href'));
						
						//give the current image an id
						this.target_id = $('#'+current_id);
					break;
				}
			}
			
			//only continue if the targeted ID exists on the page
			if(this.target_id.length > 0 ){
				
				//if the selected option is true then set the first target id panel to be visible
				if(typeof opts.selected == 'boolean' && opts.selected==true){
					
					if(jQuery.fn.metadata){
						//use meta data to find the first item on the page
						//and make it active
						data = this.target_id.metadata();					
						
						if (data.item && data.item == '1' ){
							
							//set target to active
							this.target_id.addClass('tgl-active');
							this.target_id.show();
							
							//set base element to selected		
							if(typeof($(this).parents('li')) != 'undefined'){
								$(this).parent('li').addClass('tgl-selected');//make sure any clicked link has parent li class called 'tgl-selected' if present
								if(opts.selectedLinkOpacity != null){
									//$(this).parent('li').stop().animate({'opacity':opts.selectedLinkOpacity});
								}
							}else{
								$(this).addClass('tgl-selected');//make sure any clicked link has a class called 'tgl-selected'
								if(opts.selectedLinkOpacity != null){
									//$(this).stop().animate({'opacity':opts.selectedLinkOpacity});
								}
							}
							
							if(opts.animate_type != 'custom'){
								this.target_id.css("z-index","100");
							}
							
							//append a closing link and attach action to it
							if(opts.closer != null){
								this.target_id.append(closer);
							}
							
							//only call draggable object if it exists
							if(jQuery.fn.draggable){
								
								var current_id = this.target_id.attr('id');
								
								if(opts.closer != null){
									//apply starting position to given id
									$('div.closer').click(function() { resetPosition(current_id); });
								}
							
								this.target_id.draggable({ cursor: 'crosshair'});
								this.target_id.data("right",this.target_id.css('right')).data("top",this.target_id.css('top'));
							}
							
						}else{
							// set all other items default state
							if(opts.animate_type.length > 0){
								switch(opts.animate_type){
									case "opacity":
										//hide all sibling active divs, fade them out and take away the active class using chaining
										this.target_id.css({'opacity':'0.1'});
									break;
									default:
										this.target_id.hide();
									break;
								}
							}else{
								this.target_id.hide();
							}
						}
					}else{
						alert('Please make sure that you are using the metadata plugin using the following meta data markup'+markup);					
					}
					
				//if the selected option is false then hide all target id panel
				}else if(typeof opts.selected == 'boolean' && opts.selected==false){
					this.target_id.hide();
				}
				//if the selected option is set to that of a specific id the make that id active
				else if(typeof opts.selected == 'string' && this.target_id.attr('id') == opts.selected){
					if(this.target_id == opts.selected){
						//set base element to selected
						if(typeof($(this).parents('li')) != 'undefined'){
							$(this).parent('li').addClass('tgl-selected');//make sure any clicked link has parent li class called 'tgl-selected' if present
							if(opts.selectedLinkOpacity != null){
								//$(this).parent('li').stop().animate({'opacity':opts.selectedLinkOpacity});
							}
						}else{
							$(this).addClass('tgl-selected');//make sure any clicked link has a class called 'tgl-selected'
							if(opts.selectedLinkOpacity != null){
								//$(this).stop().animate({'opacity':opts.selectedLinkOpacity});
							}
						}
						//set association link to active
						this.target_id.addClass('tgl-active');
						//show target on page
						this.target_id.show();
						//set targets z-index
						this.target_id.css("z-index","100");
						
						if(opts.closer != null){
							alert('here');
							//append a closing link and attach action to it
							this.target_id.append(closer);
						}
						
						//only call draggable object if it exists
						if(jQuery.fn.draggable){
							
							var current_id = this.target_id.attr('id');
							
							if(opts.closer != null){
								//apply starting position to given id
								$('div.closer').click(function() { resetPosition(current_id); });
							}
							
							this.target_id.draggable({ cursor: 'crosshair'});
							this.target_id.data("right",this.target_id.css('right')).data("top",this.target_id.css('top'));
						}
					}
				//hide all other ids
				}else{
					this.target_id.hide();
				}
				
				/**/
				//only show the target div if it has some content or has a src attr e.g. is an img
				if(this.target_id.html().length > 0 || this.target_id.attr('src').length > 0){ 
					
					if(!$(this).parents('li').hasClass('tgl-selected') && !$(this).hasClass('tgl-selected')){

						if(opts.linkOpacity != null){
							if(typeof($(this).parents('li')) != 'undefined'){
								$(this).parent('li').css({'filter':''}).stop().animate(
                                                                    { 'opacity':opts.linkOpacity}, // what we are animating
                                                                    {
                                                                    duration: 100, // how fast we are animating
                                                                    easing: 'linear', // the type of easing
                                                                    complete: function() { // the callback
                                                                            if(jQuery.browser.msie)
                                                                                    $(this).css('filter','');			
                                                                    }
								});
							}else{
								//$(this).stop().animate({'opacity':opts.selectedLinkOpacity});
							}
						}
					}
					
					switch(opts.event){				
						case "mouseover":
							$(this).mouseover(onEvent);
							$(this).click(function(){return false;});//make sure then any click events return false
						break;
						case "click":
							$(this).click(onEvent);
						break;
					}
				}
			}
		});
		
		function autoScroll(){
		
			if(opts.wrapper != null){
		
				var theInt = null;
				var curclicked = 0;
				var stop = 0;
				var wrapperElement = $(opts.wrapper);
				
				theInterval = function(cur){
					clearInterval(theInt);
				
					theInt = setInterval(function(){
						
						//console.log($("li.tgl-selected").next().html());
						// $('li.tgl-selected a:first')
						
						// add autoscroll behaviour 
						if(wrapperElement.find(".tgl-selected").next().children('.showhide').length > 0){
			        		wrapperElement.find(".tgl-selected").next().children('.showhide').trigger(opts.event);
			        	}else{
			        		wrapperElement.find("a.showhide:first").trigger(opts.event);
			        	}
			            
			            wrapperElement.find('.tgl-active, .showhide').die('mouseover');
			            // stop autoscroll on stage hover or controls hover
			            wrapperElement.find('.tgl-active, .showhide').live('mouseover', function(event){
							if (stop==0){ 
						        clearInterval(theInt);
						     	stop=1;
					     	}
					    });
	
	
					    
				    }, opts.autoScrollTimeout);
				    
				    wrapperElement.find('.tgl-active, .showhide').die('mouseout');
				    
				    // restart autoscroll on stage mouseout
					wrapperElement.find('.tgl-active, .showhide').live('mouseout', function(event) {  
		            	stop=0;
		            	theInterval();            	
		            });	            
					    
				     wrapperElement.find('.showhide').bind('mouseup', function(event){
						
					        clearInterval(theInt);
					     	wrapperElement.find('.tgl-active, .showhide').die('mouseover');
					     	wrapperElement.find('.tgl-active, .showhide').die('mouseout');
					     	
				     		wrapperElement.find('.showhide').unbind('mouseup');
				    });
				};
				
				// initial call
				theInterval();
			}else{
				alert('Showhide Plugin : You must provide the "wrapper" (e.g. wrapper:"#something") parameter when using autoScroll:true ');
			}
		}
		
		//preload imgs onto the page
		//limitless arguments
		//e.g. preloadImages('/dir/img.jpg','new-img.gif')
		function preloadImages()
		{
		  for(var i = 0; i<arguments.length; i++)
		  {
			jQuery("<img>").attr("src", arguments[i]);
		  }
		}
		
		
		function resetPosition(current_id) {
			//alert(current_id);
			if(opts.animate==true){	
				//close hide the div
				$('#'+current_id).hide();
			}else{
				//close hide the div
				$('#'+current_id).hide();
			}
					
			//only reposition the div if draggable object if it exists
			if(jQuery.fn.draggable){
				if($('#'+current_id).data("x")){
					$('#'+current_id).css({
						"left": $('#'+current_id).data("x")
					});
				}
				if($('#'+current_id).data("y")){
					$('#'+current_id).css({
						"top": $('#'+current_id).data("y")
					});
				}
			}
		  	return true;
		}
		
		function resetAnimation(current_id,animation) {
			switch(opts.animate_type){
				case "show":
				$(current_id).show('slow');
				break;
				case "toggle":
				$(current_id).toggle('slow');
				break;
				case "slide":
				$(current_id).slideDown('slow');
				break;				
				case "custom":
				$(current_id).css({display:'inline',left: -300, top:0, opacity: 0});
				$(current_id).animate({left: 0, opacity: 1}, 500, 'swing');
				break;
			}
		}
	
		function onEvent() {
			
			//assign div id to temp var
			var tmp_current_id = this.target_id.attr('id');
			
			//remove slected class from all previously clicked
			
			//deal with ul li a set up
			if($(this).parents('li').length > 0){
				$(this).parents('li').siblings().each(function() {
                                        if(opts.linkOpacity != null){
                                            $(this).removeClass('tgl-selected').css({'filter':''}).stop().animate(
                                                                    { 'opacity':opts.linkOpacity}, // what we are animating
                                                                    {
                                                                    duration: 100, // how fast we are animating
                                                                    easing: 'linear', // the type of easing
                                                                    complete: function() { // the callback
                                                                            if(jQuery.browser.msie)
                                                                                    $(this).css('filter','');			
                                                                    }
								});
                                        }else{
                                            $(this).removeClass('tgl-selected');
                                        }
                                        
				});
			}else{
			//all other set ups
				$(this).siblings('.tgl-selected').each(function() {
					if($(this).hasClass('tgl-selected')){
                                            if(opts.linkOpacity != null){
						$(this).removeClass('tgl-selected').css({'filter':''}).stop().animate(
                                                                    { 'opacity':opts.linkOpacity}, // what we are animating
                                                                    {
                                                                    duration: 100, // how fast we are animating
                                                                    easing: 'linear', // the type of easing
                                                                    complete: function() { // the callback
                                                                            if(jQuery.browser.msie)
                                                                                    $(this).css('filter','');			
                                                                    }
								});
                                            }else{
                                                $(this).removeClass('tgl-selected');
                                            }
                                        }
				});
			}
			
			//remove any close elements
			if(opts.closer != null){
				if($('div.closer').length > 0){
					$('div.closer').remove();
				}
			}
			
			if(opts.animate==true){				
				
				if(opts.animate_type.length > 0){
					switch(opts.animate_type){
						case "show":
							//hide all sibling active divs, fade them out and take away the active class using chaining
							this.target_id.siblings(".tgl-active").hide().removeClass('tgl-active');
							this.target_id.show().css("z-index", 100);
						break;
						case "toggle":
							if(this.target_id.hasClass('tgl-active') == false){
								var target_id = this.target_id;
								//hide all sibling active divs, fade them out and take away the active class using chaining
								this.target_id.siblings('.tgl-active').toggle('slow', function(){resetAnimation(target_id,opts.animate_type)}).removeClass('tgl-active');
							}
						break;
						case "slide":							
							if(this.target_id.hasClass('tgl-active') == false){
								var target_id = this.target_id;
								//hide all sibling active divs, fade them out and take away the active class using chaining
								this.target_id.siblings('.tgl-active').slideUp('slow', function(){resetAnimation(target_id,opts.animate_type)}).removeClass('tgl-active');
							}
						break;
						case "custom":		
							if(this.target_id.hasClass('tgl-active') == false){
								var target_id = this.target_id;
								//hide all sibling active divs, fade them out and take away the active class using chaining
								this.target_id.siblings('.tgl-active').animate({top: 220}, 500, 'swing', function(){$(this).css({display:'none'});resetAnimation(target_id,opts.animate_type)}).removeClass('tgl-active');
							}
						break;
						case "opacity":
							//hide all sibling active divs, fade them out and take away the active class using chaining
							this.target_id.siblings(".tgl-active").css({'filter':''}).animate({opacity: 0.1}, 500, 'swing', function(){$(this).removeClass('tgl-active');});
							this.target_id.stop().css("z-index", 100).stop().css({'filter':''}).animate({opacity: 1, filter:''}, 500, 'swing');
						break;
						case "left":
							//hide all sibling active divs, fade them out and take away the active class using chaining
							this.target_id.siblings(".tgl-active").css({'filter':'', 'left':'-9999px'});
                                                        this.target_id.siblings(".tgl-active").removeClass('tgl-active');
                                                        this.target_id.stop().css("z-index", 100).stop().css({'filter':'', 'left':'0px'});
						break;
						default:
							//hide all sibling active divs, fade them out and take away the active class using chaining
							this.target_id.siblings(".tgl-active").hide().removeClass('tgl-active');
							this.target_id.css({'opacity':1}).stop().fadeIn('slow').css("z-index", 100);
						break;
					}
				}else{
					//hide all sibling active divs, fade them out and take away the active class using chaining
					this.target_id.siblings(".tgl-active").css({'opactiy':'1'}).hide().removeClass('tgl-active');
					this.target_id.css({'opacity':1}).stop().fadeIn('slow').css("z-index", 100);
				}
				
				//only call draggable object if it exists
				if(jQuery.fn.draggable && opts.closer === true){
					this.target_id.draggable({ cursor: 'crosshair'});
					
					// get and assign the top, left position to elements data				
					this.target_id.data("x",this.target_id.position().left+'px');				
					this.target_id.data("y",this.target_id.position().top+'px');
					
					//remove any dragger div that is inplace within the target id
					if($('#'+tmp_current_id+' #dragger')){
						$('#'+tmp_current_id+' #dragger').remove();
					}
					this.target_id.draggable({ 
						cursor: 'move',
						drag: function(event, ui) {
							$(this).children().each(function() {
						
								if($(this).attr('class') == 'wrapper'){								
									$(this).css({'border-style':'dashed'});
								}
							});
						},
						stop: function(event, ui) {
							$(this).children().each(function() {
						
								if($(this).attr('class') == 'wrapper'){								
									$(this).css({'border-style':'solid'});
								}
							});
						}

					});
					
					
					this.target_id.children().each(function() {
						
						if($(this).attr('class') == 'wrapper'){
							
							var draggable_color = '#000000';
							
							if($(this).css('border-top-color')){
								var draggable_color = $(this).css('border-top-color');
							}
							
							//prepend the dragable div to the target element
							$(this).parent().prepend(draggable_div);
							$('#dragger').css({'background-color':draggable_color,'border':'1px solid '+draggable_color});
							
						}
						
					});
				}
				
			}else{
				//hide all sibling active divs, hide them and take away the active class using chaining                       
                                if(opts.animate_type.length > 0){
                                    switch(opts.animate_type){
                                        case "left":
                                                //hide all sibling active divs, fade them out and take away the active class using chaining
                                                this.target_id.siblings(".tgl-active").css({'filter':'', 'left':'-9999px'});
                                                this.target_id.siblings(".tgl-active").removeClass('tgl-active');
                                                this.target_id.stop().css("z-index", 100).stop().css({'filter':'', 'left':'0px'});
                                        break;
                                    }
                                }else{
                                    this.target_id.siblings(".tgl-active").hide().removeClass('tgl-active');
                                    this.target_id.show().css("z-index", 100);
                                }
				
				//only call draggable object if it exists
				if(jQuery.fn.draggable){
					this.target_id.draggable({ cursor: 'crosshair'});
				}
;
			}
			
			data = this.target_id.metadata();
			
			// go through each dependentElementShow and display
			if(data.dependentElementShow && data.dependentElementShow.length > 0){
				$(data.dependentElementShow).css({'display':'block'});
			}
			// go through each dependentElementShow and display
			if(data.dependentElementHide && data.dependentElementHide.length > 0){
				$(data.dependentElementHide).css({'display':'none'});
			}

			this.target_id.addClass('tgl-active');
			
			if(typeof($(this).parents('li')) != 'undefined'){
				$(this).parent('li').addClass('tgl-selected');//make sure any clicked link has parent li class called 'tgl-selected' if present
				if(opts.selectedLinkOpacity != null){
					//$(this).parent('li').stop().animate({'opacity':opts.selectedLinkOpacity});
				}
			}else{
				$(this).addClass('tgl-selected');//make sure any clicked link has a class called 'tgl-selected'
				if(opts.selectedLinkOpacity != null){
					//$(this).stop().animate({'opacity':opts.selectedLinkOpacity});
				}
			}
			
			if(opts.closer != null){
				//append a closing link and attach action to it
				this.target_id.append(closer);
			}
			
			//only call draggable object if it exists
			if(jQuery.fn.draggable){
							
				var current_id = this.target_id.attr('id');
				
				if(opts.closer != null){
					//apply starting position to given id
					$('div.closer').click(function() { resetPosition(current_id); });
				}
			}
			
			
		return false;
		}
		
		
		
		if(opts.autoScroll){
			autoScroll();
		}
		
	}
	
	
  
	$.fn.showhide.defaults = {
		animate: false,
		animate_type:false,
		event: 'click',		
		selected: true,	
		selectedLinkOpacity: '1',
		linkOpacity: '1',
		target: null,
		closer_img:null,
		closer:null,
		autoScroll: false,
		autoScrollTimeout:5000,
		wrapper:null
	}
})(jQuery);
