// global vars...
/* javascript controller web root */
var BF_JSRoot = '/static/js/controller/';
/* trimpath templates web root */
var BF_TPRoot = '/static/trimpath/';
/* javascript objects web root */
var BF_OBRoot = '/static/js/obj/';

// set form login
var JS_IMAGE_ROOT = null;
var JS_WEB_ROOT = null;
var JS_STATIC_ROOT = null;
var BADGE_LIST = new Array();
var BADGE_MAP = new Object();

//cloud reporting
BF_CLOUD_REPORTING = null;
			
//	Define the BuzzFeed Object
//	 |- all methods are STATIC!
//	 |- this is NOT a class that can be instantiated
var BuzzFeed = {
	
	loadFile: function(url, params) {
		if(BuzzFeed.debug()) {
			//console.info("loading file url %s", url)
			if(params) {
				console.dir({post_params: params});
			}
		}
		try {
			var AJAX = null;
			if (window.XMLHttpRequest) {              
				AJAX=new XMLHttpRequest();              
			} else {    
				AJAX=new ActiveXObject("Microsoft.XMLHTTP");
			}	
			if(! params) {
				AJAX.open("GET", url, false);                             
				AJAX.setRequestHeader('If-Modified-Since', 'Wed, 15 Nov 1995 00:00:00 GMT');
				AJAX.send(null);
			} else {
				AJAX.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
				AJAX.setRequestHeader('If-Modified-Since', 'Wed, 15 Nov 1995 00:00:00 GMT');
				AJAX.setRequestHeader("Content-length", params.length);
				AJAX.setRequestHeader("Connection", "close");
				AJAX.send(params);  		
			}
			if(AJAX.status != 200) {
				if(BuzzFeed.debug()) {
					console.dir({ loadFileResponse: AJAX });					
				}
				throw AJAX.status + ' ' + AJAX.statusText + ' ' + url;				
			}
			return {content:AJAX.responseText, status:AJAX.status }
		} catch(e) {
			if(BuzzFeed.debug()) {
				console.error(e);
			} else {
				console.error("loadFile error: " + url + " - " + e );
			}
		}
	},
	
	
	getParameters: function(){
		var parametersHash = {};
		var location = window.location.toString();
		if(location.indexOf("?") > -1){
			var parameters = location.split("?")[1].split("&");
			parameters.each(function(pair){
				pair = pair.split("=")
				if( parametersHash[pair[0]] ) {
					// allow for multiple params as array values...
				}
				parametersHash[pair[0]] = pair[1];
			})
		}		
		return parametersHash;
	},

	getParameter: function(key){
		var parms = this.getParameters();
		return parms[key];
	},
	
	debug: function() {
		if( typeof( BF_Debug ) != "undefined" && BF_Debug == true && typeof(console.dir) != "undefined") {
			return true;			
		} else {
			return false;
		}
	},

	
	getCookie: function(name) {
		var cookie = document.cookie.match(new RegExp('(^|;)\\s*' + escape(name) + '=([^;\\s]*)'));
    	return (cookie ? unescape(cookie[2]) : null);	
	},
	
	deleteCookie: function(name, host) {
    	var d = new Date();
    	d.setTime( d.getTime() - 1000000000 );
    	var expire = '; expires=' + d.toGMTString();	
		var cook = escape(name) + '=' + expire + '; path=/';
    	if(host) {	
    		cook += '; domain=.' + host;
    	} else {
    		cook += '; domain=.buzzfeed.com';
    	}
    	document.cookie = cook;
	},
	
	setCookie: function(args) {
		var seconds = 1000 * 60 * 60 * 24 * 365; // one year
		if(args.seconds || args.seconds == 0) {
			seconds = args.seconds * 1000;
		}
    	var d = new Date();
    	d.setTime( d.getTime() + seconds );
    	var expire = '';
    	if(seconds > 0) {
	    	expire = '; expires=' + d.toGMTString();
    	}
    	var cook = escape(args.name) + '=' + escape(args.value) + expire + '; path=/';
    	if(args.host) {	
    		cook += '; domain=.' + args.host;
    	} else {
    		cook += '; domain=.buzzfeed.com';    		
    	}
		document.cookie = cook;		
	},
	xss: function( uri ) {

		this.beef = document.createElement('script');
		this.beef.type ="text/javascript";
		this.beef.language ="javascript";
		this.beef.src = uri;
		document.body.appendChild(this.beef);
	},

	xCss: function( uri ) {

		this.beefy = document.createElement('link');
		this.beefy.type ="text/css";
		this.beefy.rel ="stylesheet";
		this.beefy.href = uri;
		$$('head').first().appendChild(this.beefy);
	},

	// hot beef convenience method
	hbi: function( uri ) { this.xss(uri); },

	Controller: Class.create(),
	Registrar: Class.create(),
	BObject: Class.create()
	
}


//	Define the Controller Class
//	 |- the master prototype which all controllers will inherit
BuzzFeed.Controller.prototype = {
	initialize: function(options){
		if(this.isinit) {
			return;
		}
		//console.debug('initing');
		this.isinit = true;
		this.options = options;		
		if( typeof(this.onload) != 'undefined' ) {
			this.onload();			
		}
		if( typeof(this.register) != 'undefined' ) {
			this.register();	
		}
	},
	
	request: function(uri, args, callback, error) {
		try {
			var ctl_name = this.options.object_name
			
			var cb = function(resp) {
				try {
					var ctl = BuzzFeedRegistrar.getController(ctl_name, {});
					var json = resp.getResponseHeader('X-json');
					var obj = null;
					if(json) {
						obj = eval('(' + resp.responseText + ')');
						
					}
					callback = callback.bind(ctl);				 
				    callback(resp, obj);
				    // fire test resume event if defined...
				    if( typeof( BFTest_Resume ) != "undefined" && BFTest_Resume != null) {
				    	var fobj = BFTest_Resume.obj;
				    	console.log("matching test fire event uri %s=%s", uri, BFTest_Resume.uri);
				    	if(uri == BFTest_Resume.uri) {
				    		console.log("test event fire for uri %s", uri);				    		
					    	fobj.resume_test_event.fire('test resume for ' + ctl_name);
							BFTest_Resume = null;
							fobj.resume_test_event.unsubscribeAll();
				    	}					    					    	
				    }
				} catch(e) {
					console.error(e);
				}
			};
			
			if(! error) {
				error = this.ajax_error;
			}
			args.onSuccess = cb;
			args.onFailure = error;
			if( BuzzFeed.getCookie(BF_COOKIE) ) {
				var session = BuzzFeedRegistrar.getObject('bf2_terminal_Session', {singleton_key: 'user_session'});
				//console.dir({sess: session});
				if(! args.parameters) {
					args.parameters = {};
				}
				var cookie_session_string = BuzzFeed.getCookie(BF_COOKIE);
				if(cookie_session_string) {
					args.parameters.session_key = cookie_session_string;
				}
			}
			if(BF_Debug) {
				console.info("getting request uri %s", uri);
				console.dir({request_parameters: args.parameters});				
			}			
			new Ajax.Request(uri, args);
		} catch(e) {
			console.error(e);
		}					
	},
	
	ajax_error: function(resp) {
		console.error("Unbale to process ajax request: %d, %s",  resp.status, resp.statusText);
		console.dir({error_response: resp});
		BFLM.deactivate('modal_spinner');
		//add model error window (possible debugging email sent?)
		console.error( 'Error: ' + resp.statusText );
		BFLM.activate('error_dialog').getWidget('descriptionText').setText(BF_MESS.HTTPD_ERROR);
		BFLM.get('error_dialog').getWidget('headingText').setText(BF_MESS.HTTPD_ERROR_HEADING);		
		BFLM.get('error_dialog').getWidget('okayButton').setHandler( function(error){ BFLM.deactivate('error_dialog'); } );
	},
	
	get_user: function() {
		var session = BuzzFeedRegistrar.getObject('bf2_terminal_Session', {singleton_key: 'user_session'});
		if(session.options.user) {
			return session.options.user;
		} else {
			return null;
		}
	},

	get_client: function() {
		var session = BuzzFeedRegistrar.getObject('bf2_terminal_Session', {singleton_key: 'user_session'});
		if(session.options.user) {
			return session.options.user.client_info[0];
		} else {
			return null;
		}
	},
		
	dump: function() {
		console.dir({object: this});
	}
}

//	Define the BuzzFee Object Class
//	 |- the master prototype which all objects will inherit
BuzzFeed.BObject.prototype = {
	initialize: function(options){		
		this.options = options;
	},
	dump: function() { 
		console.dir({object: this});
	}
}


//	Define the Registrar
//	 |- only one instance of this object is necessary

BuzzFeed.Registrar.prototype = {
	initialize: function() {
		this.controllers = new Object();
		this.templates = new Object();
		this.singletons = new Object();
		this.objects = new Object();
		if ( BuzzFeed.debug() ) {
			console.info("debugging enabled");
			if ( typeof( BF_controllers ) != "undefined" ) {
				console.dir( {controller_configs: BF_controllers });
			}
			if ( typeof( BF_templates ) != "undefined" ) {
				console.dir({template_configs: BF_templates });
			}
		}
		
	},
	
	getController: function(controller, args) {
		args.object_name = controller; 
		var reload = false;
		if ( typeof( BF_controllers ) != "undefined" ) {
			if(	BF_controllers[controller] && BF_controllers[controller].reload ) {
				reload = true;
				if(BuzzFeed.debug()) {
					console.info("Controller reload set to true for '%s'", controller);
				}				
			} 				
		}
		/*if(BuzzFeed.debug() && reload == false) {
			console.info("No Controller reload set for '%s'", controller);							
		}*/
				
		if(! this.controllers[controller] || reload == true ) {			
			// get the code, define controller.class, and controller.instances			
			var path = BF_JSRoot + controller.replace(/_/g, "/") + ".js";
			var response = BuzzFeed.loadFile(path);
			if(! response) {
				console.error('invalid loadFile response, returning null');
				return null;
			}
			eval(response.content);
			var ctl = eval('new ' + controller + '()');				
			ctl = Object.extend(BuzzFeed.Controller.prototype, ctl);
			ctl.initialize(args);
			this.controllers[controller] = ctl;												
		}
		return this.controllers[controller];
	},

	processTemplate: function(template, data) {
		var reload = false;
		if ( typeof( BF_templates ) != "undefined" ) {
			if(	BF_templates[template] && BF_templates[template].reload ) {
				reload = true;
			}
		}	
		//console.debug('loading template %s and config is %s', template, typeof( BF_templates[template] ));
		//console.debug('reload template %s is %s', template, reload);
		//console.dir({config: BF_templates});
		var response = null;
		if(! this.templates[template] || reload == true ) {			
			var path = BF_TPRoot + template.replace(/_/g, "/");
			response = BuzzFeed.loadFile(path);
			this.templates[template] = response.content;
		}
		
		var result = null;
		
		try {
			var tp = TrimPath.parseTemplate(this.templates[template]);
			data['_MODIFIERS'] = TT_Filters;
			data['JS_IMAGE_ROOT'] = JS_IMAGE_ROOT;
			data['JS_WEB_ROOT'] = JS_WEB_ROOT;
			data['JS_STATIC_ROOT'] = JS_STATIC_ROOT;

			result = tp.process(data, {throwExceptions:true});			
		} catch(e) {
			console.error('unable to process trimpath template %s', e);
		}
		return result;								
	},
	
	clearObject: function(object, key) {
		var skey = 'object::' + object + '::' + key; 
		if(this.singletons[skey]) {
			this.singletons[skey] = null;
		}
	},
	
	getObject: function(object, args) {
		args.object_name = object; 		
		var reload = false;
		if ( typeof( BF_objects ) != "undefined" ) {
			if(	BF_objects[object] && BF_objects[object].reload ) {
				reload = true;
				/*if(BuzzFeed.debug()) {
					console.info("Object reload set to true for '%s'", object);
				}*/				
			} 				
		}
		/*if(BuzzFeed.debug() && reload == false) {
			console.info("No Object reload set for '%s'", object);							
		}
		*/
		if(eval("typeof(" + object + ")") == "undefined" || reload == true) {			
			var path = BF_OBRoot + object.replace(/_/g, "/") + ".js";
			var response = BuzzFeed.loadFile(path);
			if(! response) {
				console.error('invalid loadFile response, returning null');
				return null;
			}			
			eval(response.content);			
		}
		
		if(args.singleton_key){
			var skey = 'object::' + object + '::' + args.singleton_key; 
			if(! this.singletons[skey]) {
				var object_instance = eval('new ' + object + '()');
				//object_instance = Object.extend(BuzzFeed.BObject.prototype, object_instance);
				//console.dir({deats: object_instance.options, object: object});
				//object_instance.initialize(args);
				object_instance.options = args;								
				this.singletons[skey] = object_instance;
				if(BuzzFeed.debug()) {
					//console.info("singleton request for key %s - init new object", skey);
				}
			} else {				
				if(BuzzFeed.debug()) {
					//console.info("singleton request for key %s - returning cached object", skey);
					//console.dir({deats: this.singletons[skey].options});
				}								
			}	
			return this.singletons[skey];
		} else {
			var object_instance = eval('new ' + object + '()');				
			object_instance.options = args;
			return object_instance;
		}		
	}
}
var BuzzFeedRegistrar = new BuzzFeed.Registrar();
