function MapParameters() {
    this.tmId = null;
    this.x = null;
    this.y = null;
    this.scale = null;
    this.width = null;
    this.height = null;
    this.sourceIds = new Array();
    this.objectIds = new Array();
    this.drawScaleBar = true;
}
function TMapIdentifier() {
    this.id = null;
    this.name = null;
    this.description = null;
}
function MaxExtent() {
    this.XMin = null;
    this.XMax = null;
    this.YMin = null;
    this.YMax = null;
}
function AddresserInfo() {
    this.classifierID = null;
    this.semanticID = null;
}
function MapIdentifier() {
    this.id = null;
    this.name = null;
    this.description = null;
    this.tmapIds = new Array();
    this.maxExtent = new MaxExtent();
    this.minScale = null;
    this.maxScale = null;
    this.addresserInfo = new AddresserInfo();
}
function ManagedElement() {
    this.code = null;
    this.display = null;
	this.legend = null;
	this.childs = null;
}
function AddresserObject(id, name) {
    TextItem.call(this, name);
    this.id = id;
    this.setDefStyle('addrListDefItem');
    this.setHLStyle('addrListHLItem');
}

function WH() {
    var READY_STATE_UNINITIALIZED = 0;
    var READY_STATE_LOADING = 1;
    var READY_STATE_LOADED = 2;
    var READY_STATE_INTERACTIVE = 3;
    var READY_STATE_COMPLETE = 4;

	var isLoading = false;
    var request = null;
    var completeHandler = null;
    var errorHandler = null;

    var onReadyState = function() {
        var ready = request.readyState;
        if (ready == READY_STATE_COMPLETE) {
            var httpStatus = request.status;
            if (httpStatus == 200 || httpStatus == 0) {
				if(isLoading) {
					completeHandler.call(request);
					isLoading = false;
				}
            }
            else {
                errorHandler.call(request);
				isLoading = false;
            }
        }
    }
    var defaultError = function() {
        alert("Error!!!\n\nReadyState:" + this.readyState
            + "\nStatus: " + this.status
            + "\nHeaders: " + this.getAllResponseHeaders()
            + "\nResponse: " + this.responseText);
    }

    var loadXMLDoc = function(url, method, content, contentType, contentLength, headers, async) {
        if (!method) {
            method = "GET";
        }
        if (!contentType && method == "POST") {
            contentType = 'text/xml; charset=utf-8';
        }
		if (window.XMLHttpRequest && !$.browser.msie) {
            request = new XMLHttpRequest();
        }
		else if (window.ActiveXObject) {
			try {
				request = new ActiveXObject("Msxml2.XMLHTTP");
			}
			catch (error) {
				request = new ActiveXObject("Microsoft.XMLHTTP");
			}
		}
       
        if (request) {
            try {
                request.open(method, url, async);
                if (contentType) {
                    request.setRequestHeader('Content-Type', contentType);
                }
                if (contentLength) {
                    request.setRequestHeader('Content-Length', contentLength);
                }
                if (headers) {
                    for (var h in headers) {
                        request.setRequestHeader(h, headers[h]);
                    }
                }
                request.onreadystatechange = onReadyState;
				isLoading = true;
                request.send(content);
				if(!async)
					isLoading = false;
            }
            catch (error) {
                errorHandler.call(request);
				isLoading = false;
            }
        }
    }
    var callMethod = function(url, onComplete, onError, method, content, contentType, contentLength, headers, async) {
        request = null;
        completeHandler = onComplete;
        errorHandler = (onError) ? onError : defaultError;
        if(async == undefined)
            async = true;
        loadXMLDoc(url, method, content, contentType, contentLength, headers, async);
    }

    this.MapWrapperURL = 'http://localhost/MapControlAJAX/MapWrapper.asmx';
    this.Namespace = 'http://tempuri.org/';
    this.Host = 'localhost';

	this.Abort = function(){
		if(isLoading && request) {
			isLoading = false;
			request.abort();
		}	
	}
	
    this.GM = function(onComplete, onError) {
        var request = SH.GM();
        callMethod(this.MapWrapperURL, onComplete, onError, 'POST', request, 'text/xml; charset=utf-8', request.length, { MessageType: "call", Host: this.Host, SOAPAction: this.Namespace + "GetMaps" });
    }
    this.GTM = function(onComplete, onError, mId) {
        var request = SH.GTM(mId);
        callMethod(this.MapWrapperURL, onComplete, onError, 'POST', request, 'text/xml; charset=utf-8', request.length, { MessageType: "call", Host: this.Host, SOAPAction: this.Namespace + "GetThematicMaps" });
    }
    this.GCMP = function(onComplete, onError, params, rect_x, rect_y, rect_width, rect_height) {
        var request = SH.GCMP(params, rect_x, rect_y, rect_width, rect_height);
        callMethod(this.MapWrapperURL, onComplete, onError, 'POST', request, 'text/xml; charset=utf-8', request.length, { MessageType: "call", Host: this.Host, SOAPAction: this.Namespace + "GetCorrectMapParameters" });
    }
    this.GMEMP = function(onComplete, onError, tmId, width, height) {
        var request = SH.GMEMP(tmId, width, height);
        callMethod(this.MapWrapperURL, onComplete, onError, 'POST', request, 'text/xml; charset=utf-8', request.length, { MessageType: "call", Host: this.Host, SOAPAction: this.Namespace + "GetMaxExtentMapParameters" });
    }
    this.VSID = function(onComplete, onError, params, type, id) {
        var request = SH.VSID(params, type, id);
        callMethod(this.MapWrapperURL, onComplete, onError, 'POST', request, 'text/xml; charset=utf-8', request.length, { MessageType: "call", Host: this.Host, SOAPAction: this.Namespace + "VerifySemanticID" });
    }
    this.GTT = function(onComplete, onError, params, x, y) {
        var request = SH.GTT(params, x, y);
        callMethod(this.MapWrapperURL, onComplete, onError, 'POST', request, 'text/xml; charset=utf-8', request.length, { MessageType: "call", Host: this.Host, SOAPAction: this.Namespace + "GetTooltip" });
    }
	this.GTT2 = function(onComplete, onError, params, x, y, layers) {
        var request = SH.GTT2(params, x, y, layers);
        callMethod(this.MapWrapperURL, onComplete, onError, 'POST', request, 'text/xml; charset=utf-8', request.length, { MessageType: "call", Host: this.Host, SOAPAction: this.Namespace + "GetTooltip2" });
    }
    this.GSID = function(onComplete, onError, params, x, y, type) {
        var request = SH.GSID(params, x, y, type);
        callMethod(this.MapWrapperURL, onComplete, onError, 'POST', request, 'text/xml; charset=utf-8', request.length, { MessageType: "call", Host: this.Host, SOAPAction: this.Namespace + "GetSemanticID" });
    }
	this.GPOI = function(onComplete, onError )
	{ var request = SH.GPOI();
        callMethod(this.MapWrapperURL, onComplete, onError, 'POST', request, 'text/xml; charset=utf-8', request.length, { MessageType: "call", Host: this.Host, SOAPAction: this.Namespace + "GetPointsOfInterestInJson" });}
    this.GMPA = function(onComplete, onError, params, regionName, areaName, moName, townName, streetName, addressName) {
        var request = SH.GMPA(tmid, params, regionName, areaName, moName, townName, streetName, addressName);
        callMethod(this.MapWrapperURL, onComplete, onError, 'POST', request, 'text/xml; charset=utf-8', request.length, { MessageType: "call", Host: this.Host, SOAPAction: this.Namespace + "GetMapParametersByAddress" });
    }
    this.GMPYA = function(onComplete, onError, width, height, streetName, addressName) {
        var request = SH.GMPYA(width, height, streetName, addressName);
        callMethod(this.MapWrapperURL, onComplete, onError, 'POST', request, 'text/xml; charset=utf-8', request.length, { MessageType: "call", Host: this.Host, SOAPAction: this.Namespace + "GetMapParametersByYarAddress" });
    }
    this.GMPTA = function(onComplete, onError, width, height, townName, streetName, addressName) {
        var request = SH.GMPTA(width, height, townName, streetName, addressName);
        callMethod(this.MapWrapperURL, onComplete, onError, 'POST', request, 'text/xml; charset=utf-8', request.length, { MessageType: "call", Host: this.Host, SOAPAction: this.Namespace + "GetMapParametersByTownAddress" });
    }
	this.GME  = function(onComplete, onError, tmID) {
        var request = SH.GME(tmID);
        callMethod(this.MapWrapperURL, onComplete, onError, 'POST', request, 'text/xml; charset=utf-8', request.length, { MessageType: "call", Host: this.Host, SOAPAction: this.Namespace + "GetManagedElements" });
    }
    this.LAD = function(onComplete, onError, type, mask, parentType, parentId) {
        var request = SH.LAD(type, mask, parentType, parentId);
        callMethod(this.MapWrapperURL, onComplete, onError, 'POST', request, 'text/xml; charset=utf-8', request.length, { MessageType: "call", Host: this.Host, SOAPAction: this.Namespace + "LoadAddresserData" });
    }
    this.PMP = function(responseXML) {
        var p = new MapParameters();
        p.tmId = responseXML.getElementsByTagName("ThematicMapId")[0].firstChild.nodeValue;
        p.x = responseXML.getElementsByTagName("X")[0].firstChild.nodeValue;
        p.y = responseXML.getElementsByTagName("Y")[0].firstChild.nodeValue;
        p.scale = responseXML.getElementsByTagName("Scale")[0].firstChild.nodeValue;
        p.width = responseXML.getElementsByTagName("Width")[0].firstChild.nodeValue;
        p.height = responseXML.getElementsByTagName("Height")[0].firstChild.nodeValue;
        p.drawScaleBar = responseXML.getElementsByTagName("DrawScaleBar")[0].firstChild.nodeValue;

        var sourceIdsXML = responseXML.getElementsByTagName('SourceId');
        p.sourceIds = new Array();
        for (var i = 0; i < sourceIdsXML.length; i++) {
            p.sourceIds[i] = sourceIdsXML[i].firstChild.nodeValue;
        }
        var objectIdsXML = responseXML.getElementsByTagName('ObjectId');
        p.objectIds = new Array();
        for (var j = 0; j < objectIdsXML.length; j++) {
            p.objectIds[j] = objectIdsXML[j].firstChild.nodeValue;
        }
        return p;
    }
    this.PMI = function(responseXML) {
        var maps = new Array;
        var mapsXML = responseXML.getElementsByTagName("MapIdentifier");
        for (var i = 0; i < mapsXML.length; i++) {
            var map = new MapIdentifier();
            map.id = mapsXML[i].childNodes[0].firstChild.nodeValue;
            map.name = mapsXML[i].childNodes[1].firstChild.nodeValue;
            map.description = mapsXML[i].childNodes[2].firstChild ? mapsXML[i].childNodes[2].firstChild.nodeValue : '';
            var tMapsXML = mapsXML[i].childNodes[3].childNodes;
            for (var j = 0; j < tMapsXML.length; j++) {
                var tMap = new TMapIdentifier();
                tMap.id = tMapsXML[j].childNodes[0].firstChild.nodeValue;
                tMap.name = tMapsXML[j].childNodes[1].firstChild.nodeValue;
                tMap.description = tMapsXML[j].childNodes[2].firstChild ? tMapsXML[j].childNodes[2].firstChild.nodeValue : '';
                map.tmapIds.push(tMap);
            }
            map.maxExtent.XMin = Number(mapsXML[i].childNodes[4].childNodes[0].firstChild.nodeValue);
            map.maxExtent.XMax = Number(mapsXML[i].childNodes[4].childNodes[2].firstChild.nodeValue);
            map.maxExtent.YMin = Number(mapsXML[i].childNodes[4].childNodes[1].firstChild.nodeValue);
            map.maxExtent.YMax = Number(mapsXML[i].childNodes[4].childNodes[3].firstChild.nodeValue);
            map.minScale = Number(mapsXML[i].childNodes[5].firstChild.nodeValue);
            map.maxScale = Number(mapsXML[i].childNodes[6].firstChild.nodeValue);
            var addresserInfoXML = mapsXML[i].childNodes[7];
            map.addresserInfo.classifierID = addresserInfoXML.childNodes[3].firstChild.nodeValue;
            map.addresserInfo.semanticID = addresserInfoXML.childNodes[4].firstChild.nodeValue;
            maps.push(map);
        }
        return maps;
    }
    this.PTT = function(responseXML) {
        var toolTipXML = responseXML.getElementsByTagName("GetTooltipResult")[0];
        if (toolTipXML.firstChild)
            return toolTipXML.firstChild.nodeValue;
        else
            return '';
    }
	this.PTT2 = function(responseXML) {
        var toolTipXML = responseXML.getElementsByTagName("GetTooltip2Result")[0];
        if (toolTipXML.firstChild)
            return toolTipXML.firstChild.nodeValue;
        else
            return '';
    }
    this.GMURL = function(mapWrapperURL, params, layers) {
        var map_x = String(params.x).replace('.', ',');
        var map_y = String(params.y).replace('.', ',');
        var ids = '';
        for (var i = 0; i < params.objectIds.length; i++) {
            ids += params.sourceIds[i] + ':' + params.objectIds[i] + ';';
        }
		//mapWrapperURL = 'http://gis-server/yarland/mapwrapper.asmx';
        var url = mapWrapperURL + '/GetRaster2InResponse?tmid=' + params.tmId + '&xc=' + map_x + '&yc=' + map_y + '&scale=' + params.scale + '&width=' + params.width + '&height=' + params.height + '&ids=' + ids + '&drawScaleBar=' + params.drawScaleBar;
		//return url = mapWrapperURL + '/GetRasterInResponse?tmid=' + params.tmId + '&xc=' + map_x + '&yc=' + map_y + '&scale=' + params.scale + '&width=' + params.width + '&height=' + params.height + '&ids=' + ids + '&drawScaleBar=' + params.drawScaleBar;
		var l = '';
		if(layers) {
			for (var i = 0; i < layers.length; i++) {
				l += layers[i] + ';';
			}
		}
		return url += ('&layers=' + l);
    }
	
	this.PME = function(responseXML, rootElem) {
        var elems = new Array;
		var elemsXML = responseXML;
		if(!rootElem) {
			elemsXML = responseXML.getElementsByTagName("GetManagedElementsResult");
			elemsXML = elemsXML[0].childNodes;
		}	
		if(!elemsXML)
			return elems;
        for (var i = 0; i < elemsXML.length; i++) {
            var elem = new ManagedElement();
            elem.code = elemsXML[i].childNodes[0].firstChild.nodeValue;
            elem.display = elemsXML[i].childNodes[1].firstChild.nodeValue;
			elem.legend = elemsXML[i].childNodes[2].firstChild.nodeValue;
			this.PME(elemsXML[i].childNodes[3].childNodes, elem);
            elems.push(elem);
        }
		if(rootElem)
			rootElem.childs = elems;
		else	
			return elems;
    }
	
    this.PAO = function(responseXML) {
        var items = new Array;
        var itemsXML = responseXML.getElementsByTagName("LoadedObject");
        for (var i = 0; i < itemsXML.length; i++) {
            var id = itemsXML[i].childNodes[0].firstChild.nodeValue;
            var name = itemsXML[i].childNodes[1].firstChild ? itemsXML[i].childNodes[1].firstChild.nodeValue : '';
            var item = new AddresserObject(id, name);
            items.push(item);
        }
        return items;
    }
}
