/**
 * @author   Ivan Andonov
 * @email    ivan.andonov[at]design[dot]bg
 *
 * @require  init
 *           use  dbg.Debug
 * @optional     
 **/

(function () {
	
	var Class = {
		/*
		* Each new class has following properties and methods:
		* 
		* Properties
		*   className    : name of the class
		*   classInstance: points to the class object
		*   parent       : points to the object where the class is originaly created
		*   s_count      : counter of the class instances
		* 
		* Methods
		*   extend
		*   toString
		* 
		* If the new class has method initialize it will be used
		* for initialization of each instance of the class
		* 
		*/
		create : function(className, parent) {
			
			var args = [];
			for (var i = 2, len = arguments.length; i < len; i++) {
				args.push(arguments[i]);
			}
			
			var cls = function () {
				// PRIVATE PROPS
				this.className = cls.className+cls.s_count++;
				
				this.classInstance = cls; // should be used when calling static method from instance of the class
				
				this.parent = parent !== undefined ? parent : window.dbg;
				
				this.toString = function() {
					return (this.parent ? this.parent+'.' : '')+this.className;
				};
				
				// PUBLIC METHODS
				this.extend = cls.extend;
				
				// initialization
				if (cls.initialize) {
					try {
						cls.initialize.apply(this, arguments);
					} catch (error) {
						var desc = error.description || error;
						if (dbg.Debug) {
							$logError(desc);
						} else {
							alert(desc);
						}
					}
				}
				
			};
			
			// STATIC PROPS
			cls.className = className || 'Class';
			
			cls.parent = parent !== undefined ? parent : window.dbg;
			
			cls.s_count = 0;
			
			// STATIC METHODS
			cls.toString = function() {
				return (this.parent && this.parent != window ? this.parent+'.' : '')+this.className;
			};
			
			cls.extend = function(obj, rewrite) {
				for (var prop in obj) {
					if (rewrite || this[prop] === undefined) {
						this[prop] = obj[prop];
					} else {
						var error = 'WARNING: "'+prop+'" already exists!';
						if (dbg && dbg.Debug) {
							$log(error);
						} else {
							alert(error);
						}
					}
				}
				return this;
			}
			
			return cls;
			
		}
		
	};
	
	var userAgent = navigator.userAgent.toLowerCase();
	window.dbg = Class.create('dbg', window).extend({
	
		isPageLoaded : false,
		
		base : window.base || '',
		
		jsPath : window.jsPath || 'js/',
		
		cssPath : window.cssPath || 'css/',
		
		browser : {
			version: (userAgent.match( /.+(?:rv|it|ra|ie)[\/: ]([\d.]+)/ ) || [])[1],
			
			safari: /webkit/.test(userAgent),
			
			opera: /opera/.test(userAgent),
			
			msie: /msie/.test(userAgent) && !/opera/.test(userAgent),
			
			msie6: /msie 6/.test(userAgent) && !/opera/.test(userAgent),
			
			msie7: /msie 7/.test(userAgent) && !/opera/.test(userAgent),
			
			mozilla: /mozilla/i.test(userAgent) && !/(compatible|webkit)/.test(userAgent),
			
			firefox: /firefox/i.test(userAgent)
		},
		
		onLoad : function() {
			dbg.isPageLoaded = true;
		},
		
		Class : Class
		
	});
	
})();