// Activate/Deactivate Otto
Otto.ACTIVE = true ;
Otto.GLOBAL_MBOX_ACTIVE = true ;
Otto.DEBUG = false ;
// CONSTANTS
Otto.GLOBAL_TEST_ID = "wp_global" ;
Otto.DEFAULT_MBOX_CLASSNAME = "mboxDefault" ;
Otto.RENDER_DEFAULT_MBOX = true ;
Otto.SUPPRESS_DEFAULT_MBOX = false ;

function Otto() {
	if ( typeof Otto.instance == "undefined" ) {
		// init
		this.init = function() {
			this.setIsLoggedIn();
			this.setSection();
			if (! Otto.GLOBAL_MBOX_ACTIVE ) {
				this.addToTestsDeactivated( Otto.GLOBAL_TEST_ID );
			}
			Otto.instance = this ;
		} ;
		// section stuff
		this.setSection = function() {
			if ( typeof thisNode != "undefined" ) {
				// for wp.com
				this.section = thisNode ;
			} else {
				// do stuff for Registration & Jobs
			}
			return this.section ;
		} ;
		this.getSection = function() {
			return this.section ;
		} ;
		this.section = "" ;
		// logged in stuff
		this.isLoggedIn = false ;
		this.setIsLoggedIn = function() {
			// check lot's of stuff. If any one is true, the user is logged in.
			if ( ! this.loggedIn ) {
				if ( typeof Registration == "function" ) {
					this.loggedIn = Registration.prototype.isSignedIn() ;
				}
			}
			// check for wpniuser cookie: should work for wp.com & Registration
			if ( ! this.loggedIn ) {
				if ( typeof getCookie == "function" ) {
					this.isLoggedIn = ( getCookie("wpniuser") ) ? true : false ;
				} else {
					this.isLoggedIn = document.cookie.indexOf( "wpniuser" ) != -1 ;
				}
			}
			// if no wpniuser cookie, you might not be on wp.com, so try other stuff
			if (! this.loggedIn ) {
				// do stuff for Jobs
			}
		} ;
		this.tests_already_run = "" ;
		this.wasTestAlreadyRun = function(id) {
			return ((this.tests_already_run).indexOf(":"+id+":") != -1) ;
		} ;
		this.addToTestsAlreadyRun = function(id) {
			this.tests_already_run += ":"+id+":" ;
		} ;
		this.tests_deactivated = "" ;
		this.isTestDeactivated = function(id) {
			return ((this.tests_deactivated).indexOf(":"+id+":") != -1) ;
		} ;
		this.addToTestsDeactivated = function(id) {
			this.tests_deactivated += ":"+id+":" ;
		} ;
		this.tests_duplicated = "" ;
		this.isTestDuplicated = function(id) {
			return ((this.tests_duplicated).indexOf(":"+id+":") != -1) ;
		} ;
		this.addToTestsDuplicated = function(id) {
			// if (! this.isTestDuplicated(id) ) {
				this.tests_duplicated += ":"+id+":" ;
			// }
		} ;
		// code output
		this.placeOttoTest = function(test_id,render_default_mox) {
			var debug = "" ;
			if ( Otto.ACTIVE ) {
				// by default, render <div class="mboxDefault"></div>
				if (typeof render_default_mox == "undefined") {
					render_default_mox = Otto.RENDER_DEFAULT_MBOX ;
				}
				if ( !this.isTestDeactivated(test_id) && !this.wasTestAlreadyRun(test_id) ) {
					// mboxCreate defined in mbox.js
					if (typeof mboxCreate == "function") {

						var output = "" ;
						if ( render_default_mox ) {
							output += '<div class="'+Otto.DEFAULT_MBOX_CLASSNAME+'"></div>' ;
							debug += Otto.DEFAULT_MBOX_CLASSNAME+" got placed right here\n" ;
						}
						debug += "created mbox: "+test_id+".\n\n" ;

						document.write( output );

						// mboxCreate defined in mbox.js
						mboxCreate(test_id,'section='+this.section,'loggedin='+this.isLoggedIn );
						this.addToTestsAlreadyRun( test_id );
					} else {
						debug += "mboxCreate is not defined.\n\n" ;
					}
				} else if ( this.wasTestAlreadyRun(test_id) ) {
					this.addToTestsDuplicated( test_id ) ;
				}
			}
			this.debug += debug ;
			if ( Otto.DEBUG ) {
				document.write( debug );
			}
		} ;
		this.placeGlobalOttoTest = function() {
			if ( Otto.GLOBAL_MBOX_ACTIVE ) {
				this.placeOttoTest( Otto.GLOBAL_TEST_ID, Otto.RENDER_DEFAULT_MBOX );
			}
		} ;
		// takes in test_id as the first argument, and arbitrarily more arguments, then calls mboxUpdate
		this.mboxUpdate = function(test_id) {
			var debug = "" ;

			var args = "" ;
			for (var i=0;i<arguments.length;i++) {
				var arg = arguments[i] ;
				if ( i > 0 ) args += "," ;
				if ( typeof arg == "string" )
					args += "'"+arg+"'";
				else
					args += arg ;
			}

			if ( this.wasTestAlreadyRun(test_id) ) {
				// mboxUpdate defined in mbox.js
				var call_mboxUpdate = "mboxUpdate(ARG_LIST)";
				call_mboxUpdate = call_mboxUpdate.replace(/ARG_LIST/,args) ;
				if ( typeof mboxUpdate == "function" ) {
					debug += "Calling mboxUpdate("+args+").\n\n" ;
					eval(call_mboxUpdate);
				}
			} else {
				debug += "The test '"+test_id+"' does not exist so...\nmboxUpdate("+args+") cannot be called.\n\n" ;
			}
			this.debug += debug ;
			if ( Otto.DEBUG ) {
				alert( debug ) ;
			}
		}
		// debug string;
		this.debug = "" ;
		// return info
		this.getInformation = function() {
			var output = "" ;

			output += "Otto.ACTIVE = "+Otto.ACTIVE+"\n" ;
			output += "Otto.GLOBAL_MBOX_ACTIVE = "+Otto.GLOBAL_MBOX_ACTIVE+"\n" ;
			output += "\n" ;

			if ( this.tests_already_run ) {
				output += "TESTS RUN:\n" ;
				output += this.tests_already_run.replace(/::/g,", ").replace(/^:/,'').replace(/:$/,'') ;
			} else {
				output += "NO TESTS RUNNING" ;
			}
			output += "\n\n" ;

			if ( this.tests_deactivated ) {
				output += "TESTS DEACTIVATED:\n" ;
				output += this.tests_deactivated.replace(/::/g,", ").replace(/^:/,'').replace(/:$/,'') ;
			} else {
				output += "NO TESTS DEACTIVATED" ;
			}
			output += "\n\n" ;

			if ( this.tests_duplicated ) {
				output += "TESTS DUPLICATED (ok, but clean up your code):\n" ;
				output += this.tests_duplicated.replace(/::/g,", ").replace(/^:/,'').replace(/:$/,'') ;
			} else {
				output += "NO TESTS DUPLICATED" ;
			}
			output += "\n\n" ;

			if ( this.debug ) {
				output += "DEBUG:\n" ;
				output += this.debug ;
				output += "\n\n" ;
			}

			return output ;
		}

		// RUN LAST: initialize OTTO
		this.init() ;

	} else {
		return Otto.instance ;
	}
}
// singleton method
Otto.getInstance = function() {
	if ( Otto.instance == null ) {
		Otto.instance = new Otto() ;
	}
	return Otto.instance ;
}

// get an Otto instance
if ( typeof otto == "undefined" ) {
	var otto = Otto.getInstance();
}
