

if (typeof Panagora != 'object')
	Panagora = {};

/**
	@namespace The Panagora namespace
*/
Panagora = Panagora;

/**
	Internal variables
*/
Panagora.internal = {

	/*
		#: {
			constant: '', // (optional, defaults to 'ERROR_GENERIC')
			internal: '', // (internal description)
		}
	*/
	errors: {
		1: {
			constant: 'ERROR_GENERIC',
			internal: 'Unknown'
		}
	},

	logLevels: {
		NONE: 0,
		ERROR: 1,
		WARN: 2,
		LOG: 3,
		INFO: 4,
		DEBUG: 5
	}
	
};

// no firebug?
if (typeof console == "undefined") {
	console = {
		'log' : function () { this.debug.apply(this, arguments); },
		'info' : function () { this.debug.apply(this, arguments); },
		'warn' : function () { this.debug.apply(this, arguments); },
		'error' : function () { this.debug.apply(this, arguments); },
		'debug' : function () {
			var debug;
			if(!document.getElementById('debug')) {
				debug = document.createElement('pre');
				debug.id = 'debug';
				//debug.style.display = 'none';
				debug.innerHTML = 'debug:\r\n';
				document.body.appendChild(debug);
			} else {
				debug = document.getElementById('debug');
			}
			
			var output = [];
			for (var i = 0, l = arguments.length; i < l; i++) {
				if (typeof arguments[i] != 'string' && arguments[i].length) {
					for (var x = 0, l2 = arguments[i].length; x < l2; x++) {
						output.push(arguments[i][x]);
					}
				} else {
					output.push(arguments[i]);
				}
			}
			debug.firstChild.nodeValue += output.join(' ') + '\r\n';
		}
	};

	Panagora.logLevel = Panagora.internal.logLevels.ERROR;
}

// default log level
if (Panagora.logLevel === undefined) {
	Panagora.logLevel = Panagora.internal.logLevels.DEBUG;
}

/**
	Wrapper for DOMContentLoaded-stuff
	
	@param {Function} fn Function reference to run on DOMContentLoaded
*/
Panagora.ready = function _ready(fn) {
	$j(document).ready(fn);
};

/**
	@class
Super-class

Do not instantiate, use Panagora.Class.create(Function) to create a derived class.
	
	@author Niklas Bergius

	@param {string} className Name of derived class

	@constructor
*/
Panagora.Class = function _Class(className) {
	var self = this;

	/** @private */
	function outputLog(func, args) {
		//console.log(func, args); return;
		var caller = outputLog.caller ? outputLog.caller.caller : null;
		var callingClass = className || this.constructor.name;
		var output = [ '(' + new Date().toLocaleTimeString() + ')', callingClass ];
		var callingFunc = caller && caller.name
			? (caller.name.length && caller.name != callingClass ? caller.name : null)
			: caller || 'function()';
		if (callingFunc) {
			output.push(':');
			output.push(callingFunc);
		}
		output.push('>');
		output.push(args);
		
		try {
			func.apply(console, output);
		} catch (ex) {
			// ignore
		}
	}

	/**
		Outputs stuff to the appropriate logger
	*/
	this.debug = function debug() {
		if (Panagora.logLevel >= Panagora.internal.logLevels.DEBUG) {
			outputLog(console.debug, arguments);
		}
	};

	/** @see #debug */
	this.info = function info() {
		if (Panagora.logLevel >= Panagora.internal.logLevels.INFO) {
			outputLog(console.info, arguments);
		}
	};

	/** @see #debug */
	this.log = function log() {
		if (Panagora.logLevel >= Panagora.internal.logLevels.LOG) {
			outputLog(console.log, arguments);
		}
	};
	
	/** @see #debug */
	this.warn = function warn() {
		if (Panagora.logLevel >= Panagora.internal.logLevels.WARN) {
			outputLog(console.warn, arguments);
		}
	};
	
	/** @see #debug */
	this.error = function error() {
		if (Panagora.logLevel >= Panagora.internal.logLevels.ERROR) {
			outputLog(console.error, arguments);
		}
	};
	
	/* make pretty
	var timer = {
		t: new Date().getTime(),
		values: [],
		addTime: function(time) {
			this.values.push(new Date().getTime() - this.t);
		}		
	};
	*/
};
	

/**
	Class-creation mechanism
	
	Use it to create a class inheriting {@link Panagora.Class}.
	
	@example
var XClass = Panagora.Class.create(function XClass() {
	this.log = function () { console.log('overridden logger') }; // overrides base class method
	this.log();
	this.uber.log('standard logger'); // access base class methods with this.uber
});
new XClass();
		
	@author Niklas Bergius

	@requires Panagora.Class
	
	@param {Function} func Derived class constructor
*/
Panagora.Class.create = function _create(func) {
	func.prototype = new Panagora.Class(func.name || 'unknown');
	func.prototype.constructor = func;
	func.prototype.uber = func.prototype;
	
	return func;
};


/**
	Produces a merged string of all Panagora scripts loaded on the current page
*/
Panagora.renderMergedScripts = function _renderMergedScripts() {
	var output = [];
	var reqs = [];
	var count = 0;
	
	$j('head script[src]').each(function iterateScripts() {
		console.log(reqs, this.src);
		if (this.src.match(/panagora([^\/]+)*\.js/i)) {
			reqs[count++] = {
				url: this.src,
				dataType: 'text',
				async: false
			};
		}
	});
	
	$j.each(reqs, function fetchFiles() {
		var req = $j.ajax(this);
		var scriptName = this.url.replace(/^.+\/(Panagora[^\/]+)$/i, '$1');
		output.push('/* begin ' + scriptName + ' */');
		output.push(req.responseText);
		output.push('/* end ' + scriptName + ' */');
	});
	
	output = output.join('\n\n');
	
	var textarea = $j('<textarea/>')
		.css('position', 'absolute')
		.css('top', 0).css('left', 0)
		.css('width', '100%').css('height', '100%')
		.css('z-index', '1000')
		.appendTo(document.body)
		.val(output)
		.keyup(function (e) {
			if (e.which == 27)
				textarea.remove();
		});
};

Panagora.confirm = function _confirm(message) {
	var str = Panagora.applyConstants(message);
	if (arguments.length > 1) {
		var args = [str];
		for (var i = 1; i < arguments.length; i++) {
			args.push(arguments[i]);
		}
		str = String.format.apply(null, args);
	}
	return window.confirm(str);
}

Panagora.alert = function _alert(message) {
	var str = Panagora.applyConstants(message);
	if (arguments.length > 1) {
		var args = [str];
		for (var i = 1; i < arguments.length; i++) {
			args.push(arguments[i]);
		}
		str = String.format.apply(null, args);
	}
	return window.alert(str);
}
