/* 
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

var appdb = appdb ||{
  rest : {}
};
appdb.rest = {
    domain : "http://appdbpi/",
    version : "0.2",
    servicetype : "rest",
    endpointRegistry : (function(){
        var endpoints = [];
        var _getList = function(){
                var res = [];
                for(var i in endpoints){
                    res[res.length] = i;
                }
                return res;
            };
        var _register = function(name,ep){
                endpoints[name] = appdb.rest.domain + appdb.rest.servicetype+ "/" + appdb.rest.version + "/" + ep + "/"
            };
        var _getEndpoint = function(name){
                return endpoints[name];
            };
        var _callEndpoint = function(endpoint,data,excludelist){
                return {
                    getObject :function(callbck){
                        return appdb.rest.createRequest().requestObject(_getEndpoint(endpoint),data,callbck,excludelist);
                    },
                    getXML : function(callbck){
                        return appdb.rest.createRequest().requestXML(_getEndpoint(endpoint), data, callbck,excludelist);
                    },
                    getText : function(callbck){
                        return appdb.rest.createRequest().requestText(_getEndpoint(endpoint), data, callbck,excludelist);
                    }
                };
            };
        return {
            register : _register,
            getList : _getList,
            getEndpoint : _getEndpoint,
            callEndpoint : _callEndpoint
        };
    })(),
    createObject : function(xmldata,excludeList){
        var buildEntry = function(entry){
            var e = {},i,tmpval=null,tmpnode = null;
            if(entry.nodeType==3){
                return entry.nodeValue;
            }
            var attr = entry.attributes;
            if(attr.length>0){
                for(i=0; i<attr.length; i+=1){
                    if(attr[i].prefix!=="xmlns"){
                        e[attr[i].localName] = attr[i].value;
                    }
                }
            }
            if(entry.hasChildNodes()){
                for(i=0; i<entry.childNodes.length; i+=1){
                    if(entry.childNodes[i].nodeType===3){
                        //e[entry.childNodes[i].nodeName] = entry.childNodes[i].textContent;
                        tmpval = entry.childNodes[i].textContent;
						e["val"] = function(){return tmpval; }
                    } else if(entry.childNodes[i].children.length==1){
                        if(entry.childNodes[i].children.nodeType===3){
                            //e[entry.childNodes[i].localName] = entry.childNodes[i].children[0].nodeValue;
                        	tmpval = entry.childNodes[i].children[0].nodeValue;
			  				e["val"] = function(){return tmpval;}
					}
                    } else {
		      if(e[entry.childNodes[i].localName]){//if tag already exists convert to array of the same tags
			if(typeof e[entry.childNodes[i].localName].length === "undefined"){
			  tmpnode = e[entry.childNodes[i].localName];
			  e[entry.childNodes[i].localName] = [];
			  e[entry.childNodes[i].localName][e[entry.childNodes[i].localName].length] = tmpnode;
			}
			e[entry.childNodes[i].localName][e[entry.childNodes[i].localName].length] = buildEntry(entry.childNodes[i]);
			
		      }else{
			e[entry.childNodes[i].localName] = buildEntry(entry.childNodes[i]);
		      }
                    }
                }
            }
            return e;
        };
        var buildList = function(list){
            var l = {};
            l.count = list.getAttribute("count");
            if(list.getAttribute("pagelength")){
                l.pagelength = list.getAttribute("pagelength");
            }
            if(list.getAttribute("pageoffset")){
                l.pageoffset = list.getAttribute("pageoffset");
            }
            if(list.getAttribute("datatype")){
                l.datatype = list.getAttribute("datatype");
            }
            if(list.hasChildNodes()){
                l.children = [];
                for(var i=0; i<list.childNodes.length; i+=1){
                    if(list.childNodes[i].nodeType===3){
                        continue;
                    }
                    if(excludeList){
                        for(var e=0; e<excludeList.length; e+=1){
                            if(list.childNodes[i].localName!==excludeList[e]){
                                l.children[l.children.length] = buildEntry(list.childNodes[i]);
                            }
                        }
                    }else{
                        l.children[l.children.length] = buildEntry(list.childNodes[i]);
                    }
                }
            }
            return l;
        };
        var obj = {};
        if(xmldata===null){
            return null;
        }
        var data = (xmldata.documentElement)?xmldata.documentElement:xmldata;
        if(data.getAttribute("type")==="list"){
            obj = buildList(data);
        }else{
            obj = buildEntry(data.childNodes[0]);
        }
        return obj;
    },
    createRequest : function(){
        return {
            getXMLResource : function(url,callbck){
                var xmlhttp = new XMLHttpRequest();
                if (typeof XDomainRequest != "undefined"){
                    xmlhttp = new XDomainRequest();
                    
                }
                if(callbck){
                    if (typeof XDomainRequest === "undefined"){
                        xmlhttp.open("GET",url,true);
                        xmlhttp.onreadystatechange = function(aEvt){
                            if(xmlhttp.readyState===4){
                                if(xmlhttp.status===200){
                                    callbck(xmlhttp);
                                }else{
                                    callbck(null);
                                }
                            }
                        };
                    }else{
                        xmlhttp.open("GET",url);
                        xmlhttp.onload = function(d) {
                            callbck(xmlhttp.responseText);
                        }
                    }
                    xmlhttp.send(null);
                    return null;
                }else{
                    if (typeof XDomainRequest === "undefined"){
                        xmlhttp.open("GET",url,false);
                    }else{
                        xmlhttp.open("GET",url);
                    }
                    xmlhttp.send(null);
                    if(callbck){
                        return xmlhttp;
                    }else{
                        xmlhttp.responseXML = $.parseXML(xmlhttp.responseText);
                    }
                    return xmlhttp;
                }
            }, 
/*			getXMLResource : function() { return $.ajax();}, */
            buildQuery : function(resource,data){
                var res = resource;
                if(data){
                    if(typeof data === "object"){
                        res = resource + "?";
                        for(var d in data){
                            res+= d + "=" + encodeURIComponent(data[d])+"&";
                        }
                        res = resource + res.substr(0, res.length-1);
                    } else {
                        res = resource + data + "/";
                    }
                }
                return res;
            },
            excludeElements : function(xml,list){
                var rem  = [];
                for(var i=0; i<xml.documentElement.childNodes.length; i+=1){
                    for(var j=0; j<list.length; j+=1){
                        if(xml.documentElement.childNodes[i].localName===list[j] || xml.documentElement.childNodes[i].nodeType===3){
                            rem[rem.length] = xml.documentElement.childNodes[i];
                        }
                    }
                }
                for(var r =0; r<rem.length; r+=1){
                    xml.documentElement.removeChild(rem[r]);
                }
                return xml;
            },
            removeWhitespace : function(xml){
                var node = xml.documentElement;
                var whitespace = /^\s+$/;
                for (i=0; i < node.childNodes.length; i++){
                    var current = node.childNodes[i];
                    if (current.nodeType == 3 && whitespace.test(current.nodeValue)) {
                        // that is, if it's a whitespace text node
                        node.removeChild(current);
                        i--;
                    }
                }
                return xml;
            },
            requestObject : function(resource,data,callbck,excludelist){
                var u = appdb.rest.createRequest().buildQuery(resource, data);
		var xmlcall = function(xmlres){
                    var error = (xmlres==null)?"Resource not found":((xmlres.responseXML.documentElement.hasAttribute("error"))?xmlres.documentElement.attributes.getAttribute("error"):null);
                    var res = {};
		    if(error!==null){
                        x = {
                            Error:error,
                            Request:resource
                        };
                    }else{
                        res = appdb.rest.createRequest().removeWhitespace(xmlres.responseXML);
                        x = appdb.rest.createObject(res,excludelist);
                    }
                    if(callbck){
		      callbck(x);
		    }else{
		      return x;
		    }
                };
                if(callbck){
		  appdb.rest.createRequest().getXMLResource(u,xmlcall);
		}else{
		  return xmlcall(appdb.rest.createRequest().getXMLResource(u));
		}
		
            },
            requestXML : function(resource,data,callbck,excludelist){
                var u = appdb.rest.createRequest().buildQuery(resource, data);
		var xmlcall = function(xmlres){
                    x = appdb.rest.createRequest().removeWhitespace(xmlres.responseXML);
                    if(excludelist){
                        x= appdb.rest.createRequest().excludeElements(x, excludelist);
                    }
                    if(callbck){
		      callbck(x);
		    }else{
		      return x;
		    }
                };
		if(callbck){
		  appdb.rest.createRequest().getXMLResource(u,xmlcall);
		}else{
		  return xmlcall(appdb.rest.createRequest().getXMLResource(u));
		}
            },
            requestText :function(resource,data,callbck,excludelist){
                var u = appdb.rest.createRequest().buildQuery(resource, data);
		var xmlcall = function(xmlres){
                    x = appdb.rest.createRequest().removeWhitespace(xmlres.responseXML);
                    if(excludelist){
                        x = appdb.rest.createRequest().excludeElements(x, excludelist);
                    }
                    if(callbck){		      
		      callbck((new XMLSerializer()).serializeToString(x));
                    }else{
		      return (new XMLSerializer()).serializeToString(x);
		    }
                };
		if(callbck){
		  appdb.rest.createRequest().getXMLResource(u,xmlcall);
		}else{
		  return xmlcall(appdb.rest.createRequest().getXMLResource(u));
		}
                
            }
        }
    },
    API : {
      applications  : function (data){
	return appdb.rest.endpointRegistry.callEndpoint("applications", data);
      },
      people : function (data){
	return appdb.rest.endpointRegistry.callEndpoint("people", data);
      },
      roles : function(){
        return appdb.rest.endpointRegistry.callEndpoint("roles");
      },
      middlewares : function(){
	return appdb.rest.endpointRegistry.callEndpoint("middlewares");
      },
      disciplines : function(notSubs){
        return appdb.rest.endpointRegistry.callEndpoint("disciplines", null,(notSubs)?["subdiscipline"]:undefined);
      },
      subdisciplines : function(){
        return appdb.rest.endpointRegistry.callEndpoint("disciplines", null,["discipline"]);
      },
      regional : function(){
        return appdb.rest.endpointRegistry.callEndpoint("regional");
      },
      countries : function(){
        return appdb.rest.endpointRegistry.callEndpoint("countries",null,["region"]);
      },
      regions : function(){
	return appdb.rest.endpointRegistry.callEndpoint("regions",null,["country"]);
      },
      vos : function(){
	return appdb.rest.endpointRegistry.callEndpoint("vos");
      },
      statuses : function(){
	return appdb.rest.endpointRegistry.callEndpoint("statuses");
      },
      GetResourceList : function(){
	return appdb.rest.endpointRegistry.getList();
      }  
    }
};
var _epregfunc = appdb.rest.endpointRegistry.register;
_epregfunc("applications", "applications");
_epregfunc("people","people");
_epregfunc("regional","regional");
_epregfunc("countries","regional");
_epregfunc("regions", "regional");
_epregfunc("middlewares","middlewares");
_epregfunc("roles","roles");
_epregfunc("disciplines","disciplines");
_epregfunc("subdisciplines","disciplines");
_epregfunc("statuses","statuses");
_epregfunc("vos","vos");

