	var Map = Class.create();
	Map.prototype = {

        initialize: function(handle, img, height, width) {
        	this.data = {
        			navrect: null,
        			lastPict: ""
        		}
        	this.data.handle = handle;
        	this.setImage(img);
        	this.serviceURL = '/common/services/map.php';
			this.mapsUrl = 'http://maps.mapnet.pl/';
        },

		setOnStart: function(a) {
			this.doOnStart = a; },

		setOnFailure: function(a) {
			this.doOnFailure = a; },
		
		setOnComplete: function(a) {
			this.doOnComplete = a; },

        setImage: function(img) {
        	img = $(img);
        	this.img = img;
        	this.data.height = img.height;
        	this.data.width = img.width;
//        	dO(this.data);
        },
        
        clearImage: function() {
        	this.img.src = '/common/imgs/pixel.gif';
        },
        

        serializeData: function(index) {
        	var s = "";
        	if (!index) index = 0;
			for (var p in this.data) {
				try {
					if (typeof(this.data[p])=="function") continue;
					if (typeof(this.data[p])=="array") {
						var ar = data[p];
						for (var i in ar) {
							s += "operations["+ index + "][data][" + i + "][]=" + encodeURIComponent(ar[p]+"") + "&";
						}
						continue;
					}
					s += "operations["+ index + "][data][" + p + "]=" + encodeURIComponent(this.data[p]+"") + "&";
				} catch (e) {
					d('Exception!\n'+e);
				}
			}
			return s;
        },
        
        serializeArgs: function(index) {
        	var s = "";
        	if (!index) index = 0;
        	ar = this.args;
        	ar.handle = this.data.handle;
        	ar.height = this.data.height;
        	ar.width = this.data.width;
			for (var p in ar) {
				try {
					if (typeof(ar[p])=="function") continue;
					if (typeof(ar[p])=="array") {
						var ar = ar[p];
						for (var i in ar) {
							s += "operations["+ index + "][args][" + i + "][]=" + encodeURIComponent(ar[p]+"") + "&";
						}
						continue;
					}
					s += "operations["+ index + "][args][" + p + "]=" + encodeURIComponent(ar[p]+"") + "&";
				} catch (e) {
					d('Exception!\n'+e);
				}
			}
			return s;
        },

        _getDebugData: function(func) {
			if (this.doOnStart)
				this.doOnStart(this);
			var s = this.serializeArgs(0);
			s = 'operations[0][function]='+func+'&' + s;
			new Ajax.Request(this.serviceURL, {
				onFailure: function(a, b) {
					if (b.options.map.doOnFailure) b.options.map.doOnFailure(b.options.map, 'AJAX failed');
				},
				onComplete: function(a, b) 
				{
					var temp = a.responseText;
					d(temp);
					if (b.options.map.doOnComplete)	b.options.map.doOnComplete(b.options.map);
				},
				method: 'get', asynchronous: true, 
				parameters: s, map: this
			});
        },
        
        getXY: function(x, y) {
        	this.args = new Array();
        	this.args.x = x;
        	this.args.y = y;
        	this._getDebugData('getxy');
        },
        
        _getListOfObjects: function(func, onDone) {
			if (this.doOnStart)
				this.doOnStart(this);
			var s = this.serializeArgs(0);
			s = 'operations[0][function]='+func+'&' + s;
			
			new Ajax.Request(this.serviceURL, {
				onFailure: function(a, b) {
					if (b.options.map.doOnFailure) b.options.map.doOnFailure(b.options.map, 'AJAX failed'); },
				onComplete: function(a, b) {
					var temp = a.responseText;
					if (temp.indexOf('Error')!=-1)
						d(temp);

					var map = b.options.map;
					var list = a.responseXML.childNodes[0].getElementsByTagName('OPERATION');

					var er = getXMLValue(list[0], 'ERROR');
					if (er != '') {
						if (b.options.map.doOnFailure) 
							b.options.map.doOnFailure(b.options.map, er);
					} else {
						
						var lays = getArrayOfNodes(list[0], 'LAYERS', 'LAYER');
						
						var res = new Array();
						for (var i = 0; i<lays.length; i++) {
							var layername = getXMLValue(lays[i], 'NAME');
							var objs = getArrayOfValues(lays[i], 'OBJECTS', 'OBJECT');
							res.push([layername, objs]);
						}

						if (map.doOnComplete)	map.doOnComplete(map);
						if (b.options.doOnDone) b.options.doOnDone(map, res, map.args.street, map.args.bn);
					}
				},
				method: 'get', asynchronous: true, 
				parameters: s, map: this,
				doOnDone: onDone
			});
        },
        
        getObjects: function(city, street, bn, onDone) {
        	this.args = new Array();
        	this.args.city = city;
        	this.args.street = street;
        	this.args.bn = bn;
        	this._getListOfObjects('getcities', onDone);
        },
        
        getClickObjects: function(x, y, onDone) {
        	this.args = new Array();
        	this.args.x = x;
        	this.args.y = y;
        	this.args.lng = 'pl';
        	this._getListOfObjects('infoClick', onDone);
        },

        getClickObjectsLng: function(x, y, lng, onDone) {
            this.args = new Array();
            this.args.x = x;
            this.args.y = y;
	    this.args.lng = lng == 'en' ? 'en' : 'pl';
            this._getListOfObjects('infoClick', onDone);
        },
        
        getNearestKSU: function(city, comm, dist, prov, street, bn, onDone) {
        	this.args = new Array();
        	this.args.city = city;
        	this.args.comm = comm;
        	this.args.dist = dist;
        	this.args.prov = prov;
        	this.args.street = street;
        	this.args.bn = bn;
        	this._getListOfObjects('getnearestksu', onDone);
        },
        
        _getNewImage: function(func, onDone) {
			if (this.doOnStart)
				this.doOnStart(this);
			var s = this.serializeArgs(0);
			s = 'operations[0][function]='+func+'&' + s;
			new Ajax.Request(this.serviceURL, {
				onFailure: function(a, b) {
					if (b.options.map.doOnFailure) b.options.map.doOnFailure(b.options.map, 'AJAX failed');
				},
				onComplete: function(a, b) 
				{
//					dO(a);
					var temp = a.responseText;
//					d(temp);
//					if (temp.indexOf('Error')!=-1)
// 						d(temp);

					var map = b.options.map;

					var er = getXMLValue(a.responseXML.childNodes[0], 'ERROR');
//					d
					if (er != '') {
//						d(er);
						if (b.options.map.doOnFailure) 
							b.options.map.doOnFailure(b.options.map, er);
						return;
					}

					var list = a.responseXML.childNodes[0].getElementsByTagName('OPERATION');

					var er = getXMLValue(list[0], 'ERROR');
					if (er != '') {
						if (b.options.map.doOnFailure) 
							b.options.map.doOnFailure(b.options.map, er);
					} else {
						var rect = list[0].getElementsByTagName('NAVRECT')[0];
						map.data.navrect = new Array();
						map.data.navrect['x1'] = getXMLValue(rect, 'X1');
						map.data.navrect['x2'] = getXMLValue(rect, 'X2');
						map.data.navrect['y1'] = getXMLValue(rect, 'Y1');
						map.data.navrect['y2'] = getXMLValue(rect, 'Y2');
					
						var k = getXMLValue(list[0], 'SRC');
						map.img.src = map.mapsUrl+k;
						map.data.lastPict = k;
						if (map.doOnComplete)	map.doOnComplete(map);
						if (b.options.doOnDone)	b.options.doOnDone(map);
					}
				},
				method: 'get', asynchronous: true, 
				parameters: s, map: this,
				doOnDone: onDone
			});
        },
        
        navigate: function(dx, dy, onDone) {
        	if (dx==0 && dy==0)
        		return;
        	this.args = new Array();
        	this.args.dx = dx;
        	this.args.dy = dy;
        	this._getNewImage('navigate', onDone);
        },

        showRect: function(onDone) {
        	this.args = new Array();
        	this.args.dx = 0;
        	this.args.dy = 0;
        	this._getNewImage('navigate', onDone);
        },

        scale: function(delta, onDone) {
        	this.args = new Array();
        	this.args.delta = delta;
        	this.args.relative = 1;
        	this._getNewImage('scale', onDone);
        },
        
        setScale: function(scale, onDone) {
        	this.args = new Array();
        	this.args.delta = scale;
        	this.args.relative = 0;
        	this._getNewImage('scale', onDone);
        },

		showObjectScale: function(id, scale, onDone) {
        	this.args = new Array();
        	this.args.objectid = id;
        	this.args.scale = scale;
			this._getNewImage('showObjectScale', onDone);
        },
        
        showPoint: function(str, bn, onDone) {
        	this.args = new Array();
        	this.args.street = str;
        	this.args.bn = bn;
			this._getNewImage('showpoint', onDone);
		},
		
		showObject: function(id, onDone) {
        	this.args = new Array();
        	this.args.objectid = id;
        	this.args.scale = this.data.startscale;
        	delete this.data.startscale;
//        	dO(this.data);
			this._getNewImage('showobject', onDone);
		},
		showStreet: function(city, street, exact, onDone, showAll) {
        	this.args = new Array();
        	this.args.city = city;
        	this.args.street = street;
        	this.args.exact = exact;
        	this.args.showAll = showAll?'true':'false';
			this._getNewImage('showStreet', onDone);
		},
		
		centerOn: function(objectid, onDone) {
        	this.args = new Array();
        	this.args.objectid = objectid;
			this._getNewImage('centeron', onDone);
		},

		routeCenterOn: function(terminus, onDone) {
        	this.args = new Array();
        	this.args.terminus = terminus;
			this._getNewImage('routecenteron', onDone);
		},

		
        _getNewRouteImage: function(func, onDone, rev) {
			if (this.doOnStart)
				this.doOnStart(this);
			var s = this.serializeArgs(0);
			s = 'operations[0][function]=addobject&' + s + '&';
			this.args = new Array();
			if (rev != true) {
				this.args.route_origin = -1;
				this.args.route_destination = 0;
			} else {
				this.args.route_origin = 0;
				this.args.route_destination = -1;
			}
			s += this.serializeArgs(1);
			s += 'operations[1][function]='+func+'&' + s;
			new Ajax.Request(this.serviceURL, {
				onFailure: function(a, b) {d('Failed'); },
				onComplete: function(a, b) 
				{
					var temp = a.responseText;
					//d(temp);
					if (temp.indexOf('Fatal error')!=-1) {
						d(temp);
						return;
					}

					var map = b.options.map;
					var list = a.responseXML.childNodes[0].getElementsByTagName('OPERATION');
					for (var i = 0; i<list.length; i++) {
						var er = getXMLValue(list[i], 'ERROR');
						if (er != '') {
							if (b.options.map.doOnFailure) {
								b.options.map.doOnFailure(b.options.map, er);
							}
							return;
						}
					} 

					map.routeDone = true;
					
					var rect = list[1].getElementsByTagName('NAVRECT')[0];
					map.data.navrect = new Array();
					map.data.navrect['x1'] = getXMLValue(rect, 'X1');
					map.data.navrect['x2'] = getXMLValue(rect, 'X2');
					map.data.navrect['y1'] = getXMLValue(rect, 'Y1');
					map.data.navrect['y2'] = getXMLValue(rect, 'Y2');


					var k = getXMLValue(list[1], 'SRC');
					map.img.src = map.mapsUrl+k;
					map.data.lastPict = k;

					k = getXMLValue(list[1], 'TEXT');

					if (map.doOnComplete)	map.doOnComplete(map);
					if (b.options.doOnDone)	b.options.doOnDone(map, k);
					
				},
				method: 'get', asynchronous: true, 
				parameters: s, map: this,
				doOnDone: onDone
			});
        },
        
        getRoute: function(street, number, onDone, city) {
			this.args = new Array();
        	this.args.object_id = 'origin';
        	this.args.object_type = 'ADDRESS';
        	this.args.object_icon = 'GreenSphere.ico';
        	this.args.object_street = street;
        	this.args.object_number = number;
			if (city) this.args.object_city = city;
        	this._getNewRouteImage('getroute', onDone, false);
        },

        getRevRoute: function(street, number, onDone, city) {
			this.args = new Array();
        	this.args.object_id = 'origin';
        	this.args.object_type = 'ADDRESS';
        	this.args.object_icon = 'RedSphere.ico';
        	this.args.object_street = street;
        	this.args.object_number = number;
		if (city) this.args.object_city = city;
        	this._getNewRouteImage('getroute', onDone, true);
        },

        getPlaceRoute: function(id, onDone) {
			this.args = new Array();
        	this.args.object_id = 'origin';
        	this.args.object_type = 'TABLE';
        	this.args.object_icon = 'GreenSphere.ico';
        	this.args.object_table = 's_dojazd_places';
        	this.args.object_field = 'id';
        	this.args.object_value = id;
        	this._getNewRouteImage('getroute', onDone, false);
        },
		
        getPlaceRevRoute: function(id, onDone) {
			this.args = new Array();
        	this.args.object_id = 'origin';
        	this.args.object_type = 'TABLE';
        	this.args.object_icon = 'RedSphere.ico';
        	this.args.object_table = 's_dojazd_places';
        	this.args.object_field = 'id';
        	this.args.object_value = id;
        	this._getNewRouteImage('getroute', onDone, true);
        },
		
        load: function() {
        	
        },
        
        save: function(onDone) {
			var s = this.serialize();
			s = 'function=save&' + s;
			new Ajax.Request('/common/services/map/', {
				onFailure: function(a, b) { d('Failed'); },
				onComplete: function(a, b) {
					var er = getXMLValue(a, 'ERROR');
					if (er != '') d(er);
					else if (b.options.doOnDone)
							b.options.doOnDone();
				},
				method: 'get', asynchronous: true, 
				parameters: s,
				doOnDone: onDone
			});
		}	
		
		
	};

