/*********************************************************
*		AJAX CLASS
*		Current class is responsible for the ajax calls
*		Designed & developed by Dima Svirid, 2007	
*		Class: ajax.js
*	  Extends: system.js
*********************************************************/
$WI.Ajax = function(options) {
	return new $WI.Class.Ajax().Request(options);
};
$WI.Class.Ajax = new $WI.Class({
	Request: function(options) {
		this._detectEngine();				
		this._initOptions(options);
		this._run();		
		return this;
	},	
	onComplete: function() {
		if(this.options.onComplete)
			this.options.onComplete.apply(this, arguments);		
		return;
	},	
	onFailure: function() {
		if(this.options.onFailure)
			this.options.onFailure.Apply(this, arguments);
		return;
	},
	onOpen: function() {
		if(this.options.onOpen)
			this.options.onOpen.Apply(this, arguments);
		return;
	},
	onSent: function() {
		if(this.options.onSent)
			this.options.onSent.Apply(this, arguments);
		return;
	},
	onReceived: function() {
		if(this.options.onReceived)
			this.options.onReceived.Apply(this, arguments);
		return;
	},
	/*******************************************************************************************
	*	:status
	*	200 - Ok
	*	404 - Page is not found	
	*******************************************************************************************/	
	_onComplete: function() {
		this.engine.onreadystatechange = function(){};		
		switch(this.engine.status) {
			case 200:					
				this.onComplete($WI.Method.XML.Init(this.engine.responseText), this.engine.responseText);
				break;
			default:
				this.onFailure();
				break;		
		}
	},
	_detectEngine: function() {		
		this.engine = $WI.System.Check(
																function(){return new XMLHttpRequest();},
																function(){return new ActiveXObject('Msxml2.XMLHTTP');},
																function(){return new ActiveXObject('Microsoft.XMLHTTP');}
																);
	},
	_run: function() {
		this.engine.open(this.options.method.toUpperCase(), this.options.url, this.options.async);		
    this.engine.onreadystatechange = this._changeStatus.Apply(this);	
			
		//set headers		
		if (this.options.method.toUpperCase()=='POST') 
			this.engine.setRequestHeader('Content-type', 'application/x-www-form-urlencoded;charset=UTF-8');
		this.engine.setRequestHeader('Powered-By', 'PRISM');
		this.engine.setRequestHeader('Accept', 'text/javascript, text/html, application/xml, text/xml, */*');
		this.engine.setRequestHeader('Connection', 'close');
		
    this.engine.send((this.options.method.toUpperCase()=='POST')?this.options.parameters:null);
	},
	/*******************************************************************************************
	*	:readyState
	*	0 - Not initialized
	*	1 - Open
	*	2 - Sent
	*	3 - Received
	*	4 - Loaded
	*******************************************************************************************/	
	_changeStatus: function() {
		switch(this.engine.readyState) {
			case 1:
				this.onOpen();			break;
			case 2:
				this.onSent();			break;
			case 3:
				this.onReceived();	break;	
			case 4:				
				this._onComplete();	break;
		}
  },
	_initOptions: function(options) {
		 this.options = {
		 								url: '',
										parameters: '',
										method: 'get',
										async: true								
										}
		 $WI._append(this.options, options);
	}	
});
$WI.extend($WI.Class.DOM, $WI.Class.Ajax);

/*********************************************************
*		XML CLASS
*********************************************************/
$WI.Method.XML = {
	Init: function(text) {	
		if(!text||$WI.System.Trim(text)=='') var text = "<?xml version=\"1.0\"?>";
		if (window.ActiveXObject) {
		  var xmlDoc=new ActiveXObject("Microsoft.XMLDOM");
		  xmlDoc.async="false";
		  xmlDoc.loadXML(text);
  	} else {
			var parser=new DOMParser();
		  var xmlDoc=parser.parseFromString(text,"text/xml");
  	}	
		return xmlDoc;
	},	
	CreateNode: function(xmlDoc, what, value, where) {
		if(!what||!xmlDoc) return;
		if(where) var x=xmlDoc.getElementsByTagName(where);
		else var x=xmlDoc.documentElement;
		
		var newel=xmlDoc.createElement(what);
  	var newtext=xmlDoc.createTextNode(value);
  			newel.appendChild(newtext);
  			x.appendChild(newel);				
				
		return newel;
	},
	GetNode: function(xmlDoc, node){
		
	},
	GetNodeValue: function(xmlDoc, node){
		var nodes = node.split('/');
	}, 	
	List: function(xml, root) {
		var root = xml.getElementsByTagName(root);
		var list = [];
		var obj = {};
		if(root.length>0)
			var children = $WI.DOM._getChildren(root[0]);
		//get attributes		
		for(var i=0;i<children.length;i++) {
			var atribs = $WI.DOM._getChildren(children[i]);
			if(atribs.length>0) {
				obj = {};				
				for(var j=0;j<atribs.length;j++) {
					obj[atribs[j].tagName] = atribs[j].firstChild.nodeValue;
				}
			}			
			list.push(obj);
		}
  	return list;
	}, 	
	toString: function(obj){
		var ret = "";
		for (var i=0; i < obj.length; i++) {
	    ret += obj._nodes[i].toString();
	  }
  	return ret;
	} 	
};

/*********************************************************
*		PROTOTYPING SOME REQUIRED FOR XPATH METHODS
*********************************************************/
if( document.implementation.hasFeature("XPath", "3.0") ) {	
	$WI._extend(XMLDocument, {
		selectNodes: function(cXPathString, xNode) {
			if( !xNode ) xNode = this;
			var oNSResolver = this.createNSResolver(this.documentElement);
			var aItems = this.evaluate(cXPathString, xNode, oNSResolver, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null);
			var aResult = [];
			for( var i = 0; i < aItems.snapshotLength; i++)
				aResult[i] =  aItems.snapshotItem(i);
			return aResult;
		},
		selectSingleNode: function(cXPathString, xNode) {
			if( !xNode ) xNode = this;
			var xItems = this.selectNodes(cXPathString, xNode);
			if( xItems.length > 0 )	return xItems[0];
			else return null;
		}
	});	
	$WI._extend(Element, {
		selectNodes: function(cXPathString) {
			if(this.ownerDocument.selectNodes)
				return this.ownerDocument.selectNodes(cXPathString, this);
			else throw "For XML Elements Only";
		},
		selectSingleNode: function(cXPathString) {
			if(this.ownerDocument.selectSingleNode)
				return this.ownerDocument.selectSingleNode(cXPathString, this);
			else throw "For XML Elements Only";
		}
	});
}
	
