var $render;
var $useMap;
var $loadView;

gloader.load(["glow", "1", "glow.dom"],{onLoad: function(glow){
	// createObject method
	function _createObject(strName) {
		var nameParts = strName.split("."),
		i = 0,
		len = nameParts.length,
		obj = window;
		
		for (; i < len; i++){
			if (obj[nameParts[i]] === undefined) {
				obj[nameParts[i]] = {};
			}
			
			obj = obj[nameParts[i]];
		}
		
		return obj;
	}

	// create bbc.fmtj namespace
	_createObject("bbc.fmtj");

	// START -> bbc.fmtj.utils	
	bbc.fmtj.utils = (function(){
		return {
			createObject: _createObject,
			isArray: _isArray,
			prefixUrl: _prefixUrl
		}
		
		function _isArray(obj){
			if (obj === undefined){
				return false;
			}
			
			return obj.push !== undefined;
		}
		
		function _prefixUrl(url, prefix){
			if (url.toLowerCase().indexOf("http") != 0){
				// Only do this for files served from the news.bbc.co.uk domain
				var docDomain = document.domain.toLowerCase();

				if (docDomain === "news.bbc.co.uk" || docDomain === "bbc.co.uk"){
					if (prefix === undefined) {
						prefix = "http://news.bbcimg.co.uk";
					}
					url = prefix + url;
				}
			}
			
			return url;
		}		
	})();
	// END -> bbc.fmtj.utils.
	// START -> bbc.fmtj.queue	
	bbc.fmtj.queue = (function(){
		var _queue = {},
		_scripts = {},
		_htmlHead,
		_htmlBody;
		
		return {
			callback: _callback,
			register: _register
		}
		
		function _recall(fContext, fName, fArgs){
			var app = _getObject(window, fName);
			app.apply(fContext, fArgs);
		}

		function _queueCallback(fContext, fName, fArgs){
			if (typeof _queue[fName] !== "object" || _queue[fName] === null) {
				_queue[fName] = new Array();
			}

			_queue[fName][_queue[fName].length] = {
				fContext: fContext,
				fName: fName,
				fArgs: fArgs
			};
		}

		function _callback(fName){
			if (typeof _queue[fName] === "object" && _queue[fName] !== null) {
				for (var i = 0; i < _queue[fName].length; i++) {
					_recall(_queue[fName][i].fContext, _queue[fName][i].fName, _queue[fName][i].fArgs);
				}
				_queue[fName] = null;
			}
		}

		function _loadscriptInline(src){
			if (_scripts[src] !== undefined) {return}
			_scripts[src] = {loading:true};
			
			if (!glow.isReady){
				document.write('<script type="text/javascript" src="' + src + '"><\/script>');
			}else{
				_loadscriptFoot(src);
			}
		}

		function _loadscriptHead(src){
			if (_scripts[src] !== undefined) {return}
			_scripts[src] = {loading:true};
			
			if (_htmlHead === undefined){
				_htmlHead = document.getElementsByTagName('head')[0];
			}
			var script= document.createElement('script');
			script.type= 'text/javascript';
			script.src= src;
			_htmlHead.appendChild(script);
		}

		function _loadscriptFoot(src){
			if (_scripts[src] !== undefined) {return}
			_scripts[src] = {loading:true};
			
			glow.onDomReady(function(){
				if (_htmlBody === undefined){
					_htmlBody = document.getElementsByTagName('body')[0];
				}
				var script= document.createElement('script');
				script.type= 'text/javascript';
				script.src= src;
				_htmlBody.appendChild(script);
			});
		}

		function _getObject(root, path){
			var ret = true;
			var splitPath = path.split(".");
			var rootPath = root;
			for (i = 0; i < splitPath.length; i++) {
				var x = splitPath[i].indexOf("[");
				if (x > 0) {
					var regex = /\[([0-9]*)\]/;
					var y = splitPath[i].substr(0, x);
					var z = regex.exec(splitPath[i])[1];
					rootPath = rootPath[y];
					rootPath = rootPath[z];
				}
				else {
					rootPath = rootPath[splitPath[i]];
				}
				ret = (typeof rootPath !== 'undefined');
				if (!ret) {
					return null;
				}
			}
			return rootPath;
		}

		function _register(obj) {
			if (obj.namespace === undefined){alert("No namespace specified to register script.");return;}
			if (obj.method === undefined){alert("No method specified to register script.");return;}
			if (obj.script === undefined && obj.scripts === undefined){alert("No sources specified to register script.");return;}			

			var ns = bbc.fmtj.utils.createObject(obj.namespace);
			var methodArray;
			var method;
			
			if (bbc.fmtj.utils.isArray(obj.method)){
				methodArray = obj.method;
			}else{
				methodArray = new Array(obj.method);
			}
			
			for (var m = 0; m < methodArray.length; m++) {
				method = methodArray[m];
				
				ns[method] = function(){
					_queueCallback(this, obj.namespace + "." + method, arguments);
					
					if (obj.script !== undefined) {
						_loadscriptFoot(obj.script);
					}
					
					if (obj.scripts !== undefined) {
						if (obj.scripts.head !== undefined) {
							for (var i = 0; i < obj.scripts.head.length; i++) {
								_loadscriptHead(obj.scripts.head[i]);
							}
						}
						
						if (obj.scripts.inline !== undefined) {
							for (var i = 0; i < obj.scripts.inline.length; i++) {
								_loadscriptInline(obj.scripts.inline[i]);
							}
						}
						
						if (obj.scripts.foot !== undefined) {
							for (var i = 0; i < obj.scripts.foot.length; i++) {
								_loadscriptFoot(obj.scripts.foot[i]);
							}
						}
					}
				};
			}
			
			ns.isReady = false;
		}
	})();
	// END -> bbc.fmtj.queue	
	// START -> bbc.fmtj.components
	bbc.fmtj.components = (function(){
		// array to hold all registered namespaces
		var _namespaces = [];
		
		// return methods
		return {
			registerNamespace: _registerNamespace,
			render: _render,
			useMap: _useMap,
			loadView: _loadView
		}
		
		// register namespace
		function _registerNamespace(namespace){
			// insert namespace into first position in the array
			_namespaces.splice(0, 0, namespace);
		}
		
		// renders item if appropriate renderer is found
		function _render(component){
			// if gloader doesn't exist on the page then do nothing
			// as a safeguard in case it has failed to load
			if (window.gloader === undefined) {return false;}

			// item renderer
			var renderer;

			// determine whether renderer exists and which one to use					
			for (var i = 0; i < _namespaces.length; i++){
				if (_namespaces[i][component] !== undefined){
					renderer = _namespaces[i][component];
					break;
				}
			}
			
			if (renderer !== undefined) {
				var args = [];

				for (var j = 1; j < arguments.length; j++){
					args.push(arguments[j]);
				}

				renderer.apply(this, args);
			}
		}
		
		// wrapper for gloader.use
		function _useMap(options){
			// if gloader doesn't exist on the page then do nothing
			// as a safeguard in case it has failed to load
			if (window.gloader === undefined) {return false;}

			gloader.use("bbc.fmtj.view",options);
			gloader.map.setProperties("bbc.fmtj.view",{$versionPath:"",$path:"{$base}{$versionPath}/"});
		}
		
		// wrapper for gloader.load
		function _loadView(version, modules){
			// if gloader doesn't exist on the page then do nothing
			// as a safeguard in case it has failed to load
			if (window.gloader === undefined) {return false;}					
			
			var modArray = modules;
			modArray.splice(0, 0, version);
			modArray.splice(0, 0, "bbc.fmtj.view");
			
			gloader.load(modArray);
		}
	})();
	// END -> bbc.fmtj.components
	
	$render = bbc.fmtj.components.render;
	$useMap = bbc.fmtj.components.useMap;
	$loadView = bbc.fmtj.components.loadView;
}});
