(function($) {      
	$.fn.showhide = function(options) {
		
		var opts = $.extend({}, $.fn.showhide.defaults, options);
		// trackers
		var active_id = null;
		//example of expected HTML for a given target element
		var markup = '\r\n\r\n<div class="{item:\'X\'}">\r\n\</div>';

		if(opts.closer != null){
			if(opts.closer_img != null){
				var closer = '<div class="closer" style="cursor:pointer;position:absolute;bottom:20px;left:5px;"><img src="'+opts.closer_img+'" alt="close" /></div>';
			}else{
				var closer = '<div class="closer" style="cursor:pointer;position:absolute;bottom:20px;left:5px;">Hide [X]</div>';
			}
		}
		
		return 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');
							
							//set base element to selected
							$(this).addClass('tgl-selected');
							$(this).parent('li').addClass('tgl-selected');
							
							this.target_id.css("z-index","1000");
							
							//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 && opts.draggable==true){
								
								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{
							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
						$(this).addClass('tgl-selected');
						$(this).parent('li').addClass('tgl-selected');
						this.target_id.addClass('tgl-active');
						this.target_id.css("z-index","1000");
						
						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 && opts.draggable==true){
							
							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){ 
					
					switch(opts.event){				
						case "mouseover":
							$(this).mouseover(onEvent);
							$(this).click(function(){return false;});//make sure then any click events return false
						break;
						case "toggle":
							//apply simple toggling behaviour
							$(this).click(function() {

									//use class to track item state
									if(this.target_id.hasClass('tgl-active')==false){
										this.target_id.addClass('tgl-active');
									}else if(this.target_id.hasClass('tgl-active')==true){
										this.target_id.removeClass('tgl-active');										
									}
									
									this.target_id.toggle('slow');
									
								return false;
							});
						break;
						case "click":
							$(this).click(onEvent);
						break;
					}
				}
			}
		});
	
		//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]);
		  }
		}
		
		//preload imgs onto the page
		//limitless arguments
		//e.g. preloadImages('<strong>some content</strong>','<ul><li>new content</li></ul>')
		function preloadContent()
		{
		  for(var i = 0; i<arguments.length; i++)
		  {
			jQuery("<div>").html(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 && opts.draggable==true){
				$('#'+current_id).css({
					"left": 'auto',
					"right": $('#'+current_id).data("right"),
					"top": $('#'+current_id).data("top")
				});
			}
		  	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;
			}
		}
	
		function onEvent() {
			
			//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() {
					$(this).children().removeClass('tgl-selected');
					$(this).removeClass('tgl-selected');
				});
			}else{
			//all other set ups
				$('.tgl-selected').each(function() {
					if($(this).hasClass('tgl-selected')){
						$(this).removeClass('tgl-selected');
						$(this).parent().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('slow').css("z-index", 1000);
						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;
						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.fadeIn('slow').css("z-index", 1000);
						break;
					}
				}else{
					//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.fadeIn('slow').css("z-index", 1000);
				}
				
				//only call draggable object if it exists
				if(jQuery.fn.draggable && opts.draggable==true){
					this.target_id.draggable({ cursor: 'crosshair'});
					this.target_id.data("right",this.target_id.css('right')).data("top",this.target_id.css('top'));
				}
				
				//only call dropShadow object if it exists
				if(jQuery.fn.dropShadow){
					this.target_id.children().each(function() {
						
						if($(this).attr('class') == 'wrapper'){
							$(this).dropShadow({left: 8, top: 8, blur: 3, opacity: 0.5});
							//alert($(this).attr('class'));
						}
					});
				}
				
			}else{
				//hide all sibling active divs, hide them 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", 1000);
				
				//only call draggable object if it exists
				if(jQuery.fn.draggable && opts.draggable==true){
					this.target_id.draggable({ cursor: 'crosshair'});
				}
;
			}

			this.target_id.addClass('tgl-active');
			$(this).addClass('tgl-selected');//make sure any clicked link has a class called 'tgl-selected'
			$(this).parent('li').addClass('tgl-selected');//make sure any clicked link has a class called 'tgl-selected'
			
			
			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 && opts.draggable==true){
							
				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;
		}
	}
  
	$.fn.showhide.defaults = {
		animate: false,
		animate_type:false,
		event: 'click',
		draggable: false,		
		selected: true,
		target: null,
		active_id:null,
		closer_img:null,
		closer:null
	}
})(jQuery);
