/*
	Author: Stephen W. Cote
	Email: wranlon@hotmail.com
	
	Copyright 2002, All Rights Reserved.
	
	Do not copy, archive, or distribute without prior written consent of the author.
*/

_js_package("org.cote.js.util.config");

org.cote.js.util.config={
	newInstance:function(s,h,a){
		/*
			ui.object.newInstance draws on js.object.newInstance.
			j.o.n implements the event and style code, and draws on the base
			generic object class definition.
		*/
		var n = {
			object_config:{
				pointers:{
					config:[],
					config_map:[],
					config_load_handler:0
				},
				status:{
					config_path:0,
					config_loaded:0,
					element_parent_name:"config",
					element_name:"param",
					attr_name_name:"name",
					attr_value_name:"value"
				}
			}
		};
		


		n.setElementParentName=function(s){
			this.object_config.status.param_parent_name = s;
		};
		n.setElementName=function(s){
			this.object_config.status.param_child_name = s;
		};
		n.setAttrNameName=function(s){
			this.object_config.status.attr_name_name = s;
		};
		n.setAttrValueName=function(s){
			this.object_config.status.attr_value_name = s;
		};
	
		n.load=function(s,h,a){
			/*
				s = source
				a = async?
				h = handler if async
			*/
			var t = this,_j = org.cote.js,o,c;
			c = t.object_config;
			c.pointers.config_load_handler = (typeof h=="function"?h:0);

			o=_j.xml.getXml(s,null,a,t.object_id);
			
			/*
				If not asynchronous, then parse the result right now.
			*/
			if(!a)
				t._parse_config(o);
			
		};
		
		n._handle_load_xml=function(s,v){
			var t = this;
			if(v.id == t.object_id){
				this._parse_config(v.xdom);
			}
		};

		n.getParams=function(){
			return this.object_config.pointers.config;
		};
		
		n.getParam=function(x){
			var t=this,c,o;
			c = t.object_config;
			if(!c.status.config_loaded) return null;
			if(typeof x=="string")
				x = c.pointers.config_map[x];
			
			if(typeof x=="number" && typeof c.pointers.config[x]=="object")
				return c.pointers.config[x].value;
			
			return null;
		};
		
		n._parse_config=function(o){
			var t = this,c,p,i=0,a,n,v;
			c = t.object_config;

			if(typeof o == "object" && o.documentElement != null){
				c.status.config_loaded = 1;
				a = org.cote.js.xml.queryNodes(o,c.status.element_parent_name,c.status.element_name);
				for(;i<a.length;i++){
					p = a[i];
					n = p.getAttribute(c.status.attr_name_name);
					if(typeof n=="string" && n.length > 0){
						v = p.getAttribute(c.status.attr_value_name);
						if(typeof v!="string") v = "";

						c.pointers.config_map[n]=c.pointers.config.length;

						if(v == "#cdata" && p.hasChildNodes())
							v = org.cote.xml.getCDATAValue(n);
						
						c.pointers.config[c.pointers.config.length]={"name":n,"value":v};
					}
				}
			}

			if(typeof c.pointers.config_load_handler == "function"){
				c.pointers.config_load_handler("onconfigload",this);
			}

		};

		org.cote.js._application_scope.add_object(n);
		


		/*
			Use the message service to pick up the xml loaded event for asynchronous
			operations because:
				- the handler loses its scope to the object instance
				- and that's bad
				
			Doing so means that the handler must correctly identify the config
		*/
		org.cote.js._implements(n,"base_object","config_util","0.1a");		
		org.cote.js.message.MessageService.subscribe(n,"onloadxml","_handle_load_xml");

		if(typeof s == "string"){
			if(!a) a =0;
			n.load(s,h,a);
		}
		
		return n;

	}
}
