/**
 * Központi (mag) elemek névtere
 */
var Core = {};

/**
 * Objektumok listája
 */
var Objects = [];

/**
 * Ős osztály
 */
Core.Class = new JS.Class( {
	
	ix : null,
	className : 'Core.Class',
	isClass : true,
	
	/**
	 * Inicializálás
	 *	@param	{object}	Tulajdonságok (opcionális)
	 */
	initialize : function( properties ) {
		
		// Futás előtti esemény kiváltása
		this.trigger( 'initialize' );
		
		// Tulajdonságok regisztrálása
		var self = this;
		$.each( properties || {}, function( property, value ) {
			self.set( property, value );
		} );
		
		// Index generálása és regisztrálás az objektumok között
		this.ix = Objects.length;
		Objects[ this.ix ] = this;
		
		// Futás utáni esemény kiváltása
		this.trigger( 'initialize' );
		
	},
	
	/**
	 * Tulajdonság dinamikus elérése
	 *	@param	{string}	Tulajdonság
	 *	@param	{mixed}		Alapértelmezett érték (opcionális)
	 *	@return	{mixed}		A tulajdonság értéke
	 */
	get : function( property, defaultValue ) {
		
		var getter = 'get' + Utils.ucFirst( property );
		
		if( this[ getter ] )
			return this[ getter ]();
		
		if( typeof this[ property ] != 'undefined' )
			return this[ property ];
		
		if( typeof defaultValue != 'undefined' )
			return defaultValue;
		
		return null;
		
	},
	
	/**
	 * Tulajdonság dinamikus beállítása
	 *	@param	{string}	Tulajdonság
	 *	@param	{mixed}		Érték
	 */
	set : function( property, value ) {
		
		var setter = 'set' + Utils.ucFirst( property );
		
		if( this[ setter ] )
			this[ setter ]( value );
		
		else
			this[ property ] = value;
		
	},
	
	/**
	 * Esemény automatikus nyitó-záró meghívása
	 *	@param	{string}	Esemény neve
	 */
	trigger : function( event ) {
		
		var triggered = event + 'Triggered';
		
		var eventName = 'on' + ( this[ triggered ] ? 'After' : 'Before' ) + Utils.ucFirst( event );
		if( this[ eventName ] )
			this[ eventName ]();
		
		this[ triggered ] = !this[ triggered ];
		
	}
	
} );

/**
 * Eszközök névtere
 */
var Utils = {
	
	/**
	 * Szöveg első karakterének nagybetűsítése
	 *	@param	{string}	Szöveg
	 *	@return	{string}	Szöveg, nagybetűs első karakterrel
	 */
	ucFirst : function( string ) {
    string += '';
    return string.charAt( 0 ).toUpperCase() + string.substr( 1 );
	},
	
	/**
	 * Szöveg első karakterének kisbetűsítése
	 *	@param	{string}	Szöveg
	 *	@return	{string}	Szöveg, kisbetűs első karakterrel
	 */
	lcFirst : function( string ) {
    string += '';
    return string.charAt( 0 ).toLowerCase() + string.substr( 1 );
	}
	
};

/**
 * Sablonozási eszközök névtere
 */
var Template = {
	
	loadeds   : {},
	fetcheds  : {},
	assigns   : {},
	path      : URI_STATIC + 'scripts/templates/',
	extension : '.tpl',
	
	/**
	 * Sablon változó regisztrálása
	 *	@param	{string}	Változó neve
	 *	@param	{mixed}		Változó értéke
	 */
	assign : function( property, value ) {
		Template.assigns[ property ] = value;
	},
	
	/**
	 * Sablon egyszeri betöltése, visszatérés a sablon tartalmával
	 *	@param	{string}	Sablon neve (könyvtár és kiterjesztés nélkül)
	 *	@return	{string}	Sablon tartalma
	 */
	load : function( template ) {
		
		var template = template.toLowerCase();
		
		// Ha még nem volt betöltve, akkor betöltjük a sablont
		if( !Template.loadeds[ template ] ) {
			$.ajax( {
				async : false,
				cache : false,
				url   : Template.path + template + Template.extension,
				complete : function( trans ) {
					Template.loadeds[ template ] = trans.responseText.replace( /[\r\n\t]/gi, '' );
				}
			} );
		}
		
		// Visszatérés a betöltött sablonnal
		return Template.loadeds[ template ];
		
	},
	
	/**
	 * Sablon egyszeri fordítása, majd visszatérés a feldolgozott sablon futási eredményével
	 *	@param	{string}	Sablon neve (könyvtár és kiterjesztés nélkül)
	 *	@return	{string}	Feldolgozott sablon eredménye
	 */
	fetch : function( template ) {
		
		var template = template.toLowerCase();
		
		// Ha még nem volt fordítva, akkor lefordítjuk
		if( !Template.fetcheds[ template ] ) {
			
			// Sablon betöltése
			var fetched = Template.load( template );
			
			/*
			 * Sablon feldolgozása
			 */
			
			// Sablon elemek listázása
			var fields = fetched.match( /\{([^\}]+)\}/gi );
			$.each( fields || [], function( index, field ) {
				
				var replacement = field;
				var oldField = field;
				var field = field.replace( /\$/gi, "Template.assigns." );
				
					// {if ...}
				if( field.match( /\{if\s([^\}]+)\}/gi ) )
					replacement = field.replace( /\{if\s/gi, "'; if( " ).replace( /\}/gi, " ) { _results += '" );
				else {
					// {else}
					if( field.match( /\{else\}/gi ) ) {
						replacement = "'; } else { _results += '";
					} else {
						// {/if}
						if( field.match( /\{\/if\}/gi ) ) {
							replacement = "'; } _results += '";
						} else {
							// {foreach from=$...}
							// {foreach from=$... item="..."}
							// {foreach from=$... item="..." key="..."}
							if( field.match( /\{foreach([^\}]+)\}/gi ) ) {
								from = field.match( /from=([^\s\}]+)/ );
								if( from && from[ 1 ] ) {
									from = from[ 1 ];
									item = field.match( /item=\"([^\s\}]+)\"/ );
									item = ( item && item[ 1 ] ? item[ 1 ] : 'item' );
									key  = field.match( /key=\"([^\s\}]+)\"/ );
									key  = ( key && key[ 1 ] ? key[ 1 ] : 'key' );
									replacement = "'; $.each( " + from + ", function( " + key + ", " + item + " ) { Template.assigns." + item + " = " + item + "; Template.assigns." + key + " = " + key + "; _results += '";
								} else {
									replacement = field;
								}
							} else {
								// {/foreach}
								if( field.match( /\{\/foreach\}/gi ) ) {
									replacement = "'; } ); _results += '";
								} else {
									// {...}
									replacement = field.replace( /\{/, "' + ( " ).replace( /\}/, " ) + '" );
								}
							}
						}
					}
				}
				
				fetched = fetched.replace( oldField, replacement );
				
			} );
			
			// Fedolgozott sablon mentése
			Template.fetcheds[ template ] = "var _results = '" + fetched + "';";
			
		}
		
		//alert(Template.fetcheds[ template ]);
		
		// Futtatjuk a fordított sablont és visszatérünk az eredménnyel
		eval( Template.fetcheds[ template ] );
		return _results;
		
	}
	
};

/**
 * Felhasználói felületet építő eszközök névtere
 */
var UI = {};

/**
 * Komponens ősosztály
 */
UI.Component = new JS.Class( Core.Class, {
	
	id          : '',
	autoRender  : true,
	renderTo    : '',
	rendered    : false,
	renderMode  : 'append',
	className   : 'UI.Component',
	isComponent : true,
	childrens   : [],
	
	/**
	 * Inicializálás utáni esemény
	 */
	onAfterInitialize : function() {
		
		var self = this;
		
		// Gyermek komponensek regisztrálása
		$.each( this.childrens, function( index, children ) {
			children.parent = this;
			if( children.isComponent )
				self.childrens[ index ] = children;
			else
				eval( "self.childrens[ index ] = new " + ( children.className ? children.className : 'UI.Component' ) + "( children );" );
		} );
		
		console.dir( this.childrens );
		
		this.id = this.id || ( this.className.replace( /\./gi, '_' ).toLowerCase() + '_' + this.ix );
		
		// Kirajzolás, ha automatikus a render
		if( this.autoRender )
			this.render();
		
	},
	
	/**
	 * Komponens kirajzolása (DOM generálás/frissítés)
	 */
	render : function() {
		
		// Rajzolás előtti esemény kiváltás
		this.trigger( 'render' );
		
		if( this.renderTo ) {
			
			// Újrarajzolás
			if( this.rendered )
				$( '#' + this.id + 'Element' ).replaceWith( this.output() );
			
			// Rajzolás
			else {
				$( '#' + this.renderTo )[ this.renderMode ]( this.output() );
				this.rendered = true;
			}
			
			// Gyermek komponensek rajzolása
			var self = this;
			$.each( this.childrens, function( index, children ) {
				self.childrens[ index ].renderTo = self.id + 'Childrens';
				self.childrens[ index ].rendered = false;
				self.childrens[ index ].render();
			} );
			
		}
		
		// Rajzolás utáni esemény kiváltás
		this.trigger( 'render' );
		
	},
	
	/**
	 * HTML kimenet generálása
	 *	@return	{string}	HTML kimenet
	 */
	output : function() {
		this.trigger( 'output' );
		var variableName = this.className.split( '.' );
		variableName = variableName[ variableName.length - 1 ].toLowerCase();
		Template.assign( variableName, this );
		this._output = Template.fetch( this.className.toLowerCase() );
		this.trigger( 'output' );
		return this._output;
	}
	
} );

/*$().ready( function() {
	new UI.Component( { renderTo : 'zone-header', childrens : [
		{ className : 'UI.Component' },
		{ className : 'UI.Component', childrens : [
			{ className : 'UI.Component' },
			{ className : 'UI.Component' },
			{ className : 'UI.Component' }
		] },
		{ className : 'UI.Component' },
		{ className : 'UI.Component' }
	] } );
} );*/
