/*
 *  Common VAPI Script
 */
var vapi = {

	settings: {
		trace: {
			enabled: 0
		},
		ajax: {
			globals: 1
		},
		repo: "/api/comp/resource",	// was "/_vapi"
		scriptRepo: "/api/comp/resource"	// was "/_tools"
	},

	libraries: {},
	scripts: {},

	/*
	 * Require javascript library/file
	 */
	require: function(include) {
		
		var library = '';	// api library name (simple ID)
		var uri = '';			// script name (relative to repo)

		if (include.match(/^http/)) {
			$("head").append($("<script/>").attr({
				type: "text/javascript",
				src: include
			}));
			return;
			uri = include;
		} else if (include.match(/\.js$/)) {
			uri = this.settings.scriptRepo + "/" + include;
		} else {
			library = include;
			uri = this.settings.repo + "/vapi-" + library + ".js";
		}

		//alert("Loading " + uri);
		
		if (vapi.scripts[uri]) {
		//alert(uri + " is already loaded!");
		} else {
			//alert(uri + " needs to be loaded!");
			if (library) this.libraries[library] = 'loading';
			$.ajax({
				url: uri,
				dataType: "script",
				async: false,
				timeout: 500,
				success: function(js){
					if (library) vapi.libraries[library] = 'loaded';
					vapi.scripts[uri] = true;
				//alert("Loaded " + uri);
				},
				error: function(js){
					if (library) vapi.libraries[library] = 'failed';
				//alert("Failed to load " + uri);
				},
				complete: function(js){
				}
			});
		}

	//
	// If loading a library, wait until dependencies are loaded.
	//
	//if (library) while (this.libraries[library] == 'loading') {}
	},

	/**
     * Format string like classic sprintf
     * @param {string} format format string with % escapes
     * @param {array} values array of values for substitution
     * @type string
     */
	sprintf: function(format, values) {
		return format.replace(/(%[-+0-9]*[%bcdfosxX])/g, function(match){
			var matches = match.match(/%([-+0-9]*)([%bcdfosxX])/);
			if (matches[2] == '%') {
				return '%';
			}
			if (matches[2] == 's') {
				return values.shift();
			}
			if (matches[2] == 'd') {
				var n = parseInt(values.shift());
				if (matches[1] == "02") {
					return (n < 10 ? "0" : "") + n;
				} else {
					return n;
				}
			}
			return match;
		});
	},

	cry: function(message) {
		vapi.trace.warn(message);
		alert(message);
	},

	alert: function(message, data) {
		alert(vapi.sprintf(message, data));
	},

	site: {

		init: function() {},
		load: function() {},

		onReady: function() {
			vapi.trace.write("site.onReady()");
            
			vapi.trace.onload();
            
			vapi.comp.onload();
			/*
            vapi.site.init();
            vapi.page.init();
            for (var c in vapi.comps) {
                vapi.comps[c].init();
            }
            for (var c in vapi.comps) {
                vapi.comps[c].load();
            }
            vapi.page.load();
            vapi.site.load();
             */

			//
			// Dump trace messages.
			//
			vapi.trace.dump();

			//
			// Dump comp tree.
			//
			if (vapi.settings.trace.enabled) {
				vapi.comp.dumpTree();
			}
		}

	},

	page: {
		init: function() {},
		load: function() {}
	},

	/**
     * Handle call of deprecated function.
     * @param String f deprecated function
     * @param String n replacement function
     */
	deprecate: function(f, n) {
		var msg = vapi.sprintf("Function %s() is DEPRECATED! Use %s() instead.", [f, n]);
		vapi.trace.warnf(msg);
		alert(msg);
	},

	//
	// Deprecated functions.
	//
	defineComp: function(compClass) {
		vapi.deprecate("vapi.defineComp", "vapi.comp.define");
		vapi.comp.define(compClass);
	},
	initComp: function(id, uri, parentID) {
		vapi.deprecate("vapi.initComp", "vapi.comp.construct");
		vapi.comp.construct(id, uri, parentID);
	},
	registerComp: function(c) {
		vapi.deprecate("vapi.registerComp", "vapi.comp.define");
	},
	registerPage: function(p) {
		vapi.deprecate("vapi.registerPage", "vapi.comp.define");
	}
/*
    registerSite: function(s) {
        s.init = s.init || function(){};
        s.load = s.load || function(){};
        s.onReady = function() {
            vapi.site.init();
            vapi.page.init();
            vapi.page.load();
            vapi.site.load();
        };
        this.site = s;
    },
    registerScript: function(uri) {
        alert(uri);
        $.include(uri);
    },
     */

};
//
// Add "onready" handler for vapi.site.
//
$(document).ready(function(){
	vapi.site.onReady();
});



/**
 * Trace Library
 */
vapi.trace = {
	messages: [],
	dumped: false,

	onload: function() {
		if (!vapi.settings.trace.enabled) {
			return;
		}
		var panel = $('<div/>');
		panel.addClass("vapi-debug vapi-trace").css({
			width: "10px",
			//overflow: "hidden",
			position: "absolute",
			zIndex: "100",
			opacity: 0.2
		}).hover(
			function(){
				$(this).css({
					opacity:1.0,
					width:"90%"
				})
			},
			function(){
				$(this).css({
					opacity:0.2,
					width:"10px"
				})
			}
			);
		$("body").prepend(panel);
	},

	/**
     * Add normal trace message
     * @param string message
     */
	write: function(message) {
		if (!vapi.settings.trace.enabled) return;

		if (this.dumped) {
			this.dumpMessage(message);
		} else {
			this._process("normal", message);
		}
	},

	/**
     * Add normal trace message with formatted data
     * @param string format
     * @param array data
     */
	writef: function(format, data) {
		this.write(vapi.sprintf(format, data));
	},

	/**
     * Add trace warning
     * @param string message
     */
	warn: function(message) {
		if (!vapi.settings.trace.enabled) return;

		if (this.dumped) {
			this.dumpMessage(message);
		} else {
			this._process("warning", message);
		}
	},

	/**
     * Add trace warning with formatted data
     * @param string format
     * @param array data
     */
	warnf: function(format, data) {
		this.warn(vapi.sprintf(format, data));
	},

	/**
     * Add trace alert.
     * @param string message
     */
	cry: function(message) {
		this.warn(message);
		alert(message);
	},

	/**
     * Add trace alert with formatted data
     * @param string format
     * @param array data
     */
	cryf: function(format, values) {
		var message = vapi.sprintf(format, values);
		this.warn(message);
		alert(message);
	},

	/**
     * Dump trace messages to document.
     */
	dump: function() {
		if (!vapi.settings.trace.enabled) return;

		var $output = $("<div/>").addClass("vapi-trace");
		$(this.messages).each(function(){
			$output.append(vapi.sprintf('<div class="vapi-trace-item"><span class="%s">%s</span></div>', [this.type, this.message]));
		});

		$output.appendTo("body");
        
		this.dumped = true;
	},

	/**
     * Handle formatted trace message.
     * @private
     */
	_process: function(type, message) {
		this.messages.push({
			type: type,
			message: message
		})
	}

};


