

(function( $, pyro ) {
	if ( $[pyro] ) return;
	$[pyro] = $.extend( { }, $.ui, {
		
		includedScripts: {},
		includeTimer: null,
		isReady: true,
		ptr_jQuery_ready: null,

		widgetsClasses: {},
		behaviors: [],

		extendClass: function ( extended, construct, child ) {
			var cls = construct;
			extended = extended ? extended.prototype : {};
			cls.prototype = $.extend( {}, extended, child );
			return cls;
		},
		jQuery_ready: function () {
			this.isReady = true;
			for ( var script in this.includedScripts ) {
				if ( this.includedScripts[script] == false) {
					this.isReady = false;
					break;
				}
			}
			if ( this.isReady ) {
				window.clearInterval( this.includeTimer );
				this.ptr_jQuery_ready.apply( $, arguments );
			}
		},
		include: function ( url, onload ) {
			var self = this;
			if ( this.includedScripts[url] != undefined ) return;
			this.includedScripts[url] = false;
			this.isReady = false;
			/*if ( ! this.ptr_jQuery_ready ) {
				this.ptr_jQuery_ready = $.ready;
				$.ready = function () { return self.jQuery_ready.apply( self, arguments ); };
			}
			if ( !this.includeTimer) {
				this.includeTimer = window.setInterval( function () {
					$.ready();
				}, 50 );
			}*/
			onload = onload || ( function() { } );
			var script = document.createElement('script');
			script.type = 'text/javascript';
			script.onload = function () {
				if ( !self.includedScripts[url] ) {
					self.includedScripts[url] = true;
					onload.apply( $(script), arguments );
				}
			};
			script.onreadystatechange = function () {
				if ( script.readyState == 'complete' && !self.includedScripts[url] ) {
					self.includedScripts[url] = true;
					onload.apply( $(script), arguments );
				}
			};
			script.src = url;
			document.getElementsByTagName('head')[0].appendChild( script );
		},

		registerBehavior: function ( pattern, func ) {
			this.behaviors.push( { pattern: pattern, callback: func } );
		},
		callBehaviors: function( context ) {
			console.info( "pyro: callBehaviors " + this.behaviors.length + ' ' + context );
			$(this.behaviors).each( function () {
				var self = this;
				var cb = this.callback;
				$( this.pattern, context ).each( function () {
					console.info( "pyro: behavior " + self.pattern + " applied to " + ( this.id || this ) );
					cb.call( this );
				} );
			} );
		},
		onReady: function ( elt ) {
			if ( elt == undefined ) elt = document;
			console.group( "pyro: onReady " + ( elt === document ? 'document' : ( elt.id || elt ) ) );
			$.pyro.callBehaviors( elt );
			console.groupEnd();
		},
		hasWidget: function ( widgetName ) {
			return ( this.widgetsClasses[widgetName] != undefined );
		},
		registerWidget: function ( widgetName, className, behaviors ) {
			if ( !this.hasWidget( widgetName ) ) {
				console.info( "pyro: registering widgets " + widgetName + " as " + window[className] );
				this.widgetsClasses[widgetName] = window[className];
				$.widget( "pyro." + widgetName, this.widgetsClasses[widgetName].prototype );
				this.registerBehavior( '.pyro-' + widgetName, function () {
					var options = $(this).data( 'config-' + className ) || {};
					var jq = $(this);
					jq[ widgetName ].call( jq, options );
				} );
			}
			return this.widgetsClasses[widgetName];
		},
		importWidgetClass: function ( className, widgetName ) {
			var self = this;
			if ( className.indexOf( '_' ) == -1 ) {
				className = 'kos_pyro_' + className;
			}
			var pos = className.lastIndexOf( '_' ), shortName = className.substr( pos+1 );
			if ( !widgetName || !widgetName.length ) {
				widgetName = shortName;
			}
			if ( !this.hasWidget( widgetName ) ) {
				var path = '/class/' + className.replace( /_/g, '/' ) + '/www';
				this.include( path + '/' + shortName + '.js', function () {
					self.registerWidget( widgetName, className );
				} );
			}
		}
	} );
	$(document).ready( function () { $[pyro].onReady(); } );
	// ------ Base widget class
	$[pyro].Widget = $[pyro].extendClass( $.widget, function () {
		this.pyroWidgetName = '';
		$.widget.apply( this, arguments );
	}, {
		ui: {},
		create: function ( options ) {
			var elt = $('<div class="pyro-autoremove" />').appendTo('body');
			return elt[ this.pyroWidgetName ]( options ); 
		},
		init: function () {
			console.info( 'pyro: Initializing widget ' + this.widgetName + ' for ' + ( this.element[0].id || this.element[0] ) );
			$.widget.prototype.init.call( this, arguments );
			this.ui.container = this.element.wrap( '<span />' ).parent();
			this.ui.container.addClass( 'pyro-Widget' );
		},
		destroy: function () {
			if ( this.element.hasClass('pyro-autoremove') ) {
				this.element.removeClass('pyro-autoremove');
				this.element.remove();
			} else {
				$.widget.prototype.destroy.call( this, arguments );
			}
		}
	} );

	$[pyro].registerBehavior( '.pyro-form', function (elt) { return $(this).validate(); } );

})( jQuery, 'pyro' );

$.validator.addMethod( 'dateFR', function(value, element) {
	return this.optional(element) || /^\d{2}[\/-]\d{2}[\/-]\d{4}$/.test(value);
} );
$.validator.addClassRules( 'date', { dateFR: true} );

if ( window.console === undefined ) {
	window.console = {
		log: function (msg) {},
		debug: function (msg) {},
		info: function (msg) {},
		warn: function (msg) {},
		error: function (msg) {},
		trace: function (msg) {},
		time: function (msg) {},
		timeEnd: function (msg) {},
		profile: function (msg) {},
		profileEnd: function (msg) {},
		group: function (msg) {},
		groupEnd: function (msg) {},
		dir: function (msg) {},
		dirxml: function (msg) {}
	};
}
