function DataAccess(){
	if(!this.getRequest()){
		alert("Sorry! Map could not be initialized.\n Please upgrade your browser.");
	}
}


DataAccess.prototype.getRequest = function(){
	var activexModes=["Msxml2.XMLHTTP", "Microsoft.XMLHTTP"];
	if (window.ActiveXObject){
		for (var i=0; i<activexModes.length; i++){
			try{
				return new ActiveXObject(activexModes[i]);
			}catch(e){
			}
		}
	}else if(window.XMLHttpRequest){
		var request = new XMLHttpRequest();
		if (request.overrideMimeType){
			request.overrideMimeType("text/xml; charset=utf-8");
		}
		return request;
	}else{
		return false
	}
}

DataAccess.prototype.getXmlDom = function(documentUrl){
	var xmlDom;
	
	if(navigator.userAgent.toLowerCase().indexOf('safari/') != -1){
		var request = this.getRequest();
		
		request.onreadystatechange = function(){
			if(request.readyState != 4){
				return false;
			}else{
				xmlDom = request.responseXML;
				return true;
			}
		};
		
		request.open("get", documentUrl, false);
		request.send(null);
	}else{
		if(document.implementation && document.implementation.createDocument){
			xmlDom = document.implementation.createDocument("", "", null);
		}else if(window.ActiveXObject){
			xmlDom = new ActiveXObject("Microsoft.XMLDOM");
			
		}
		xmlDom.async = false;
		xmlDom.preserveWhiteSpace = false;
		xmlDom.load(documentUrl);
	}

	return xmlDom;
}

DataAccess.prototype.getXmlData = function(documentUrl){
	var xmlDom = this.getXmlDom(documentUrl);
	var root = xmlDom.documentElement;
	
	this.prepareTree(root);
	var xmlData = this.parseDocument(root);
	xmlData = xmlData["gov.fec.map"];
	
	return xmlData;
}

DataAccess.prototype.loadXmlData = function(xmlData){
	var myXml = xmlData.toString().replace(/^\s+|\s+$/, '').toLowerCase();
	try
	{
		var xmlDoc = new ActiveXObject("Microsoft.XMLDOM");
		xmlDoc.async="false";
		xmlDoc.loadXML(myXml);
		return xmlDoc;
	}catch(e){
		try
		{
			parser=new DOMParser();
			xmlDoc=parser.parseFromString(xmlData, "text/xml");
			return xmlDoc;
		}catch(e){
			alert(e.message)
		}
	}
	return null;
}

DataAccess.prototype.prepareTree = function(tree){
	if(tree == undefined) return;
	var notWhitespace = /\S/;
	for(var i=0; i<tree.childNodes.length; i++){
		var childNode = tree.childNodes[i];
		if((childNode.nodeType == 3) && (!notWhitespace.test(childNode.nodeValue))) {
			tree.removeChild(tree.childNodes[i]);
			i--;
		}
	
		if(childNode.nodeType == 1) {
			this.prepareTree(childNode);
		}
	}
}

DataAccess.prototype.parseDocument = function ( root ) {
    if ( ! root ) return;
    
    var ret = this.parseElement( root );
    if ( this.usearray == true ) { 
        ret = [ ret ];
    } else if ( this.usearray == false ) {         

    } else if ( this.usearray == null ) {         

    } else if ( this.usearray[root.nodeName] ) {   
        ret = [ ret ];
    }
    
    var json = {};
    json[root.nodeName] = ret; 
    return json;
};


DataAccess.prototype.parseElement = function ( elem ) {
    if ( elem.nodeType == 7 ) {
        return;
    }
    if ( elem.nodeType == 3 || elem.nodeType == 4 ) {
        var bool = elem.nodeValue.match( /[^\x00-\x20]/ );
        if ( bool == null ) return;
        return elem.nodeValue;
    }
    var retval;
    var cnt = {};
    if ( elem.attributes && elem.attributes.length ) {
        retval = {};
        for ( var i=0; i<elem.attributes.length; i++ ) {
            var key = elem.attributes[i].nodeName;
            if ( typeof(key) != "string" ) continue;
            var val = elem.attributes[i].nodeValue;
            if ( ! val ) continue;
            if ( typeof(cnt[key]) == "undefined" ) cnt[key] = 0;
            cnt[key] ++;
            this.addNode( retval, key, cnt[key], val );
        }
    }

    if ( elem.childNodes && elem.childNodes.length ) {
        var textonly = true;
        if ( retval ) textonly = false;
        for ( var i=0; i<elem.childNodes.length && textonly; i++ ) {
            var ntype = elem.childNodes[i].nodeType;
            if ( ntype == 3 || ntype == 4 ) continue;
            textonly = false;
        }
        if (textonly) {
            if ( ! retval ) retval = "";
            for ( var i=0; i<elem.childNodes.length; i++ ) {
                retval += elem.childNodes[i].nodeValue;
            }
        } else {
            if ( ! retval ) retval = {};
            for ( var i=0; i<elem.childNodes.length; i++ ) {
                var key = elem.childNodes[i].nodeName;
                if ( typeof(key) != "string" ) continue;
                var val = this.parseElement( elem.childNodes[i] );
                if ( ! val ) continue;
                if ( typeof(cnt[key]) == "undefined" ) cnt[key] = 0;
                cnt[key] ++;
                this.addNode( retval, key, cnt[key], val );
            }
        }
    }
    return retval;
};

DataAccess.prototype.addNode = function ( hash, key, cnts, val ) {	
	if ( this.usearray == true ) {
        if ( cnts == 1 ) hash[key] = [];
        hash[key][hash[key].length] = val; 
    } else if ( this.usearray == false ) {
        if ( cnts == 1 ) hash[key] = val;
    } else if ( this.usearray == null ) {
        if ( cnts == 1 ) {  
            hash[key] = val;
        } else if ( cnts == 2 ) {           
            hash[key] = [ hash[key], val ];
        } else {                          
            hash[key][hash[key].length] = val;
        }
    } else if ( this.usearray[key] ) {
        if ( cnts == 1 ) hash[key] = [];
        hash[key][hash[key].length] = val;
    } else {
        if ( cnts == 1 ) hash[key] = val;
    }
};
