//Creating Objects as namespaces
/////////////////////////////////////////////////////////////////////
//Structures:
//1.1 Simple function
/*function myNamespace(i_property1) {
	this.property1 = i_property1;
	this.display = function(text){alert(text);}
}
alert(myNamespace);//=>function myNamespace(i_property1) {this.property1 = i_property1;this.display = function (text) {alert(text);};}
alert(myNamespace.toSource());//=>function myNamespace(i_property1) {this.property1 = i_property1;this.display = function (text) {alert(text);};}
alert(myNamespace.display);//=>undefined
//myNamespace.display("eeee");//=>Error: myNamespace.display is not a function
var test = new myNamespace("eee");
alert(test);//=>[object Object]
alert(test.toSource());//=>({property1:"eee", display:(function (text) {alert(text);})})
alert(test.display);//=>function (text) {alert(text);}
test.display("eeee");//=>eeee*/
/////////////////////////////////////////////////////////////////////
//1.2 Anonymous function
/*var myNamespace = function (i_property1) {
	this.property1 = i_property1;
	this.display = function(text){alert(text);}
}
alert(myNamespace);//=>function (i_property1) {this.property1 = i_property1;this.display = function (text) {alert(text);};}
alert(myNamespace.toSource());//=>(function (i_property1) {this.property1 = i_property1;this.display = function (text) {alert(text);};})
alert(myNamespace.display)//=>undefined
//myNamespace.display("eeee");//=>Error: myNamespace.display is not a function
var test = new myNamespace("eee");
alert(test);//=>[object Object]
alert(test.toSource());//=>({property1:"eee", display:(function (text) {alert(text);})})
alert(test.display);//=>function (text) {alert(text);}
test.display("eeee");//=>eeee*/
/////////////////////////////////////////////////////////////////////
//2.Object Literal notation (a shortcut method for creating "objects" using name/value pairs)
//The object literal is encapsulated by curly brackets with zero or more property and value pairs, separated by commas.
//Each property and value is separated by a colon.
//used in modsposition.js
/*var myNamespace = {
	display : function(text) {     
		alert(text);
	}
}
alert(myNamespace);//=>[object Object]
alert(myNamespace.toSource());//=>({display:(function (text) {alert(text);})})
alert(myNamespace.display)//=>function (text) {alert(text);}
myNamespace.display("eeee");//=>eeee
var test = new myNamespace();//=>error:Error: myNamespace is not a constructor*/
/////////////////////////////////////////////////////////////////////
//3.Simple function & Object Literal notation
/*function myNamespace(i_property1) {
	return {
		property1 : i_property1, 
		display : function(text){alert(text);},  
	}; 
}
alert(myNamespace);//=>function myNamespace(i_property1) {return {property1:i_property1, display:function (text) {alert(text);}};}
alert(myNamespace.toSource());//=>function myNamespace(i_property1) {return {property1:i_property1, display:function (text) {alert(text);}};}
alert(myNamespace.display)//=>undefined
//myNamespace.display("eeee");//=>Error: myNamespace.display is not a function
var test = new myNamespace("eee");
alert(test);//=>[object Object]
alert(test.toSource());//=>({property1:"eee", display:(function (text) {alert(text);})})
alert(test.display);//=>function (text) {alert(text);}
test.display("eeee");//=>eeee*/
/////////////////////////////////////////////////////////////////////
//4 Anonymous function & Object Literal notation & Autoexecution
//http://www.lixo.org/archives/2007/09/14/javascript-put-everything-in-a-namespace/
//Creating an anonymous function that returns the object I want to define, 
//and then immediately calling it (note the ‘()’ at the last line).
//Will only work with an anonymous function :
//No "function myNamespace(i_property1){}" only "var myNamespace = function(i_property1){}" will work.
//http://www.dustindiaz.com/namespace-your-javascript
/*var myNamespace = function(i_property1) {
	return {
		property1 : i_property1, 
		display : function(text){alert(text);},  
	}; 
}();
alert(myNamespace);//=>[object Object]
alert(myNamespace.toSource());//=>({property1:undefined, display:(function (text) {alert(text);})})
alert(myNamespace.display)//=>function (text) {alert(text);}
myNamespace.display("eeee");//=>eeee
//var test = new myNamespace("eee");//=>error:Error: myNamespace is not a constructor*/
/////////////////////////////////////////////////////////////////////
//Memory Leak with namespaces:
//SOURCE:http://www.digital-web.com/articles/objectifying_javascript/
//We have seen that a simple function used as a namespace could give us a lot of advantages but the drawback 
//was that the main function,used as a namespace, wrapped all the other functions.
//If you 'instantiate' the 'class' several times and that it contains hundreds of lines, these hundreds of lines 
//will be copied in memory several times. Creating a thousand objects would create a thousand copies of each method 
//and property, taking up valuable memory and creating the potential for memory leaks.
//Luckily for us, there’s a way to create object templates that generate objects that all reference the 
//same methods and properties: We attach properties to the template’s prototype. Doing so, any objects 
//instantiated from the original template will be able to use the methods and properties from the template’s 
//prototype instead of creating their own copies. In short, a call to a property of an object first checks 
//the object itself for the property; if it doesn’t exist, it’ll check it’s template’s prototype chain; we’ll only 
//have one version of the property stored in memory, no matter how many objects we create.
//SOURCE:http://www.webmasterworld.com/javascript/3066162.htm
//using prototypes allows a single instance of a method to be shared by all instances of a "class"
/////////////////////////////////////////////////////////////////////
//5.1 Anonymous function & Object Literal notation & Prototype!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
//used in modsctrl.js
/*var myNamespace = function (i_property1){
	this.property1 = i_property1;
}
myNamespace.prototype = {//this will be the same as myNamespace.prototype.display = function(text){alert(text);}
	display:function(text){alert(text);}
}
alert(myNamespace);//=>function (i_property1) {this.property1 = i_property1;}
alert(myNamespace.toSource());//=>(function (i_property1) {this.property1 = i_property1;})
alert(myNamespace.prototype.toSource());//=>({display:(function (text) {alert(text);})})
alert(myNamespace.display)//=>undefined
//myNamespace.display("eeee");//=>Error: myNamespace.display is not a function
var test = new myNamespace("eee");
alert(test);//=>[object Object]
alert(test.toSource());//=>({property1:"eee"})
alert(test.display);//=>function (text) {alert(text);}
test.display("eeee");//=>eeee*/
/////////////////////////////////////////////////////////////////////
//5.2 Anonymous function & Object Literal notation & Autoexecution & Prototype
//Then you can make lots of myClass objects like this:
/*var myNamespace = function() {
	var myClass = function(i_property1) {
		this.property1 = i_property1;
	}
	myClass.prototype.display = function (text) {alert(text);}
	return {myClass : myClass};
}();

alert(myNamespace);//=>[object Object]
alert(myNamespace.toSource());//=>({myClass:(function (i_property1) {this.property1 = i_property1;})})
alert(myNamespace.myClass);//=>function (i_property1) {this.property1 = i_property1;}
alert(myNamespace.myClass.toSource());//=>(function (i_property1) {this.property1 = i_property1;})
alert(myNamespace.myClass.display);//=>undefined
alert(myNamespace.myClass.prototype.toSource());//=>({display:(function (text) {alert(text);})})
//var test = new myNamespace("eee");//=>error:Error: myNamespace is not a constructor
var test2 = new myNamespace.myClass("eee");
alert(test2.toSource());//=>({property1:"eee"})
alert(test2);//=>[object Object]
alert(test2.display);//=>function (text) {alert(text);}*/

/////////////////////////////////////////////////////////////////////
//prompt("",//alert(

/*var myNamespace = function() {};
myNamespace = myNamespace.prototype=function () {};

//myNamespace.My1 = function() {};
//myNamespace.My1 = myNamespace.My1.prototype= function() {};

myNamespace.Strings={
firstToUpperCase : function(str) {
  return str.replace(/^([a-z])/, function(m, l){return l.toUpperCase()});
}
};
alert(myNamespace.toSource());//=>(function () {})
alert(myNamespace.prototype.toSource());//=>({})
alert(myNamespace.Strings.toSource());//=>({firstToUpperCase:(function (str) {return str.replace(/^([a-z])/, function (m, l) {return l.toUpperCase();});})})
alert(myNamespace.Strings.firstToUpperCase("eeee"));//=>Eeee
var test = new myNamespace();
alert(test);//=>[object Object]
alert(test.toSource());//=>({})
//alert(test.prototype.toSource());//=>Error: test.prototype has no properties
//alert(test.Strings.firstToUpperCase);//=>Error: test.Strings has no properties
//alert(test.Strings.firstToUpperCase("eeee"));//=>Error: test.Strings has no properties*/
/////////////////////////////////////////////////////////////////////

/*var myNamespace = function() {};
myNamespace = myNamespace.prototype={
firstToUpperCase : function(str) {
  return str.replace(/^([a-z])/, function(m, l){return l.toUpperCase()});
}
};
alert(myNamespace.toSource());//=>({firstToUpperCase:(function (str) {return str.replace(/^([a-z])/, function (m, l) {return l.toUpperCase();});})})
//alert(myNamespace.prototype.toSource());//=>Error: myNamespace.prototype has no properties
alert(myNamespace.firstToUpperCase.toSource());//=>(function (str) {return str.replace(/^([a-z])/, function (m, l) {return l.toUpperCase();});})
alert(myNamespace.firstToUpperCase("eeee"));//=>Eeee
//var test = new myNamespace();//=>Error: myNamespace is not a constructor*/

/////////////////////////////////////////////////////////////////////
//SOURCE:http://shiriru.blogspot.com/2007/12/javascript-simulating-namespaces-part-2.html
/////////////////////////////////////////////////////////////////////
//Carful with var garwin = function (){}; is not the same as var garwin = {};. If you use only the brackets then 
//when you use alert(garwin.toSource()); you get all the prototype methods and you seem to lose the hole idea of
//using prototype in the first place.

//var garwin = garwin ? garwin : function (){};//This could be used to check if namespace not already created and if not create it.
var garwin = function (){//function used as a container.
	this.Type = "Garwin";
};
garwin = window.garwin = garwin.prototype = {//extend garwin namespace thru its prototype.BY SETTING garwin = garwin.prototype we can add to and ACCESS garwin prototype methodes straight away without having to create new garwin();
	/*namespace:function(sName){//creates namespace in the same way as the garwin namespace was created
		var namespaces = sName.split('.') || [sName];
 		var nlen = namespaces.length;
 		var root = window;
 		var F = function() {};
 		for(var i=0; i < nlen; i++) {
 			var ns = namespaces[i];
  			if(typeof(root[ns])==='undefined') {
  				root = root[ns] = F;
  				root = root.prototype = F;
 			}
  			else
   				root = root[ns];
 		}
	},*/
	getType:function(i_obj){
		return(i_obj.constructor.toString());
	},
	getUnique:function ()
	{
		return(new Date().getTime());
	},
	////////////
	//http://jibbering.com/faq/faq_notes/closures.html
	createDelegateByName: function(obj, methodName){
		return(this.createDelegate(obj,obj[methodName]));
		/*return (
			function(){
				//return obj[methodName]();
				return obj[methodName].apply(obj,arguments);
			});*/
	},
	createDelegate: function(instance, method)//ex:garwin.createDelegate(this, this.toolbarAction)
	{
   	//alert("instance arguments[0]="+arguments[0]);
   	//alert("method arguments[1]="+arguments[1]);
    return function(){
			//alert("return instance="+instance);
			//alert("return method="+method);
    	//alert("return arguments.length="+arguments.length);
			//alert("return arguments[0]="+arguments[0]);//arguments[0] = [object Event]  	
			//prompt("","return arguments[1]="+arguments[1]);//return arguments[1]=javascript:__doPostBack('MainMenuControl$anchor_8','')
   	 	method.apply(instance, arguments);
  	};
	},
	///////////////////////THE FOLLOWING TO CHECK
	escapeForEval: function(s)	//needs work...
	{
		return s.replace(/\\/g, '\\\\').replace(/\'/g, "\\'").replace(/\r/g, '').replace(/\n/g, '\\n').replace(/\./, '\\.');
	},
	encode: function(sArg)
	{
		if (encodeURIComponent)
			return encodeURIComponent(sArg);
		else
			return escape(sArg);
	},
	///////////////////////THE FOLLOWING TO CHECK
	delay : new Array(),
	//garwin.doDelay('WaitForCssStyles', 10, garwin.createDelegate(this,this.LoadStyles));
 	doDelay: function(name, iTime, pFunc, oContext) 
	{
		if (this.delay[name] == null)
		{
			this.delay[name] = new garwin.delayObject(pFunc, oContext, name);
			//this.delay[name].num = window.setTimeout(dnn.dom.getObjMethRef(this.delay[name], 'complete'), iTime);
			this.delay[name].num = window.setTimeout(garwin.createDelegate(this.delay[name], this.delay[name].complete), iTime);
		}
	},
	cancelDelay: function(name)
	{
		if (this.delay[name] != null)
		{
			window.clearTimeout(this.delay[name].num);
			this.delay[name] = null;
		}
	},
	delayObject: function(pFunc, oContext, name)
	{
		this.num = null;
		this.pfunc = pFunc;
		this.context = oContext;
		this.name = name;
	} 	
}
garwin.delayObject.prototype =
{
	complete: function()
	{
		//alert("garwin.delayObject this.type="+this.type)
		garwin.delay[this.name] = null;
			this.pfunc(this.context);
	}
}

//With garwin.prototype = {}
/*alert(garwin);//=>function () {}
alert(garwin.toSource());//=>(function () {})
alert(garwin.prototype.toSource());//=>({display:(function (text) {alert(text);}), namespace:(function (sName) {var namespaces = sName.split(".") || [sName];var nlen = namespaces.length;var root = window;var F = function () {};for (var i = 0; i < nlen; i++) {var ns = namespaces[i];if (typeof root[ns] === "undefined") {root = root[ns] = F;root = root.prototype = F;} else {root = root[ns];}}})})
alert(garwin.display)//=>undefined
var test = new garwin();
alert(test);//=>[object Object]
alert(test.toSource());//=>({})
alert(test.display);//=>function (text) {alert(text);}
test.display("eeee");//=>eeee*/
/////
//With garwin = garwin.prototype = {}
/*alert(garwin);//=>[object Object]
alert(garwin.toSource());//=>({display:(function (text) {alert(text);}), namespace:(function (sName) {var namespaces = sName.split(".") || [sName];var nlen = namespaces.length;var root = window;var F = function () {};for (var i = 0; i < nlen; i++) {var ns = namespaces[i];if (typeof root[ns] === "undefined") {root = root[ns] = F;root = root.prototype = F;} else {root = root[ns];}}})})
//alert(garwin.prototype.toSource());//=>Error: garwin.prototype has no properties
alert(garwin.display)//=>function (text) {alert(text);}
garwin.display("eeee");//=>eeee
//var test = new garwin();//=>Error: garwin is not a constructor*/
/////////////////////////////////////////////////////////












