
/*////////////////////////////////////////////////////////*/
/*#################### CLS.ESSENTIALS ####################*/
/*////////////////////////////////////////////////////////*/

	/*////////////////////////////////////*/
	/*/////////// PROTO.GET|SET //////////*/
	/*////////////////////////////////////*/

	Object.prototype.toString=function()
	{
		return typeof(this.Get)=='function'?this.Get():this.Value;
	}

/*////////////////////////////////////////////////////////*/
/*####################### OSF.COM ########################*/
/*////////////////////////////////////////////////////////*/

	var COM=
	{
		/*////////////////////////////////////*/
		/*////////// THIS.VARIABLES //////////*/
		/*////////////////////////////////////*/

		Head	:window.document.getElementsByTagName('HEAD')[0],
		Location:null,

		Files	:{},
		Handlers:{},
		Ids		:1,

		utl		:{},

		/*##############################################*/
		/*############## PUBLIC.SOLUTIONS ##############*/
		/*##############################################*/

		/*////////////////////////////////////*/
		/*/////////// THIS.EXTEND ////////////*/
		/*////////////////////////////////////*/

		Extend:function(Extender,Extendee)
		{
			Extendee.prototype=new Extender();
			Extendee.prototype.constructor=Extendee;

			return Extendee;
		},

		/*////////////////////////////////////*/
		/*/////////// THIS.ISARRAY ///////////*/
		/*////////////////////////////////////*/

		isArray:function(Input)
		{
			return (typeof(Input)=='object'?Array.prototype==Input.constructor.prototype:false);
		},

		/*////////////////////////////////////*/
		/*/////////// THIS.ISOBJECT //////////*/
		/*////////////////////////////////////*/

		isObject:function(Input)
		{
			return (typeof(Input)=='object'?Object.prototype==Input.constructor.prototype:false);
		},

		/*////////////////////////////////////*/
		/*/////////// THIS.IMPORT ////////////*/
		/*////////////////////////////////////*/

		Import:function(File,Handle)
		{
			this.SetLocation();

			if(typeof(File)=='string' || typeof(File)=='object')
			{
				var HandleId=this.RegisterHandle(Handle);

				if(typeof(File)=='string')
				{
					this.RegisterImport(File,HandleId);
				}
				else if(typeof(File)=='object' && File.length>0)
				{
					this.RegisterImport(File.splice(0,1)[0],HandleId,null,File);
				}
			}
		},

		/*////////////////////////////////////*/
		/*/////////// THIS.REQUIRE ///////////*/
		/*////////////////////////////////////*/

		Require:function(RequiredBy,File)
		{
			this.SetLocation();

			if(this.Files[RequiredBy] && (typeof(File)=='string' || typeof(File)=='object'))
			{
				if(typeof(File)=='string' && File!=RequiredBy)
				{
					this.RegisterImport(File,null,RequiredBy);
				}
				else if(typeof(File)=='object' && File.length>0)
				{
					this.RegisterImport(File.splice(0,1)[0],null,RequiredBy,File);
				}
			}
		},

		/*##############################################*/
		/*############### PRIVATE.IMPORT ###############*/
		/*##############################################*/

		/*////////////////////////////////////*/
		/*/////// THIS.REGISTERHANDLE ////////*/
		/*////////////////////////////////////*/

		RegisterHandle:function(Handle)
		{
			var HandleId=null;

			if(Handle)
			{
				HandleId='H_'+this.Ids;

				this.Handlers[HandleId]=Handle;

				this.Ids++;
			}

			return HandleId;
		},

		/*////////////////////////////////////*/
		/*/////// THIS.REGISTERIMPORT ////////*/
		/*////////////////////////////////////*/

		RegisterImport:function(File,HandleId,Required,List)
		{
			if(typeof(File)=='string')
			{
				if(!this.Files[File])
				{
					this.Files[File]=
					{
						'Handles'	:[],
						'Requires'	:{},
						'RequiredBy':{},
						'LoadAfter'	:[],
						'Loaded'	:false,
						'Complete'	:false,
						'Node'		:null
					}

					this.LoadImport(File);
				}

				if(HandleId)
				{
					this.Files[File].Handles.push(HandleId);
				}

				if(this.Files[Required] && Required!=File)
				{
					if(this.IsRequired(File,Required))
					{
						this.Files[Required].Requires[File]		=true;
						this.Files[File].RequiredBy[Required]	=true;
					}
				}

				if(typeof(List)=='object')
				{
					this.Files[File].LoadAfter=List;
				}

				this.Files[File].Complete=false;

				this.CheckImport(File);
			}
		},

		/*////////////////////////////////////*/
		/*///////// THIS.LOADIMPORT //////////*/
		/*////////////////////////////////////*/

		LoadImport:function(File)
		{
			if(this.Files[File])
			{
				var Node	=document.createElement('SCRIPT');
				var Stamp	=(new Date()).getTime();

				this.Head.appendChild(Node);

				Node.onload				=function(){ this.Loaded?null:setTimeout('COM.CheckImport("'+this.File+'",true);',10);this.Loaded=true;	};
				Node.onreadystatechange	=function(){ this.readyState=='complete' || this.readyState=='loading' ? null : setTimeout('COM.CheckImport("'+this.File+'",true);',10);	};

				Node.language	='javascript';
				Node.type		='text/javascript';
				Node.File		=File;
				Node.Loaded		=false;
				Node.src		=(File.search('http://')==-1?this.Location+File:File)+(File.indexOf('?')==-1?'?'+Stamp:Stamp);
				
				this.Files[File].Node=Node;
			}
		},

		/*////////////////////////////////////*/
		/*///////// THIS.CHECKIMPORT /////////*/
		/*////////////////////////////////////*/

		CheckImport:function(File,Loaded)
		{
			var Item=this.Files[File];

			if(Item)
			{
				if(Loaded || Item.Loaded)
				{
					var Complete=true;
					Item.Loaded	=true;

					for(var a in Item.Requires)
					{
						if (!Item.Requires.hasOwnProperty(a)) continue;
						
						Complete=false;
						break;
					}

					if(Complete)
					{
						if(Item.LoadAfter.length>0)
						{
							this.Require(File,Item.LoadAfter.splice(0,1)[0]);
							Complete=false;
						}
					}

					if(Complete && !Item.Complete)
					{
						Item.Complete=true;

						for(var a in Item.RequiredBy)
						{
							if (!Item.RequiredBy.hasOwnProperty(a)) continue;
							
							var RequiredBy=this.Files[a];

							if(RequiredBy)
							{
								delete Item.RequiredBy[a];

								if(RequiredBy.Requires[File])
								{
									delete RequiredBy.Requires[File];
									this.CheckImport(a);
								}
							}
						}

						for(var a in Item.Handles)
						{
							if (!Item.Handles.hasOwnProperty(a)) continue;
							
							setTimeout('COM.CallHandle(\''+Item.Handles[a]+'\');',1);
						}

						Item.Handles =[];

						(Item.Node.parentNode?Item.Node.parentNode.removeChild(Item.Node):null);
					}
				}
			}
		},

		/*////////////////////////////////////*/
		/*////////// THIS.CALLHANDLE /////////*/
		/*////////////////////////////////////*/

		CallHandle:function(HandleId)
		{
			var Handle=this.Handlers[HandleId];

			if(Handle)
			{
				if(typeof(Handle)=='function')
				{
					Handle();
				}
				else if(typeof(window[Handle])=='function')
				{
					window[Handle]();
				}

				delete this.Handlers[HandleId];
			}
		},

		/*////////////////////////////////////*/
		/*////////// THIS.ISREQUIRED /////////*/
		/*////////////////////////////////////*/

		IsRequired:function(File,RequiredBy)
		{
			var Required	=true;
			var Item		=this.Files[RequiredBy];

			if(Item)
			{
				if(Item.Requires[File])
				{
					Required=false;
				}

				for(var a in Item.RequiredBy)
				{
					if (!Item.RequiredBy.hasOwnProperty(a)) continue;
					
					if(a==File)
					{
						Required=false;
						break;
					}
					else if(!this.IsRequired(File,a))
					{
						Required=false;
						break;
					}
				}
			}

			return Required;
		},

		/*##############################################*/
		/*################ PRIVATE.HELP ################*/
		/*##############################################*/

		/*////////////////////////////////////*/
		/*///////// THIS.SETLOCATION /////////*/
		/*////////////////////////////////////*/

		SetLocation:function()
		{
			if(this.Location==null)
			{
				for(var a=0;a<this.Head.childNodes.length;a++)
				{
					var Node=this.Head.childNodes[a];

					if(Node.nodeType=='1' && Node.nodeName.toUpperCase()=='SCRIPT')
					{
						if(Node.src.substr(Node.src.length-6,6)=='com.js')
						{
							this.Location=Node.src.replace('com.js','');
							break;
						}
					}
				}
			}
		}
	}
