(function($){ // confine scope
/*******************************************************************************************/
// jquery.Register.js - rev 12 
// Copyright (c) 2008, Mike Helgeson 
// Liscensed under the MIT License (MIT-LICENSE.txt)
// http://www.opensource.org/licenses/mit-license.php
// Created: 2008-01-31 | Updated: 2008-03-18
/*******************************************************************************************/
// REQUIRES: jquery 1.2.3+, utils.js
/*******************************************************************************************/
// "Register" constructor
$.Register = function( plugin, methods ){
	return !isStr( plugin ) || plugin.indexOf('.')>-1 ? null : // bad plugin name
		isDef( $Reg[ plugin ] ) ? $Reg[ plugin ].expose( methods ) : // extend old instance
		this instanceof $.Register ? (function( obj, plugin, methods ){ // init instance
			$Reg[ plugin ] = $.extend( obj, {
				index: 0, plugin: plugin, stash: {}, public: []
				}).expose( methods ); 
			// $(':plugin') - jquery expression selector
			$.expr[':'][ plugin ] = $.expr[':'][ plugin ] || "jQuery(a).is('."+( plugin+xx )+"')";
			// $.plugin() - global plugin function
			$[ plugin ] = $[ plugin ] || function( arg ){ 
				if ( !isStr( arg ) ) // set/return default plugin settings
					return $.extend( $[ plugin ].defaults, arg||{} ); 	
				if ( $.inArray( arg, $Reg[ plugin ].public )>-1 ){ // call public method	
					var args = Slice( arguments, 1 );
					$.each( $Reg[ plugin ].stash, function(){
						if ( this.obj ) this.obj[ arg ].apply( this.obj, args );
						});
					}
				}; 
			})( this, plugin, methods ) : new $.Register( plugin, methods ); // new instance
	};
/*******************************************************************************************/
// "Register" methods
$.Register.prototype = {
	add: function( elem, obj ){
		var i = obj[ this.plugin+xx ] = this.index++; 
		$( elem ).addClass( this.plugin+xx ); // for the ":plugin" selector
		this.stash[i] = { elem: elem, obj: obj }; // store the args
		return $.extend( obj, { NS: '.'+this.plugin+i } ); // return the obj + (Event) Name Space
		},
	drop: function( obj ){
		var i = obj[ this.plugin+xx ], elem = this.stash[i].elem;
		delete this.stash[i]; // remove obj from cache 
		if ( !getReg( this.plugin, elem ) ) // no more refs found
			$( elem ).removeClass( this.plugin+xx ); 
		},
	call: function( elem, method, args ){ // $(el).plugin('method',arg1,...argN)
		if ( $.inArray( method, this.public )>-1 ){
			var obj = getReg( this.plugin, elem );
			if ( obj ) return obj[ method ].apply( obj, args );
			}
		},
	publish: function( obj, event, args ){ // trigger "event.plugin" custom event
		$( this.stash[ obj[ this.plugin+xx ] ].elem )
			.triggerHandler( event+"."+this.plugin, args ); // bound custom events 
		return this; // return the registry
		},
	expose: function( method ){ var reg = this; // store public methods
		if ( isStr( method ) ) reg.public.push( method ); // save method as public
		else if ( isArr( method ) ) $.each( method, function(i){ reg.expose( method[i] ); }); // each method
		return reg; // return the registry
		}
	};
/*******************************************************************************************/
// private vars and functions
var $Reg = $.data( document, "Register", {} ), // the "Registry"
xx = String( (new Date()).getTime() - 1205864543597 ), // expando
getReg = function( plugin, elem ){ var ret; // find plugin instance from element 	
	$.each( $Reg[ plugin ].stash, function(){ 
		if (elem==this.elem) return !(ret=this.obj); 
		});
	return ret; 
	};
/*******************************************************************************************/
})(jQuery) // secure the $ jQuery alias
