﻿var ZoomPlusMode = "ZoomPlusMode";
var ZoomMinusMode = "ZoomMinusMode";
var ZoomPlusWheelMode = "ZoomPlusWheelMode";
var ZoomMinusWheelMode = "ZoomMinusWheelMode";
var ZoomNoClearMode = "ZoomNoClearMode";
var ZoomNoneMode = "ZoomNoneMode";
var ZoomPlusFactor = 0.09;
var ZoomMinusFactor = 0.09;

//var ZoomPlusSim = 25;
//var ZoomMinusSim = 25;


var MapMinScrollX = -7550;
var MapMaxScrollX =  9200;
var MapMinScrollY = -9750;
var MapMaxScrollY =  9000;
var DefaultMapWidth = 512;
var DefaultMapHeight = 512;
var MIN_ZOOM_LEVEL = 5;
var MAX_ZOOM_LEVEL = kWinToMap["length"] - 1;
var NAVRECT_TO_NAVCROSS_ZOOM = 9;
var MOVE_OFFSET = 45;
var PRELOAD_OFFSET = 30;
var ALERT_MAP_CONTROLS_NOT_FOUND = "Ошибка! Блок для вывода карты не найден!";
var TileAltName = "Карта";
var TileAltName2 = "Загрузка...";
var CursorOpenHand = mapSourcePath + "cursor/openhand.cur";
var MapControlStyle = "position:absolute; overflow:hidden; z-index:0; cursor:default;z-index:3;-moz-user-select: none; user-select: none;";
var TilesContainerStyle = "position:absolute; z-index:1;";
var TilesContainerStyle2 = "position:absolute; z-index:0;";
var MarkerLayerStyle = "position:absolute; z-index:3;";
var MarkerTitleStyle = "position:absolute; top:-17px; left:5px; border:solid 1px black; background-color:#FFFFAA; font-size:10pt; white-space: nowrap;";
var LineLayerStyle = "position:absolute; left:0px; top:0px; z-index:2; visibility:visible;";
var TileStyle = "position:absolute; overflow:hidden; margin:0px 0px 0px 0px; padding:0px 0px 0px 0px; border-style:none; z-index:1;";
var TileStyle2 = "position:absolute; overflow:hidden; margin:0px 0px 0px 0px; padding:0px 0px 0px 0px; border-style:none; z-index:0;";
var ToolControlsStyle = "position:absolute; cursor:pointer; left:40px; top:5px; width:25px; height:25px;  z-index:3;-moz-user-select: none; user-select: none;";
var ControlsStyle = "position:absolute; cursor:pointer; left:0px; top:35px; width:60px; height:100px;  z-index:3;";
var NavigatorStyle = "position:absolute; cursor:pointer; overflow:hidden; right:10px; top:10px; width:100px; height:112px;  z-index:3;";
var NavigatorMapPath = mapSourcePath + "image/navigator_map.png";
var NavigatorMapAltName = "Навигатор";
var NavigatorCrossStyle = "position:absolute; left:0px; top:0px; width:10px; height:10px; z-index:3;";
var NavigatorCrossPath = mapSourcePath + "image/navigator_cross.gif";
var NavigatorRectStyle = "position:absolute; left:0px; top:0px; width:0px; height:0px; min-height:0px; font-size:1px; line-height:0; z-index:3; border:2px solid black;";
var UpArrowImagePath = mapSourcePath + "image/up_arrow.png";
var UpArrowAltName = "Вверх";
var UpArrowStyle = "cursor:pointer; left:40px; top:10px; width:16px; height:16px; position:absolute; z-index:1;";
var DownArrowImagePath = mapSourcePath + "image/down_arrow.png";
var DownArrowAltName = "Вниз";
var DownArrowStyle = "cursor:pointer; left:40px; top:42px; width:16px; height:16px; position:absolute; z-index:2;";
var LeftArrowImagePath = mapSourcePath + "image/left_arrow.png";
var LeftArrowAltName = "Влево";
var LeftArrowStyle = "cursor:pointer; left:24px; top:26px; width:16px; height:16px; position:absolute; z-index:3;";
var RightArrowImagePath = mapSourcePath + "image/right_arrow.png";
var RightArrowAltName = "Вправо";
var RightArrowStyle = "cursor:pointer; left:56px; top:26px; width:16px; height:16px; position:absolute; z-index:4;";
var ZoomPlusImagePath = mapSourcePath + "image/zoom_plus.png";
var ZoomPlusAltName = "Увеличить масштаб";
var ZoomPlusStyle = "cursor:pointer; left:40px; top:60px; width:16px; height:16px; position:absolute; z-index:5;";
var ZoomMinusImagePath = mapSourcePath + "image/zoom_minus.png";
var ZoomMinusAltName = "Уменьшить масштаб";
var ZoomMinusStyle = "cursor:pointer; left:40px; top:240px; width:16px; height:16px; position:absolute; z-index:6;";
var ZoomLineImagePath = mapSourcePath + "image/zoom_line.gif";
var ZoomLineStyle = "cursor:pointer; left:40px; top:78px; width:17px; height:161px; position:absolute; z-index:6;";
var ZoomLineBlockImagePath = mapSourcePath + "image/zoom_block.gif";
var ZoomLineBlockStyle = "left:0px; top:0px; width:17px; height:9px; position:absolute; z-index:7;-moz-user-select:none;";
var CanvasStyle = "position: absolute;top:0px;left:0px; background-color: Transparent;-moz-user-select:none; width:100%; height:100%; z-index:2";

var NoneToolImagePath = mapSourcePath + "image/hand.png";
var NoneToolActiveImagePath = mapSourcePath + "image/activehand.png";
var NoneToolAltName = "Перемещение";
var NoneToolStyle = "cursor:pointer; left:0px; top:0px; width:25px; height:25px; position:absolute; z-index:5;";

var InfoAltName = "Условные обозначения";
var InfoImagePath = mapSourcePath + "image/info.png";
var InfoStyle = "cursor:pointer; left:100px; top:0px; width:25px; height:25px; position:absolute; z-index:5;"; 

var RouteImagePath = mapSourcePath + "image/route.png";
var AltRouteImagePath = mapSourcePath + "image/altroute.png";
var RouteAltName = "Маршрут";
var RouteStyle = "cursor:pointer; left:60px; top:0px; width:25px; height:25px; position:absolute; z-index:5;";
var RouteStartImagePath = mapSourcePath + "image/route_start.png";
var RouteFinishImagePath = mapSourcePath + "image/route_finish.png";
var RouteByTimeAltName = "По времени";
var RouteByLengthAltName = "По расстоянию";
var MapFooterText = "<p align='right'> <a href='http://kissa.pro' style='color: blue;'>КИССа Иваново</a>, <a href='http://www.ivanovomap.ru'style='color: blue;'>www.ivanovomap.ru</a>, <a href='http://www.neogis.ru/'style='color: blue;'>ООО НеоГИС</a>, © 2012</p>";
var MapFooterStyle = "right:20px; bottom:5px; position:absolute; z-index:6;-moz-user-select: none; user-select: none;";

var MapLogoText = "<p align='left'><a href='http://kissa.pro'><img src='" + mapSourcePath + "image/kissa.png' style='border:0px'></img></a></p>";
var MapLogoStyle = "left:2px; bottom:2px; position:absolute; z-index:6;-moz-user-select: none; user-select: none;";

var RouteByTimeImagePath = mapSourcePath + "image/route_bytime.png";
var RouteByLengthImagePath = mapSourcePath + "image/route_bylength.png";
var RouteByTimeActiveImagePath = mapSourcePath + "image/route_bytime_active.png";
var RouteByLengthActiveImagePath = mapSourcePath + "image/route_bylength_active.png";

var RouteFinishImagePath = mapSourcePath + "image/route_finish.png";

var RouteLineWidth = 5;
var RouteLineColor = "#ff0000"; //red
//var routeUrl = "http://localhost:1752/maps/handler/RouteHandler.ashx";
var ScaleImagePath = mapSourcePath + "image/ruler.png";
var AltScaleImagePath = mapSourcePath + "image/activeruler.png";
var ScaleAltName = "Линейка";
var ScaleStyle = "cursor:pointer; left:30px; top:0px; width:25px; height:25px; position:absolute; z-index:5;";
var NULL_GIF_LINK = mapSourcePath + "image/null.gif";
var DEFAULT_MARKER_IMG = mapSourcePath + "image/marker_user.png";
var DEFAULT_MARKER_SHIFT_X = 6;
var DEFAULT_MARKER_SHIFT_Y = 2;
var DEFAULT_MARKER_DESC = "Маркер";
var HOUSE_MARKER_IMG = mapSourcePath + "image/g_marker.png";
var LINE_MARKER_IMG = mapSourcePath + "image/m_marker.gif";
var LINE_MARKER_SHIFT_X = 6;
var LINE_MARKER_SHIFT_Y = 1;
//Функция возвращает true если текущий бразуер Internet explorer
function IE() { return '\v' == 'v'; };

function RenderLine(x1, y1, x2, y2, weight, color) {
    return "\x3Cv:line from=\x27" + x1 + "," + y1 + "\x27 to=\x27" + x2 + "," + y2 + "\x27\x3E\x3Cv:stroke Weight=\x27" + weight + "\x27 Color=\x27" + color + "\x27 /\x3E\x3C/v:line\x3E";
};
function GetDeltaToCenter(pMap) {
    var dtx = Math["floor"](pMap.GetWidth() / 2);
    var dty = Math["floor"](pMap.GetHeight() / 2);
    while (dtx > 0) {
        dtx -= tileWidth;
    };
    while (dty > 0) {
        dty -= tileHeight;
    };
    var obj = new Object();
    obj["dtx"] = dtx;
    obj["dty"] = dty;
    return obj;
};
function mousePageXY(e) {
    var x = 0, y = 0;
    if (!e) {
        e = window["event"];
    };
    if (e["pageX"] || e["pageY"]) {
        x = e["pageX"];
        y = e["pageY"];
    }
    else {
        if (e["clientX"] || e["clientY"]) {
            x = e["clientX"] + (document["documentElement"]["scrollLeft"] || document["body"]["scrollLeft"]) - document["documentElement"]["clientLeft"];
            y = e["clientY"] + (document["documentElement"]["scrollTop"] || document["body"]["scrollTop"]) - document["documentElement"]["clientTop"];
        };
    };
    return { "x": x, "y": y };
};
function getAbsolutePos(el) {
    var r = { x: el["offsetLeft"], y: el["offsetTop"] };
    if (el["offsetParent"]) {
        var tmp = getAbsolutePos(el["offsetParent"]);
        r["x"] += tmp["x"];
        r["y"] += tmp["y"];
    };
    return r;
};

function CheckAllLoaded(map) {
    map._loadedTilesCount++;
    //if (map._loadedTilesCount == 1)
    //    map._tilesContainer2.style.display = "none";
    var totalTiles = map._tileCountX * map._tileCountY;
    if (map._loadedTilesCount >= totalTiles && map._zoomAnimationsCount==0) {       
        //if (!map._zoomAnimationInProgress)
        //map._BuildBackImages();//
        
        //SetBackTilesPosition(map);
        //SetBackTilesSrc(map);
        SetBackTilesPositionAndSrc(map);

        map.HideBackTiles(); //map._tilesContainer2.style.display = "none";
        map._tilesWasLoaded = true; 
        //map._loadedTilesCount = 0;
    }


};

function SetBackTilesPositionAndSrc(map) {
    for (var i = 1; i <= map._tileCountY; i++) {
        for (var j = 1; j <= map._tileCountX; j++) {
            var image = map._tileArray[i][j];
            var backImage = map._tileArray2[i][j];
            backImage.width = image.width;
            backImage.height = image.height;
            backImage.style.left = image.style.left;
            backImage.style.top = image.style.top;
            backImage.src = image.src;   
        }
    }
};

function SetBackTilesPosition(map) {
    for (i = 1; i <= map._tileCountY; i++) {
        for (j = 1; j <= map._tileCountX; j++) {
            var image = map._tileArray[i][j];
            var backImage = map._tileArray2[i][j];
            backImage.width = image.width;
            backImage.height = image.height;
            backImage.style.left = image.style.left;
            backImage.style.top = image.style.top;
        }
    }
};

function HideBackTiles(map) {
    for (i = 1; i <= map._tileCountY; i++)
        for (j = 1; j <= map._tileCountX; j++) {
        var image = map._tileArray[i][j];
        var backImage = map._tileArray2[i][j];
        //backImage.style.visibility = "hidden";
    }
};


function SetBackTilesSrc(map) {
    for (i = 1; i <= map._tileCountY; i++)
        for (j = 1; j <= map._tileCountX; j++) {
        var image = map._tileArray[i][j];
        var backImage = map._tileArray2[i][j];
        backImage.src = image.src;
        //backImage.style.visibility = "visisble";
        
    }
};

function SetBackTiles(map) {
    while (this["_tilesContainer2"]["childNodes"]["length"] > 0) {
        this["_tilesContainer2"]["removeChild"](this["_tilesContainer2"]["firstChild"]);
    };
    for (i = 1; i <= map._tileCountY; i++) {
        this["_tileArray2"][i] = new Array();
        for (j = 1; j <= map._tileCountX; j++) {
            var image = map._tileArray[i][j];
            this["_tileArray2"][i][j] = document["createElement"]("IMG");
            var backImage = map._tileArray2[i][j];
            with (backImage) {
                width = tileWidth;
                height = tileHeight;
                alt = TileAltName2;
                onmousedown = function() {
                    return false;
                };
                onmousemove = function() {
                    return false;
                };
                onmouseup = function() {
                    return false;
                };
                onlclick = function() {
                    return false;
                };
                ondblclick = function() {
                    return false;
                };
            };
            backImage.galleryImg = "no";
             backImage.unselectable = "on";
            backImage.style.cssText = TileStyle2;
            backImage.width = image.width;
            backImage.height = image.height;
            backImage.style.left = image.style.left;
            backImage.style.top = image.style.top;
            backImage.src = image.src;
        }
    }
};

this["_BuildBackImages"] = function() {
    while (this["_tilesContainer2"]["childNodes"]["length"] > 0) {
        this["_tilesContainer2"]["removeChild"](this["_tilesContainer2"]["firstChild"]);
    };

    for (i = 1; i <= this["_tileCountY"]; i++) {
        this["_tileArray2"][i] = new Array(); //
        for (j = 1; j <= this["_tileCountX"]; j++) {
            //---------------------------------------------------------------------
            this["_tileArray2"][i][j] = document["createElement"]("IMG");
            with (this["_tileArray2"][i][j]) {
                width = tileWidth;
                height = tileHeight;
                alt = TileAltName2;
                onmousedown = function() {
                    return false;
                };
                onmousemove = function() {
                    return false;
                };
                onmouseup = function() {
                    return false;
                };
                onlclick = function() {
                    return false;
                };
                ondblclick = function() {
                    return false;
                };
            };
            this["_tileArray2"][i][j]["galleryImg"] = "no";
            this["_tileArray2"][i][j]["unselectable"] = "on";
            this["_tileArray2"][i][j]["style"]["cssText"] = TileStyle2;
            var obj = GetDeltaToCenter(this);
            dtx = obj["dtx"];
            dty = obj["dty"];
            this._tileArray2[i][j].style.left = (j - 1) * tileWidth + dtx + "px";
            this._tileArray2[i][j].style.top = (i - 1) * tileHeight + dty + "px";

            this._tileArray2[i][j].width = tileWidth + "px";
            this._tileArray2[i][j].height = tileHeight + "px";
            this._tilesContainer2.appendChild(this._tileArray2[i][j]);

            //----------------------------
        };
    };

};

function SetDelayedImage(tileImg, x, y, z,tileImg2, zoomMode, map) {
  //  if (tileImg2) {
//        if (zoomMode) {
//            if (zoomMode == ZoomPlusMode || zoomMode == ZoomPlusWheelMode) {
//                tileImg2.src = tileImg.src;
//            }
//            else
//                if (zoomMode == ZoomMinusMode || zoomMode == ZoomMinusWheelMode) {
//                tileImg2.src = tileImg.src;
//            }

//        }
//        else {
//            tileImg2.src = "";
//        }
 //   }

  //  if (map._zoomAnimationsCount > 0)
   //    return; 
   tileImg["style"]["visibility"] = "hidden";
    tileImg["onload"] = function() {
        this["style"]["visibility"] = "visible";
        //if(!IE())
        if (map)
            CheckAllLoaded(map);

    };
    tileImg["src"] = getTileURL(x, y, z);  //+ "?dummy="+Math.random;
	
	
	
	
};
function Marker(map, index, x, y, source, description, isDraggable, showTitle, shiftX, shiftY) {
    this["_map"] = map;
    this["_isDraggable"] = isDraggable ? isDraggable : false;
    this["_showTitle"] = showTitle ? showTitle : false;
    this["_index"] = index;
    this["GetIndex"] = function() {
        return this["_index"];
    };
    this["_div"] = undefined;
    this["_imgsrc"] = source ? source : DEFAULT_MARKER_IMG;
    this["_shiftX"] = shiftX ? shiftX : DEFAULT_MARKER_SHIFT_X;
    this["_shiftY"] = shiftY ? shiftY : DEFAULT_MARKER_SHIFT_Y;
    this["_img"] = undefined;
    this["isVisible"] = false;
    this["_x"] = x;
    this["_y"] = y;
    this["_description"] = description ? description : DEFAULT_MARKER_DESC;
    this["SetDescription"] = function(description) {
        this["_description"] = description;
        this["_title"]["innerHTML"] = description;
        this["_title"]["style"]["left"] = 10+"px";
    };
    this["LoadMarker"] = function() {
        this["_div"] = document["createElement"]("DIV");
        this["_map"].AddChild(this._div);
        this["_img"] = document["createElement"]("IMG");
        with (this["_img"]) {
            alt = this["_description"];
            if (IE()) {
                src = NULL_GIF_LINK;
                style["filter"] = "progid:DXImageTransform.Microsoft.AlphaImageLoader(src=\x27" + this["_imgsrc"] + "\x27)";
            } else {
                src = this["_imgsrc"];
            };
            onmousedown = function(e) {
                return false;
            };
            onmousemove = function(e) {
                return false;
            };
        };
        this["_div"]["appendChild"](this._img);
        with (this["_div"]) {
            style["zIndex"] = 2;
            style["position"] = "absolute";
            style["left"] = (this["_map"].GetWidth() / 2) + (this["_x"] - this["_map"].GetMapCenter()["x"]) / kWinToMap[this["_map"].GetZoom()] - this["_shiftX"] + "px";
            style["top"] = (this["_map"].GetHeight() / 2) - (this["_y"] - this["_map"].GetMapCenter()["y"]) / kWinToMap[this["_map"].GetZoom()] - parseInt(clientHeight) + this["_shiftY"]+"px";
        };
        this["_div"]["_owner"] = this;
        this["_div"]["_onmousedown"] = function(e) {
            this._StartDrag(e);
        };
        this["_div"]["onmousedown"] = function(e) {
            var event = window["event"] || e;
            this["_onmousedown"]["call"](this._owner, e);
            event["cancelBubble"] = true;
        };
        this["_div"]["_onmousemove"] = function(e) {
            this._Drag(e);
            var event = window["event"] || e;
            event["cancelBubble"] = true;
        };
        this["_div"]["onmousemove"] = function(e) {
            var event = window["event"] || e;
            this["_onmousemove"]["call"](this._owner, e);
            event["cancelBubble"] = true;
        };
        this["_div"]["_onmouseup"] = function(e) {
            this._EndDrag(e);
        };
        this["_div"]["onmouseup"] = function(e) {
            var event = window["event"] || e;
            this["_onmouseup"]["call"](this._owner, e);
            event["cancelBubble"] = true;
        };
        if (this["_showTitle"]) {
            this["_title"] = document["createElement"]("DIV");
            this["_title"]["style"]["cssText"] = MarkerTitleStyle;
            this["_title"]["visibility"] = showTitle ? "visible" : "hidden";
            this["_title"]["innerHTML"] = this["_description"];
            this["_title"]["onmousedown"] = function(e) {
                return false;
            }
            this["_title"]["onmousemove"] = function(e) {
                return false;
            }
            this["_div"]["appendChild"](this._title);
        };
        this["isVisible"] = true;
    };
    this["UnloadMarker"] = function() {
        this["_map"].RemoveChild(this._div);
        this["isVisible"] = false;
    };
    this["_left"] = 0;
    this["_top"] = 0;
    this["SetMarkerFixPoint"] = function() {
        this["_left"] = parseInt(this["_div"]["style"]["left"]);
        this["_top"] = parseInt(this["_div"]["style"]["top"]) ;
    };
    this["MoveMarkerFromFixPoint"] = function(dx, dy) {
    this["_div"]["style"]["left"] = this["_left"] + parseInt(dx) + "px";
        this["_div"]["style"]["top"] = this["_top"] + parseInt(dy)+ "px";
    };
    this["_isDragging"] = false;
    this["_startPosX"] = 0;
    this["_startPosY"] = 0;
    this["_fixX"] = 0;
    this["_fixY"] = 0;
    this["_StartDrag"] = function(e) {
        if ((this["_isDragging"] == false) && (this["_isDraggable"])) {
            this["_isDragging"] = true;
            this.SetMarkerFixPoint();
            var mousePos = mousePageXY(e);
            this["_startPosX"] = mousePos["x"];
            this["_startPosY"] = mousePos["y"];
            this["_fixX"] = this["_x"];
            this["_fixY"] = this["_y"];
        };
    };
    this["onDrag"] = function(e) {
        return true;
    };
    this["_Drag"] = function(e) {
        if ((this["_isDragging"]) && (this["_isDraggable"])) {
            var mousePos = mousePageXY(e);
            var dx = mousePos["x"] - this["_startPosX"];
            var dy = mousePos["y"] - this["_startPosY"];
            this.MoveMarkerFromFixPoint(dx, dy);
            this["_x"] = this["_fixX"] + dx * kWinToMap[this["_map"].GetZoom()];
            this["_y"] = this["_fixY"] - dy * kWinToMap[this["_map"].GetZoom()];
            this["onDrag"]["call"](this._map, this._index);
        };
    };
    this["onEndDrag"] = function(e) {
        return true;
    };
    this["_EndDrag"] = function(e) {
        if ((this["_isDragging"]) && (this["_isDraggable"])) {
            this["_isDragging"] = false;
            var mousePos = mousePageXY(e);
            var dx = mousePos["x"] - this["_startPosX"];
            var dy = mousePos["y"] - this["_startPosY"];
            this["onEndDrag"]["call"](this._map, this._index);
        };
    };
    this["UpdateMarker"] = function() {
        if (!this["isVisible"]) {
            this.LoadMarker();
            this["isVisible"] = true;
        } else {
            with (this["_div"]) {
                style["left"] = (this["_map"].GetWidth() / 2) + (this["_x"] - this["_map"].GetMapCenter()["x"]) / kWinToMap[this["_map"].GetZoom()] - this["_shiftX"] + "px";
                style["top"] = (this["_map"].GetHeight() / 2) - (this["_y"] - this["_map"].GetMapCenter()["y"]) / kWinToMap[this["_map"].GetZoom()] - parseInt(clientHeight) + this["_shiftY"]+ "px";
            };
        };
    };
};
function Map(mapControl, routesControl) {
      this["_mapControl"] = mapControl;
      this["_canvas"] = routesControl; //document.getElementById("routes");
       
      //var routes = document.getElementById("routes");
      //routes.style.moz-user-select="none";
     //this["_canvas"]["style"]["user-select"] = "none";
      //this.preventSelection(_canvas);
      

//      this["_canvas"]["_owner"] = this["_mapControl"];
//      this["_canvas"]["ondblclick"] = function(e) {
//          var event = window["event"] || e;
//          //event["cancelBubble"] = true;
//          this["_owner"]["ondblclick"]["call"](this._owner, event);
//          return false;
//      };
//      this["_canvas"]["onclick"] = function(e) {
//          var event = window["event"] || e;
//           //event["cancelBubble"] = true;
//          this["_owner"]["onclick"]["call"](this._owner, event);
//          return false;
//      };
//      this["_canvas"]["onselectstart"] = function(e) {
//          return false;
//      };

      if (!this["_canvas"]) {
          this._canvas = document["createElement"]("DIV");
          this._canvas.id = "routes";
          this._canvas.style.cssText = CanvasStyle;
          this._mapControl.appendChild(this._canvas);
      }
      if (this["_canvas"]) {
          this["_jg"] = new jsGraphics(this._canvas.id); //new jsGraphics("routes");
          this["_jg"].setColor(RouteLineColor);
          this["_jg"].setStroke(RouteLineWidth);
      }
     
    if (this["_mapControl"] != null) {
        this["_mapControl"]["style"]["position"] = "relative";
        this["_mapControl"]["style"]["overflow"] = "hidden";
        this["_mapControl"]["style"]["border"] = "solid 1px black";
        this["_mapControl"]["style"]["backgroundColor"] = "#DDDDDD";
        this["_mapControl"]["onselectstart"] = function() {
            return false;
        };
        this["_mapControl"]["oncontextmenu"] = function() {
            return false;
        };
        this["_mapControl"]["style"]["cursor"] = "url(" + CursorOpenHand + ")";
        this["_mapCenterX"] = 0;
        this["_mapCenterY"] = 0;
        this["GetMapCenter"] = function() {
            var mapcenter = new Object();
            mapcenter["x"] = this["_mapCenterX"];
            mapcenter["y"] = this["_mapCenterY"];
            return mapcenter;
        };
        this["AddChild"] = function(node) {
            this["_mapControl"]["appendChild"](node);
        };
        this["RemoveChild"] = function(node) {
            this["_mapControl"]["removeChild"](node);
        };
        this["_tilesContainer"] = document["createElement"]("DIV");
        this["_tilesContainer"]["style"]["cssText"] = TilesContainerStyle;
        this.AddChild(this._tilesContainer);

        this["_tilesContainer2"] = document["createElement"]("DIV");
        this["_tilesContainer2"]["style"]["cssText"] = TilesContainerStyle2;
        this.AddChild(this._tilesContainer2);
        
        this["_width"] = 0;
        this["_height"] = 0;
        this["_ApplyMapSize"] = function() {
            this["_mapControl"]["style"]["width"] = this["_width"]+"px";
            this["_mapControl"]["style"]["height"] = this["_height"]+"px";
        };
        this["ChangeMapSize"] = function(width, height) {
            var gWidth = parseInt(width);
            if (gWidth) {
                this["_width"] = gWidth;
            } else {
                this["_width"] = DefaultMapWidth;
            };
            var gHeight = parseInt(height);
            if (gHeight) {
                this["_height"] = gHeight;
            } else {
                this["_height"] = DefaultMapHeight;
            };
            //this._ApplyMapSize();
            this._SetTileCount();
            this._BuildMap();
            this.UpdateMap();
        };
        this["MapAutoSize"] = function() {
            //var width = getClientWidth() - this.mapAutoSizeWidth;
            //var height = getClientHeight() - this.mapAutoSizeHeight;

            var width = parseInt(this._mapControl.offsetWidth) - this.mapAutoSizeWidth;
            var height = parseInt(this._mapControl.offsetHeight) - this.mapAutoSizeHeight;

            //var width = this["_mapControl"]["style"]["width"];
            //var height = this["_mapControl"]["style"]["height"];
            map.ChangeMapSize(width, height);
        }

        function getClientWidth() {
            return document.compatMode == 'CSS1Compat' && !window.opera ? document.documentElement.clientWidth : document.body.clientWidth;
        }

        function getClientHeight() {
            return document.compatMode == 'CSS1Compat' && !window.opera ? document.documentElement.clientHeight : document.body.clientHeight;
        }
        this["mapAutoSize"] = true;
        this["mapAutoSizeWidth"] = 0;
        this["mapAutoSizeHeight"] = 0;
        this["onMapWindowResize"] = function() {
            if (map.mapAutoSize) {
                map.MapAutoSize();
            }
        }
        //document.body.onresize = this.onMapWindowResize;
		 window.onresize = this.onMapWindowResize;
		 
        this["GetWidth"] = function() {
            return this["_width"];
        };
        this["GetHeight"] = function() {
            return this["_height"];
        };
        this["_tileCountX"] = 0;
        this["_tileCountY"] = 0;
        this["_SetTileCount"] = function() {
            var i = Math["ceil"](this["_width"] / tileWidth);
            var j = Math["ceil"](this["_height"] / tileHeight);
            i++;
            j++;
            if (i % 2 == 0) {
                i++;
            };
            if (j % 2 == 0) {
                j++;
            };
            this["_tileCountX"] = i;
            this["_tileCountY"] = j;
        };
        this["_tileArray"] = new Array();
        this["_tileArray2"] = new Array(); //
        this._lastMousePosOnWheel;
        this._zoomAnimationInProgress = false;
        this._zoomAnimationsCount = 0;
        this._MapClickX;
        this._MapClickY;
        this._loadedTilesCount = 0;
        this._tilesWasLoaded = false;
        this._enableMouseWheelOnlyAfterMouseDown = false;
        this._disableMouseWheelAfterMouseLeave = false;
        this._mouseWheelEnabled = true;

        this["SetDisableMouseWheelAfterMouseLeave"] = function(enable) {
            this._disableMouseWheelAfterMouseLeave = enable;
        }

        this["SetMouseWheelEnabled"] = function(enable) {
            this._mouseWheelEnabled = enable;
        }

        this["SetEnableMouseWheelOnlyAfterClick"] = function(enable) {
            this._enableMouseWheelOnlyAfterMouseDown = enable;
            this.SetMouseWheelEnabled(!enable);
        }
        
        this["_BuildMap"] = function() {
            while (this["_tilesContainer"]["childNodes"]["length"] > 0) {
                this["_tilesContainer"]["removeChild"](this["_tilesContainer"]["firstChild"]);
            };
            while (this["_tilesContainer2"]["childNodes"]["length"] > 0) {
                this["_tilesContainer2"]["removeChild"](this["_tilesContainer2"]["firstChild"]);
            };
            for (i = 1; i <= this["_tileCountY"]; i++) {
                this["_tileArray"][i] = new Array();
                this["_tileArray2"][i] = new Array(); //
                for (j = 1; j <= this["_tileCountX"]; j++) {
                    this["_tileArray"][i][j] = document["createElement"]("IMG");
                    with (this["_tileArray"][i][j]) {
                        width = tileWidth;
                        height = tileHeight;
                        alt = TileAltName;
                        onmousedown = function() {
                            return false;
                        };
                        onmousemove = function() {
                            return false;
                        };
                        onmouseup = function() {
                            return false;
                        };
                        onlclick = function() {
                            return false;
                        };
                        ondblclick = function() {
                            return false;
                        };
                    };
                    this["_tileArray"][i][j]["galleryImg"] = "no";
                    this["_tileArray"][i][j]["unselectable"] = "on";
                    this["_tileArray"][i][j]["style"]["cssText"] = TileStyle;
                    var obj = GetDeltaToCenter(this);
                    dtx = obj["dtx"];
                    dty = obj["dty"];
                    this["_tileArray"][i][j]["style"]["left"] = (j - 1) * tileWidth + dtx + "px";
                    this["_tileArray"][i][j]["style"]["top"] = (i - 1) * tileHeight + dty + "px";
                    this["_tilesContainer"]["appendChild"](this["_tileArray"][i][j]);
                    //---------------------------------------------------------------------
                    this["_tileArray2"][i][j] = document["createElement"]("IMG");
                    with (this["_tileArray2"][i][j]) {
                        width = tileWidth;
                        height = tileHeight;
                        alt = TileAltName2;
                        onmousedown = function() {
                            return false;
                        };
                        onmousemove = function() {
                            return false;
                        };
                        onmouseup = function() {
                            return false;
                        };
                        onlclick = function() {
                            return false;
                        };
                        ondblclick = function() {
                            return false;
                        };
                    };
                    this["_tileArray2"][i][j]["galleryImg"] = "no";
                    this["_tileArray2"][i][j]["unselectable"] = "on";
                    this["_tileArray2"][i][j]["style"]["cssText"] = TileStyle2;
                    var obj = GetDeltaToCenter(this);
                    dtx = obj["dtx"];
                    dty = obj["dty"];
                    this._tileArray2[i][j].style.left = (j - 1) * tileWidth + dtx + "px";
                    this._tileArray2[i][j].style.top = (i - 1) * tileHeight + dty + "px";

                    this._tileArray2[i][j].width = tileWidth + "px";
                    this._tileArray2[i][j].height = tileHeight + "px";
                    this._tilesContainer2.appendChild(this._tileArray2[i][j]);

                    //----------------------------
                };
            };
            
        };
        this["onmove"] = function() {
            return true;
        };
        this["_MoveTiles"] = function(x, y) {
            for (i = 1; i <= this["_tileCountY"]; i++) {
                for (j = 1; j <= this["_tileCountX"]; j++) {
                    //---------------------------------
//                    TileTopOld = parseInt(this["_tileArray2"][i][j]["style"]["top"]);
//                    TileTopNew = TileTopOld + parseInt(y);
//                    this["_tileArray2"][i][j]["style"]["top"] = TileTopNew + "px";
//                    TileLeftOld = parseInt(this["_tileArray2"][i][j]["style"]["left"]);
//                    TileLeftNew = TileLeftOld + parseInt(x);
//                    this["_tileArray2"][i][j]["style"]["left"] = TileLeftNew + "px";
                    //---------------------------------
                    TileTopOld = parseInt(this["_tileArray"][i][j]["style"]["top"]);
                    TileTopNew = TileTopOld + parseInt(y);
                    this["_tileArray"][i][j]["style"]["top"] = TileTopNew + "px";
                    TileLeftOld = parseInt(this["_tileArray"][i][j]["style"]["left"]);
                    TileLeftNew = TileLeftOld + parseInt(x);
                    this["_tileArray"][i][j]["style"]["left"] = TileLeftNew + "px";
                };
            };
            this["onmove"]();
        };
        this["_x"] = 0;
        this["_y"] = 0;
        this["_z"] = 0;
        this["_offset_x"] = 0;
        this["_offset_y"] = 0;
        this["_SetXY"] = function() {
            this["_x"] = Math["floor"](this["_mapCenterX"] / kWinToMap[this["_z"]] / tileWidth);
            this["_y"] = Math["ceil"](this["_mapCenterY"] / kWinToMap[this["_z"]] / tileHeight);
        };
        this["_UpdateImage"] = function(zoomMode) {
        if (this._zoomAnimationsCount ==0)
            for (i = 1; i <= this["_tileCountY"]; i++) {
                for (j = 1; j <= this["_tileCountX"]; j++) {
                    var nx = this["_x"] + this["_offset_x"] - Math["floor"](1 + this["_tileCountX"] / 2) + j;
                    var ny = this["_y"] + this["_offset_y"] + Math["floor"](1 + this["_tileCountY"] / 2) - i;
                    SetDelayedImage(this["_tileArray"][i][j], nx, ny, this._z, this["_tileArray2"][i][j],zoomMode,this);
                };
            };
        };
        this["_CenterMap"] = function() {
            var obj = GetDeltaToCenter(this);
            var dtx = obj["dtx"];
            var dty = obj["dty"];
            var dddx = parseInt(this["_tileArray"][1][1]["style"]["left"]);
            var dddy = parseInt(this["_tileArray"][1][1]["style"]["top"]);
            var nx = (this["_x"] + this["_offset_x"]) * kWinToMap[this["_z"]] * tileWidth;
            var ny = (this["_y"] + this["_offset_y"]) * kWinToMap[this["_z"]] * tileHeight;
            var ddx = this["_mapCenterX"] - nx;
            var ddy = this["_mapCenterY"] - ny;
            ddx /= kWinToMap[this["_z"]];
            ddy /= kWinToMap[this["_z"]];
            var ndx = dtx - dddx - ddx;
            var ndy = dty - dddy + ddy;
            this._MoveTiles(ndx, ndy);
        };



            this["UpdateMap"] = function(zoomMode) {
                this["_offset_x"] = 0;
                this["_offset_y"] = 0;

                this._SetXY();
                this._UpdateImage(zoomMode);
                this._CenterMap();
            };
        this["_replaceToLeft"] = function() {
            this["_offset_x"]--;
            var left_border = parseInt(this["_tileArray"][1][1]["style"]["left"]);
            for (i = 1; i <= this["_tileCountY"]; i++) {
                //---------------
//                this["_tileArray2"][i][0] = this["_tileArray2"][i][this["_tileCountX"]];
//                this["_tileArray2"][i][0]["style"]["left"] = left_border - tileWidth + "px";
//                var nx = this["_x"] + this["_offset_x"] - Math["floor"](1 + this["_tileCountX"] / 2) + 1;
//                var ny = this["_y"] + this["_offset_y"] + Math["floor"](1 + this["_tileCountY"] / 2) - i;
//                for (j = this["_tileCountX"]; j > 0; j--) {
//                    this["_tileArray2"][i][j] = this["_tileArray2"][i][j - 1];
//                };
                //--------------
                
                this["_tileArray"][i][0] = this["_tileArray"][i][this["_tileCountX"]];
                this["_tileArray"][i][0]["style"]["left"] = left_border - tileWidth +"px";
                var nx = this["_x"] + this["_offset_x"] - Math["floor"](1 + this["_tileCountX"] / 2) + 1;
                var ny = this["_y"] + this["_offset_y"] + Math["floor"](1 + this["_tileCountY"] / 2) - i;
                SetDelayedImage(this["_tileArray"][i][0], nx, ny, this._z, this["_tileArray2"][i][0], ZoomNoneMode,this);
                for (j = this["_tileCountX"]; j > 0; j--) {
                    this["_tileArray"][i][j] = this["_tileArray"][i][j - 1];
                };
                
            };
        };
        this["_replaceToRight"] = function() {
              this["_offset_x"]++;
            var right_border = parseInt(this["_tileArray"][1][this["_tileCountX"]]["style"]["left"]);
            for (i = 1; i <= this["_tileCountY"]; i++) {
               
                this["_tileArray"][i][0] = this["_tileArray"][i][1];
                this["_tileArray"][i][0]["style"]["left"] = right_border + tileWidth + "px";
                var nx = this["_x"] + this["_offset_x"] + Math["ceil"](this["_tileCountX"] / 2) - 1;
                var ny = this["_y"] + this["_offset_y"] + Math["floor"](1 + this["_tileCountY"] / 2) - i;
                SetDelayedImage(this["_tileArray"][i][0], nx, ny, this._z, this["_tileArray2"][i][0], ZoomNoneMode, this);
                for (j = 1; j <= this["_tileCountX"]; j++) {
                   this["_tileArray"][i][j] = (j != this["_tileCountX"]) ? (this["_tileArray"][i][j + 1]) : (this["_tileArray"][i][0]);
                };
                
            };
        };
        this["_replaceToTop"] = function() {
            this["_offset_y"]++;
            this["_tileArray"][0] = new Array();
            this["_tileArray2"][0] = new Array();//
            var top_border = parseInt(this["_tileArray"][1][1]["style"]["top"]);
            for (i = 1; i <= this["_tileCountX"]; i++) {
                //--------------
//                this["_tileArray2"][0][i] = this["_tileArray2"][this["_tileCountY"]][i];
//                this["_tileArray2"][0][i]["style"]["top"] = top_border - tileHeight + "px";
//                var nx = this["_x"] + this["_offset_x"] - Math["floor"](1 + this["_tileCountX"] / 2) + i;
//                var ny = this["_y"] + this["_offset_y"] + Math["floor"](1 + this["_tileCountY"] / 2) - 1;
//                for (j = this["_tileCountY"]; j > 0; j--) {
//                    this["_tileArray2"][j][i] = this["_tileArray2"][j - 1][i];
//                };
                //--------------
                
                this["_tileArray"][0][i] = this["_tileArray"][this["_tileCountY"]][i];
                this["_tileArray"][0][i]["style"]["top"] = top_border - tileHeight + "px";
                var nx = this["_x"] + this["_offset_x"] - Math["floor"](1 + this["_tileCountX"] / 2) + i;
                var ny = this["_y"] + this["_offset_y"] + Math["floor"](1 + this["_tileCountY"] / 2) - 1;
                SetDelayedImage(this["_tileArray"][0][i], nx, ny, this._z, this["_tileArray2"][0][i], ZoomNoneMode, this);
                for (j = this["_tileCountY"]; j > 0; j--) {
                    this["_tileArray"][j][i] = this["_tileArray"][j - 1][i];
                };
                
            };
        };
        this["_replaceToBottom"] = function() {
            this["_offset_y"]--;
            this["_tileArray"][0] = new Array();
            this["_tileArray2"][0] = new Array();//
            var bottom_border = parseInt(this["_tileArray"][this["_tileCountY"]][1]["style"]["top"]);
            for (i = 1; i <= this["_tileCountX"]; i++) {
                //------------
//                this["_tileArray2"][0][i] = this["_tileArray2"][1][i];
//                this["_tileArray2"][0][i]["style"]["top"] = bottom_border + tileHeight;
//                var nx = this["_x"] + this["_offset_x"] - Math["floor"](1 + this["_tileCountX"] / 2) + i;
//                var ny = this["_y"] + this["_offset_y"] - Math["ceil"](this["_tileCountY"] / 2) + 1;
//                for (j = 1; j <= this["_tileCountY"]; j++) {
//                    this["_tileArray2"][j][i] = (j != this["_tileCountY"]) ? (this["_tileArray2"][j + 1][i]) : (this["_tileArray2"][0][i]);
//                };
                //------------
                
                this["_tileArray"][0][i] = this["_tileArray"][1][i];
                this["_tileArray"][0][i]["style"]["top"] = bottom_border + tileHeight + "px";
                var nx = this["_x"] + this["_offset_x"] - Math["floor"](1 + this["_tileCountX"] / 2) + i;
                var ny = this["_y"] + this["_offset_y"] - Math["ceil"](this["_tileCountY"] / 2) + 1;
                SetDelayedImage(this["_tileArray"][0][i], nx, ny, this._z, this["_tileArray2"][0][i], ZoomNoneMode, this);
                for (j = 1; j <= this["_tileCountY"]; j++) {
                    this["_tileArray"][j][i] = (j != this["_tileCountY"]) ? (this["_tileArray"][j + 1][i]) : (this["_tileArray"][0][i]);
                };
               
            };
        };
        this["MoveLeft"] = function() {
            this["_mapCenterX"] -= MOVE_OFFSET * kWinToMap[this["_z"]];
            var d = parseInt(this["_tileArray"][1][1]["style"]["left"]) + MOVE_OFFSET;
            if (d > 0) {
                this._replaceToLeft();
                this._MoveTiles(MOVE_OFFSET, 0);
            } else {
                this._MoveTiles(MOVE_OFFSET, 0);
            };
        };
        this["MoveRight"] = function() {
            this["_mapCenterX"] += MOVE_OFFSET * kWinToMap[this["_z"]];
            var d = parseInt(this["_tileArray"][1][this["_tileCountX"]]["style"]["left"]) - MOVE_OFFSET + tileWidth;
            if (d < this["_width"]) {
                this._replaceToRight(); this._MoveTiles(-MOVE_OFFSET, 0);
            } else {
                this._MoveTiles(-MOVE_OFFSET, 0);
            };
        };
        this["MoveUp"] = function() {
            this["_mapCenterY"] += MOVE_OFFSET * kWinToMap[this["_z"]];
            var d = parseInt(this["_tileArray"][1][1]["style"]["top"]) + MOVE_OFFSET;
            if (d > 0) {
                this._replaceToTop(); this._MoveTiles(0, MOVE_OFFSET);
            } else {
                this._MoveTiles(0, MOVE_OFFSET);
            };
        };
        this["MoveDown"] = function() {
            this["_mapCenterY"] -= MOVE_OFFSET * kWinToMap[this["_z"]];
            var d = parseInt(this["_tileArray"][this["_tileCountY"]][2]["style"]["top"]) - MOVE_OFFSET + tileHeight;
            if (d < this["_height"]) {
                this._replaceToBottom(); this._MoveTiles(0, -MOVE_OFFSET);
            } else {
                this._MoveTiles(0, -MOVE_OFFSET);
            };
        };
        this["_GetMarkerDistance"] = function(mIndex1, mIndex2) {
            var d = 0; if ((mIndex1 >= 0) && (mIndex2 < this["_markerIndex"]) && (array)) {
                for (var i = mIndex1; i < mIndex2; i++) {
                    var x1 = array[i]["_x"];
                    var x2 = array[i + 1]["_x"];
                    var y1 = array[i]["_y"];
                    var y2 = array[i + 1]["_y"];
                    d += Math["sqrt"](Math["pow"](x1 - x2, 2) + Math["pow"](y1 - y2, 2));
                };
            };
            return d;
        };
        this["_GetLineMarkerDistance"] = function(mIndex1, mIndex2) {
            var d = 0;
            if ((mIndex1 >= 0) && (mIndex2 < this["_lineMarkerIndex"])) {
                for (var i = mIndex1; i < mIndex2; i++) {
                    var x1 = this["_lineMarkers"][i]["_x"];
                    var x2 = this["_lineMarkers"][i + 1]["_x"];
                    var y1 = this["_lineMarkers"][i]["_y"];
                    var y2 = this["_lineMarkers"][i + 1]["_y"];
                    d += Math["sqrt"](Math["pow"](x1 - x2, 2) + Math["pow"](y1 - y2, 2));
                };
            };
            return d;
        };
        this["_scaleStarted"] = 0;
        this["StartScale"] = function() {
            if (this["_scaleStarted"] == 0) {
                //                this["_scaleStarted"] = 1;
                //                this["_scaleControl"]["firstChild"]["src"] = AltScaleImagePath;
                //                this["_mapControl"]["style"]["cursor"] = "default";
                this.EnableScaleTool();
            } else {
//                this["_scaleStarted"] = 0;
//                this["_scaleControl"]["firstChild"]["src"] = ScaleImagePath;
//                this["_mapControl"]["style"]["cursor"] = "url(" + CursorOpenHand + ")";
//                this.RemoveAllLineMarkers();
                  this.DisableScaleTool();
            };
        };

        this["EnableScaleTool"] = function() {
            this["_scaleStarted"] = 1;
            this["_scaleControl"]["firstChild"]["src"] = AltScaleImagePath;
            //this["_mapControl"]["style"]["cursor"] = "default";
        };

        this["DisableScaleTool"] = function() {
            this["_scaleStarted"] = 0;
            this["_scaleControl"]["firstChild"]["src"] = ScaleImagePath;
            this.RemoveAllLineMarkers();
        };
        
        this["_isDragging"] = false;
        this["_firstTileX"] = 0;
        this["_firstTileY"] = 0;
        this["_startDragPos"] = 0;
        this["_currDragPos"] = 0;
        this["_mapCenterXb"] = 0;
        this["_mapCenterYb"] = 0;
        this["_SetTilesPosition"] = function(PosX, PosY) {
            for (i = 1; i <= this["_tileCountY"]; i++) {
                for (j = 1; j <= this["_tileCountX"]; j++) {
                    this["_tileArray"][i][j]["style"]["left"] = parseInt(PosX) + (j - 1) * tileWidth + "px";
                    this["_tileArray"][i][j]["style"]["top"] = parseInt(PosY) + (i - 1) * tileHeight + "px";
                    //--------------
                    //this._tileArray2[i][j].style.left = parseInt(PosX) + (j - 1) * this._tileArray2[i][j].width + "px";
                    //this._tileArray2[i][j].style.top = parseInt(PosY) + (i - 1) * this._tileArray2[i][j].height + "px";
                    //------------
                };
            };
        };

        this["_SetTiles2Position"] = function(PosX, PosY) {
            for (i = 1; i <= this["_tileCountY"]; i++) {
                for (j = 1; j <= this["_tileCountX"]; j++) {
                    //--------------
                    this._tileArray2[i][j].style.left = parseInt(PosX) + (j - 1) * this._tileArray2[i][j].width + "px";
                    this._tileArray2[i][j].style.top = parseInt(PosY) + (i - 1) * this._tileArray2[i][j].height + "px";
                    //------------
                };
            };
        };
        
        this["_StartDrag"] = function(e) {
            document["_currMap"] = this;
            if (!this["_isDragging"]) {
                this["_startDragPos"] = mousePageXY(e);
                this["_mapCenterXb"] = this["_mapCenterX"];
                this["_mapCenterYb"] = this["_mapCenterY"];
            };
            this["_currDragPos"] = mousePageXY(e);
            this["_isDragging"] = true;
            this["_firstTileX"] = parseInt(this["_tileArray"][1][1]["style"]["left"]);
            this["_firstTileY"] = parseInt(this["_tileArray"][1][1]["style"]["top"]);
            
            this["_firstTile2X"] = parseInt(this["_tileArray2"][1][1]["style"]["left"]);//
            this["_firstTile2Y"] = parseInt(this["_tileArray2"][1][1]["style"]["top"]);//
            
            for (marker in this["_markers"]) {
                this["_markers"][marker].SetMarkerFixPoint();
            };
            for (marker in this["_lineMarkers"]) {
                this["_lineMarkers"][marker].SetMarkerFixPoint();
            };
        };
        this["_Drag"] = function(e) {
            if (this["_isDragging"]) {
                var newDragPos = mousePageXY(e);
                var dx = newDragPos["x"] - this["_currDragPos"]["x"];
                var dy = newDragPos["y"] - this["_currDragPos"]["y"];
                this._SetTilesPosition(this["_firstTileX"] + dx, this["_firstTileY"] + dy);
                this._SetTiles2Position(this["_firstTile2X"] + dx, this["_firstTile2Y"] + dy);
                for (marker in this["_markers"]) {
                    this["_markers"][marker].MoveMarkerFromFixPoint(dx, dy);
                };
                for (marker in this["_lineMarkers"]) {
                    this["_lineMarkers"][marker].MoveMarkerFromFixPoint(dx, dy);
                };
                var mapCX = this["_mapCenterXb"] - (newDragPos["x"] - this["_startDragPos"]["x"]) * kWinToMap[this["_z"]];
                var mapCY = this["_mapCenterYb"] + (newDragPos["y"] - this["_startDragPos"]["y"]) * kWinToMap[this["_z"]];
                this["_mapCenterX"] = parseFloat(mapCX);
                this["_mapCenterY"] = parseFloat(mapCY);
                var delta_left = parseInt(this["_tileArray"][1][1]["style"]["left"]) + PRELOAD_OFFSET;
                if (delta_left > 0) {
                    this._replaceToLeft();
                    this._StartDrag(e);
                };
                var delta_right = parseInt(this["_tileArray"][1][this["_tileCountX"]]["style"]["left"]) - PRELOAD_OFFSET + tileWidth;
                if (delta_right < this["_width"]) {
                    this._replaceToRight();
                    this._StartDrag(e);
                };
                var delta_up = parseInt(this["_tileArray"][1][1]["style"]["top"]) + PRELOAD_OFFSET;
                if (delta_up > 0) {
                    this._replaceToTop();
                    this._StartDrag(e);
                };
                var delta_down = parseInt(this["_tileArray"][this["_tileCountY"]][2]["style"]["top"]) - PRELOAD_OFFSET + tileHeight;
                if (delta_down < this["_height"]) {
                    this._replaceToBottom();
                    this._StartDrag(e);
                };
                this["onmove"]();
            };
        };
        this["_EndDrag"] = function(e) {
            if (this["_isDragging"]) {
                this["_isDragging"] = false;
            };
            var needCorrection = false;
            var correctedX = this._mapCenterX;
            var correctedY = this._mapCenterY;
            
            if (this._mapCenterX < MapMinScrollX) {
                needCorrection = true;
                correctedX = MapMinScrollX;
            }
            else
            if (this._mapCenterX > MapMaxScrollX) {
                needCorrection = true;
                correctedX = MapMaxScrollX;
            }

            if (this._mapCenterY < MapMinScrollY) {
                needCorrection = true;
                correctedY = MapMinScrollY;
            }
            else
            if (this._mapCenterY > MapMaxScrollY) {
                needCorrection = true;
                correctedY = MapMaxScrollY;
            }
            
            if(needCorrection)
                this.SetMapCenter(correctedX, correctedY);
                

        };
        this["_moveMapCenter"] = function(dx, dy) {
            this["_mapCenterX"] += parseFloat(dx);
            this["_mapCenterY"] += parseFloat(dy);
        };
        this["_mapControl"]["_owner"] = this;
        this["_mapControl"]["_onmousedown"] = function(e) {
            if (this._enableMouseWheelOnlyAfterMouseDown) {
                if (!this._mouseWheelEnabled)
                 this.SetMouseWheelEnabled(true);
            }
            var event = window.event || e;
            if (event["button"]) {
                if (event["button"] == 1) {
                    this._StartDrag(e);
                };
            };
            if (event["which"]) {
                if (event["which"] == 1) {
                    this._StartDrag(e);
                };
            };
        };
        this["_mapControl"]["onmousedown"] = function(e) {
            this["_onmousedown"]["call"](this._owner, e);
        };
        this["_mapControl"]["_onmousemove"] = function(e) {
            //this._mouseWheelEnabled = true; //
            this._Drag(e);
            this._controls_drag(e);
            for (marker in this["_markers"]) {
                this["_markers"][marker]._Drag(e);
            };
            for (marker in this["_lineMarkers"]) {
                this["_lineMarkers"][marker]._Drag(e);
            };
        };

//        this["_mapControl"]["onmouseout"] = function(e) {
//            this["_onmouseout"]["call"](this._owner, e);
//        };

        $(this._mapControl).mouseleave(function() {
        // this["_onmouseout"]["call"](this._owner, e);
            if (this._owner._disableMouseWheelAfterMouseLeave) {
            this._owner.SetMouseWheelEnabled(false);
            }
         });

    //    $(this._mapControl).mouseleave();


        this["_mapControl"]["_onmouseout"] = function(e) {
            //this._mouseWheelEnabled = false; //
            if (this._disableMouseWheelAfterMouseLeave) {
                this.SetMouseWheelEnabled(false);
            }

        };
        
        this["_mapControl"]["onmousemove"] = function(e) {
            this["_onmousemove"]["call"](this._owner, e);
        };
        this["_mapControl"]["onclick"] = function(e) {
            this["focus"]();
        };
        document["_currMap"] = this;
        document["_onmouseup"] = function(e) {
            var event = window.event || e;
            if (event["button"]) {
                if (event["button"] == 1) {
                    this._EndDrag(e);
                    this._controls_enddrag(e);
                    for (marker in this["_markers"]) {
                        this["_markers"][marker]._EndDrag(e);
                    };
                    for (marker in this["_lineMarkers"]) {
                        this["_lineMarkers"][marker]._EndDrag(e);
                    };
                };
            };
            if (event["which"]) {
                if (event["which"] == 1) {
                    this._EndDrag(e);
                    this._controls_enddrag(e);
                    for (marker in this["_markers"]) {
                        this["_markers"][marker]._EndDrag(e);
                    };
                    for (marker in this["_lineMarkers"]) {
                        this["_lineMarkers"][marker]._EndDrag(e);
                    };
                };
            };
            //
            var mousePos = mousePageXY(e);
            var dx = Math.abs(mousePos.x - this._startDragPos.x);
            var dy = Math.abs(mousePos.y - this._startDragPos.y);
            if (dx < 1 && dy < 1) {
                var mapCoord = this._GetMouseXYOnMap(e);
                var mouseX = mapCoord.x;
                var mouseY = mapCoord.y;
                if (this["_scaleStarted"] != 0) {
                    this.AddLineMarker(mouseX, mouseY, "");
                    this["_lineMarkers"][this["_lineMarkerIndex"] - 1].SetDescription(Math["round"](this._GetLineMarkerDistance(0, this["_lineMarkerIndex"] - 1) * 100) / 100 + "\x26nbsp;м");
                    this["_scaleStarted"]++;
                } else {
                    if (this._isRouteMode) {
                        if (this["_startPoint"] && this["_finishPoint"]) {
                            this.ClearRoute();
                        }
                        if (this["_startPoint"]) {
                            this["_finishPoint"] = new Object();
                            this["_finishPoint"]["X"] = mouseX;
                            this["_finishPoint"]["Y"] = mouseY;
                            this.AddFinishRouteMarker(mouseX, mouseY, "Конец маршрута");
                            var opt = 0;
                            if (document.getElementById("bytime")["checked"])
                                opt = 1;
                            FindRoute(this._startPoint, this._finishPoint, opt, this._onFindRoute);

                        } else {
                            this["_startPoint"] = new Object();
                            this["_startPoint"]["X"] = mouseX;
                            this["_startPoint"]["Y"] = mouseY;
                            this.AddStartRouteMarker(mouseX, mouseY, "Начало маршрута");
                        }
                    }
                }

            }
            //



        };
        document["onmouseup"] = function(e) {
            this["_onmouseup"]["call"](this._currMap, e);
        };
        this["_GetMouseXYOnMap"] = function(e) {
            var mousePos = mousePageXY(e);
            this._lastMousePosOnWheel = mousePos;
            //var MapLeft = parseInt(this["_mapControl"]["offsetLeft"]);
            //var MapTop = parseInt(this["_mapControl"]["offsetTop"]);
            var offset = $(this._mapControl).offset(); //$("#map").offset(); //; 
            var MapLeft = offset.left;
            var MapTop = offset.top;

            var MapClickX = mousePos["x"] - MapLeft;
            var MapClickY = mousePos["y"] - MapTop;
            this._MapClickX = MapClickX;
            this._MapClickY = MapClickY;
            //this._lastMousePosOnWheel.x = MapClickX;
            //this._lastMousePosOnWheel.y = MapClickY;
            var mCenterX = this["_width"] / 2;
            var mCenterY = this["_height"] / 2;
            var MapDeltaX = MapClickX - mCenterX;
            var MapDeltaY = MapClickY - mCenterY;
            var mapPointX = this["_mapCenterX"] + MapDeltaX * kWinToMap[this["_z"]];
            var mapPointY = this["_mapCenterY"] - MapDeltaY * kWinToMap[this["_z"]];
            var mapCoord = new Object();
            mapCoord["x"] = mapPointX;
            mapCoord["y"] = mapPointY;
            return mapCoord;
        };
        this["_mapControl"]["ondblclick"] = function(e) {
            this["_ondblclick"]["call"](this._owner, e);
        };
        this["_mapControl"]["_onmousewheel"] = function(event) {
            if (this._enableMouseWheelOnlyAfterMouseDown) {
                if (!this._mouseWheelEnabled)
                     return;
            }

            var delta = 0;
            if (!event) {
                event = window["event"];
            };
            if (event["wheelDelta"]) {
                delta = event["wheelDelta"] / 120;
                if (window["opera"]) {
                    delta = delta;
                }
            }
            else if (event["detail"]) {
                delta = -event["detail"] / 3;
            }

            var mapCoordBeforeZoom = this["_GetMouseXYOnMap"](event);
            var mapCenter = this.GetMapCenter();
            if ((delta > 0) && (MIN_ZOOM_LEVEL < this["_z"])) {
                this.ZoomPlus(ZoomPlusWheelMode);
                var mapCoordAfterZoom = this._GetMouseXYOnMap(event);
                var newCenterX = mapCenter["x"] - (mapCoordAfterZoom["x"] - mapCoordBeforeZoom["x"]);
                var newCenterY = mapCenter["y"] - (mapCoordAfterZoom["y"] - mapCoordBeforeZoom["y"]);
                this.SetMapCenter(newCenterX, newCenterY, ZoomNoClearMode);
            } else {
                if ((delta < 0) && (MAX_ZOOM_LEVEL > this["_z"])) {
                    this.ZoomMinus(ZoomMinusWheelMode);
                    var mapCoordAfterZoom = this._GetMouseXYOnMap(event);
                    var newCenterX = mapCenter["x"] - (mapCoordAfterZoom["x"] - mapCoordBeforeZoom["x"]);
                    var newCenterY = mapCenter["y"] - (mapCoordAfterZoom["y"] - mapCoordBeforeZoom["y"]);
                    this.SetMapCenter(newCenterX, newCenterY, ZoomNoClearMode);
                };
            };
            if (event["preventDefault"]) {
                event["preventDefault"]();
            };
            event["returnValue"] = false;
        };
        this["_mapControl"]["onmousewheel"] = function(event) {
            this["_onmousewheel"]["call"](this._owner, event);
        };
        if (this["_mapControl"]["addEventListener"]) {
            this["_mapControl"]["addEventListener"]('DOMMouseScroll', this["_mapControl"]["onmousewheel"], false);
        }
        this["SetMapCenter"] = function(newX, newY, zoomMode) {
            this["_mapCenterX"] = parseInt(newX);
            this["_mapCenterY"] = parseInt(newY);
            this.UpdateMap(zoomMode);
        };

        this["CorrectBackTilesZoom_"] = function(ic, jc, Sim) {
            var corrector = Sim * 2;
            var centerTile = this._tileArray[ic][jc];
            var centerBackImage = this._tileArray2[ic][jc];
            var dLeft = 0; //parseInt(centerTile.style.left) + parseInt(centerTile.width / 2) - parseInt(centerBackImage.style.left) + parseInt(centerBackImage.width / 2);
            var dTop = 0; //parseInt(centerTile.style.top) + parseInt(centerTile.height / 2) - parseInt(centerBackImage.style.top) + parseInt(centerBackImage.height / 2);
            for (var i = 1; i <= this["_tileCountY"]; i++)
                for (j = 1; j <= this["_tileCountX"]; j++) {
                var backImage = this._tileArray2[i][j];
                if (j < jc) {
                    backImage.style.left = parseInt(backImage.style.left) - (jc - j) * corrector + dLeft + "px";
                }
                else
                    if (j > jc) {
                    backImage.style.left = parseInt(backImage.style.left) + (j - jc) * corrector + dLeft + "px";
                }

                if (i < ic) {
                    backImage.style.top = parseInt(backImage.style.top) - (ic - i) * corrector + dTop + "px";
                }
                else
                    if (i > ic) {
                    backImage.style.top = parseInt(backImage.style.top) + (i - ic) * corrector + dTop + "px";
                }
            }

        }

        this["CorrectBackTilesZoom"] = function(lc, tc, Sim) {
            var ic = Math.ceil(this._tileCountY / 2);
            var jc = Math.ceil(this._tileCountX / 2);
            for (var i = 1; i <= this["_tileCountY"]; i++)
                for (j = 1; j <= this["_tileCountX"]; j++) {
                var backImage = this._tileArray2[i][j];
                var blc = parseInt((parseInt(backImage.style.left) + backImage.width) / 2);
                var btc = parseInt((parseInt(backImage.style.top) + backImage.height) / 2);
                if (btc < tc) {
                    backImage.style.left = parseInt(backImage.style.left) - (jc - j) * Sim + "px";
                }
                else
                    if (btc > tc) {
                    backImage.style.left = parseInt(backImage.style.left) + (j - jc) * Sim + "px";
                }

                if (blc < lc) {
                    backImage.style.top = parseInt(backImage.style.top) - (ic - i) * Sim + "px";
                }
                else
                    if (blc > lc) {
                    backImage.style.top = parseInt(backImage.style.top) + (i - ic) * Sim + "px";
                }
            }

        }

        this["ScaleBackImages"] = function(Sim, dx, dy) {
            if (!dx || !dy) {
                dx = 0;
                dy = 0;
            }

            for (var i = 1; i <= this["_tileCountY"]; i++)
                for (var j = 1; j <= this["_tileCountX"]; j++) {
                var image = this._tileArray[i][j];
                var backImage = this._tileArray2[i][j];
                var newBackWidth = backImage.width + 2 * Sim;
                var newBackHeight = backImage.height + 2 * Sim;

                backImage.width = newBackWidth;
                backImage.height = newBackHeight;
                backImage.style.left = parseInt(backImage.style.left) - Sim + dx + "px";
                backImage.style.top = parseInt(backImage.style.top) - Sim + dy + "px";
                backImage.style.visibility = "visible";
            }
        }

        this["CheckScaleBackImagesPossibility"] = function(Sim) {
            for (var i = 1; i <= this["_tileCountY"]; i++)
                for (var j = 1; j <= this["_tileCountX"]; j++) {
                var image = this._tileArray[i][j];
                var backImage = this._tileArray2[i][j];
                var newBackWidth = backImage.width + 2 * Sim;
                if (newBackWidth < 0) {
                    return false;

                }

                var newBackHeight = backImage.height + 2 * Sim;
                if (newBackHeight < 0) {
                    return false;
                }
            }
            return true;
        }

        this["SetBackTilesToTop"] = function() {
         this._tilesContainer2.style.zIndex = 1;
         this._tilesContainer.style.zIndex = 0;
        };

        this["SetBackTilesToBottom"] = function() {
        this._tilesContainer2.style.zIndex = 0;
        this._tilesContainer.style.zIndex = 1;
          
         };

         this["IsCorrect"] = function() {
             var firstBackImage = this._tileArray2[1][1];
             var secondBackImage = this._tileArray2[1][2];
             var delta = Math.abs(parseInt(firstBackImage.style.left) + firstBackImage.width - parseInt(secondBackImage.style.left));
             if (delta < 1)
                 return true
             else
                 return false;
         }

         this["animate"] = function(Sim, dx, dy, ic, jc, iterations) {
             var map = this;
            if (!map.IsCorrect())
                map.HideBackTiles();
             
             var SimA = Math.ceil(Sim / iterations);
             var dxA = Math.ceil(dx / iterations);
             var dyA = Math.ceil(dy / iterations);
             var iterationsCount = 0;
             this._zoomAnimationInProgress = true;
             this._zoomAnimationsCount++;
             //this._tilesContainer2.style.display = "block";
             // this.SetBackTilesToTop();

             // map._tilesContainer.style.display = "none";
             //map._tilesContainer2.style.display = "block";

             //map.RemoveAllMarkers(); //

             setTimeout(function() {
                if (!map.IsCorrect())
                    map.HideBackTiles();
                 /* Тут изменение параметров */
                 map.ScaleBackImages(SimA, dxA, dyA);
                 map.CorrectBackTilesZoom_(ic, jc, SimA);
                 if (iterationsCount < iterations) {
                     iterationsCount++;
                     setTimeout(arguments.callee, 10);
                 }
                 else {
                     //map._tilesContainer.style.display = "block";

                     map._zoomAnimationsCount--;

                     //

                     function check() {
                         if (map._zoomAnimationsCount == 0 && map._zoomAnimationInProgress == true) {
                             map.ShowFrontTiles(); //map._tilesContainer.style.display = "block";
                             //map.SetBackTilesToBottom();
                             map._UpdateImage(ZoomNoneMode);
                             map._zoomAnimationInProgress = false;

                         }

                     }
                     if (map._zoomAnimationsCount == 0)
                         setTimeout(check, 1200)

                     //
                     //SetBackTilesSrc(map);


                 }

             }, 0);
         }

         this["HideBackTiles"] = function() {
         map._tilesContainer2.style.display = "none";
        }

        this["ShowBackTiles"] = function() {
            map._tilesContainer2.style.display = "block";
        }

        this["HideFrontTiles"] = function() {
            map._tilesContainer.style.display = "none";
        }

        this["ShowFrontTiles"] = function() {
            map._tilesContainer.style.display = "block";
        }

        this["SetZoom"] = function(level, zoomMode) {

            level = parseInt(level);
            if ((MIN_ZOOM_LEVEL <= level) && (level <= MAX_ZOOM_LEVEL)) {
                this["_z"] = level;

                if (zoomMode) {
                    map.HideFrontTiles(); //map._tilesContainer.style.display = "none";
                    map.ShowBackTiles(); //map._tilesContainer2.style.display = "block";
                    //this._tilesContainer2.style.display = "block";
                    //SetBackTilesPosition(map);
                    //SetBackTilesSrc(map);
                    map._loadedTilesCount = 0;

                    var ic = Math.ceil(this._tileCountY / 2);
                    var jc = Math.ceil(this._tileCountX / 2);
                    var centerTile = this._tileArray[ic][jc];
                    var firstBackImage = this._tileArray2[1][1];
                    var firstBackImageLeft = parseInt(firstBackImage.style.left);
                    var firstBackImageTop = parseInt(firstBackImage.style.top);
                    var centerBackImage = this._tileArray2[ic][jc];
                    var mousePos;

                    //var topLeftBackImage = this._tileArray2[1][1];
                    //var bottomRightBackImage = this._tileArray2[this._tileCountY][this._tileCountX];
                    var centerBackImageLeft = parseInt(parseInt(centerBackImage.style.left) + centerBackImage.width / 2);//$(centerBackImage).offset().left + centerBackImage.width / 2;  // parseInt((parseInt(bottomRightBackImage.style.left) + bottomRightBackImage.width - parseInt(topLeftBackImage.style.left)) / 2); //parseInt(this._width) / 2;
                    var centerBackImageTop =  parseInt(parseInt(centerBackImage.style.top) + centerBackImage.height / 2);//$(centerBackImage).offset().top + centerBackImage.height / 2;  // parseInt((parseInt(bottomRightBackImage.style.top) + bottomRightBackImage.height - parseInt(topLeftBackImage.style.top)) / 2); //parseInt(this._height) / 2;
                    var centerTileLeft = parseInt(parseInt(centerTile.style.left) + centerTile.width / 2);
                    var centerTileTop = parseInt(parseInt(centerTile.style.top) + centerTile.height / 2);
                    var dx = 0;
                    var dy = 0;
                    var ZoomPlusSim = parseInt(this._tileArray2[1][1].width * ZoomPlusFactor); //20; //parseInt(this._tileArray2[1][1].width * ZoomPlusFactor);
                    var ZoomMinusSim = parseInt(this._tileArray2[1][1].width * ZoomMinusFactor); //20; //parseInt(this._tileArray2[1][1].width * ZoomMinusFactor);
                    var Sim; //Величина сжатия или растяжения картинки относительтно исходной в пикселях
                    var centerLeft = parseInt(parseInt(this._width) / 2);
                    var centerTop = parseInt(parseInt(this._height) / 2);


                    if (zoomMode == ZoomPlusWheelMode || zoomMode == ZoomMinusWheelMode) {
                        mousePos = this._lastMousePosOnWheel;
                        var offset = $(this._mapControl).offset(); //$("#map").offset();
                        var MapLeft = offset.left;
                        var MapTop = offset.top;
                        var MapClickX = mousePos.x - MapLeft;
                        var MapClickY = mousePos.y - MapTop;
                        var mCenterX = this["_width"] / 2;
                        var mCenterY = this["_height"] / 2;
                        var MapDeltaX = MapClickX - mCenterX;
                        var MapDeltaY = MapClickY - mCenterY;
                        this._loadedTilesCount = 0;

                        var tileHeight = this._tileArray2[1][1].height;
                        var tileWidth = this._tileArray2[1][1].width;

                        if (zoomMode == ZoomPlusWheelMode) {
                            Sim = ZoomPlusSim;
                        }

                        else {
                            Sim = -ZoomMinusSim;

                        }

                        var factor = (centerBackImage.width + 2 * Sim) / centerBackImage.width + 0.01;
                        // if (zoomMode == ZoomPlusWheelMode)
                        //     factor = ZoomPlusFactor;
                        // else
                        //   factor = ZoomMinusFactor;


                        is = Math.floor(this._tileCountY / 2);
                        js = Math.floor(this._tileCountX / 2);
                        var deltaX = centerBackImageLeft - MapClickX; //centerBackImageLeft - MapClickX;
                        var deltaY = centerBackImageTop - MapClickY; //centerBackImageTop - MapClickY
                        dx = parseInt(deltaX * factor - deltaX); //ZoomPlusSim; //parseInt(deltaX * factor);
                        dy = parseInt(deltaY * factor - deltaY); //ZoomPlusSim; //parseInt(deltaY * factor);
                        //is = Math.floor(mousePos.y / tileHeight);
                        //js = Math.floor(mousePos.x / tileWidth) + 1;


                        //                         if (zoomMode == ZoomPlusWheelMode) {
                        //                             Sim = ZoomPlusSim;
                        //                         }

                        //                         else {
                        //                             Sim = -ZoomMinusSim;
                        //                             
                        //                         }


                    }
                    else
                        if (zoomMode == ZoomPlusMode || zoomMode == ZoomMinusMode) {
                        var mCenterX = this["_width"] / 2;
                        var mCenterY = this["_height"] / 2;
                        //if (zoomMode == ZoomPlusMode)
                        //    factor = ZoomPlusFactor;
                        //else
                        //   factor = ZoomMinusFactor;
                        this._loadedTilesCount = 0;

                        //dx = 0; //ZoomPlusSim;
                        //dy = 0; //ZoomPlusSim;
                        if (zoomMode == ZoomPlusMode) {
                            Sim = ZoomPlusSim;
                        }

                        else {
                            Sim = -ZoomMinusSim;

                        }

                        var factor = (centerBackImage.width + 2 * Sim) / centerBackImage.width + 0.01;

                        var deltaX = centerBackImageLeft - mCenterX; //centerBackImageLeft - MapClickX;
                        var deltaY = centerBackImageTop - mCenterY; //centerBackImageTop - MapClickY
                        dx = parseInt(deltaX * factor - deltaX); //ZoomPlusSim; //parseInt(deltaX * factor);
                        dy = parseInt(deltaY * factor - deltaY);

                    }


                    if (this.CheckScaleBackImagesPossibility(Sim) && this._tilesWasLoaded) {
                        //this._tilesContainer.style.display = "none";
                        //this.ScaleBackImages(Sim, dx, dy);
                        //this.CorrectBackTilesZoom_(ic, jc, Sim);
                        //this._tilesContainer2.style.display = "block";
                        this.animate(Sim, dx, dy, ic, jc, 3);

                    }



                }
                else {
                    this._tilesContainer2.style.display = "none";



                }

                this.UpdateMap(zoomMode);
                if (this["_controlsAreVisible"]) {
                    this._UpdateZoomLineBlock();
                };

            };

        };
        this["GetZoom"] = function(zoomMode) {
            return this["_z"];
        };
        this["ZoomPlus"] = function(zoomMode) {
            var CurrZoom = this["_z"];
            CurrZoom--;
            this.SetZoom(CurrZoom, zoomMode);
        };
        this["ZoomMinus"] = function(zoomMode) {
            var CurrZoom = this["_z"];
            CurrZoom++;
            this.SetZoom(CurrZoom, zoomMode);
        };
        this["_toolControls"] = document["createElement"]("DIV");
        this["_controls"] = document["createElement"]("DIV");
        this["_controlsAreVisible"] = false;
        this["ShowControls"] = function() {
            if (this["_controlsAreVisible"]) {
                return;
            };
            this.AddChild(this._toolControls); //
            this._toolControls.style.cssText = ToolControlsStyle;
            
            this.AddChild(this._controls);
            this["_controls"]["style"]["cssText"] = ControlsStyle;
            this["_upArrowControl"] = document["createElement"]("DIV");
            this["_upArrowControl"]["style"]["cssText"] = UpArrowStyle;
            img = document["createElement"]("IMG");
            img["_onclick"] = this["MoveUp"];
            img["_owner"] = this;
            img["onclick"] = function() {
                this["_onclick"]["call"](this._owner, arguments);
            };
            img["ondblclick"] = function(e) {
                var event = window["event"] || e;
                event["cancelBubble"] = true;
            };
            img["onmousemove"] = function(e) {
                var event = window["event"] || e;
                event["cancelBubble"] = true;
            };
            img["onmousedown"] = function(e) {
                var event = window["event"] || e;
                event["cancelBubble"] = true;
            };
            img["src"] = UpArrowImagePath;
            img["alt"] = UpArrowAltName;
            this["_upArrowControl"]["appendChild"](img);
            this["_controls"]["appendChild"](this._upArrowControl);
            this["_downArrowControl"] = document["createElement"]("DIV");
            this["_downArrowControl"]["style"]["cssText"] = DownArrowStyle;
            img = document["createElement"]("IMG");
            img["_onclick"] = this["MoveDown"];
            img["_owner"] = this;
            img["onclick"] = function() {
                this["_onclick"]["call"](this._owner, arguments);
            };
            img["ondblclick"] = function(e) {
                var event = window["event"] || e;
                event["cancelBubble"] = true;
            };
            img["onmousemove"] = function(e) {
                var event = window["event"] || e;
                event["cancelBubble"] = true;
            };
            img["onmousedown"] = function(e) {
                var event = window["event"] || e;
                event["cancelBubble"] = true;
            };
            img["src"] = DownArrowImagePath;
            img["alt"] = DownArrowAltName;
            this["_downArrowControl"]["appendChild"](img);
            this["_controls"]["appendChild"](this._downArrowControl);
            this["_leftArrowControl"] = document["createElement"]("DIV");
            this["_leftArrowControl"]["style"]["cssText"] = LeftArrowStyle;
            img = document["createElement"]("IMG");
            img["_onclick"] = this["MoveLeft"];
            img["_owner"] = this;
            img["onclick"] = function() {
                this["_onclick"]["call"](this._owner, arguments);
            };
            img["ondblclick"] = function(e) {
                var event = window["event"] || e;
                event["cancelBubble"] = true;
            };
            img["onmousemove"] = function(e) {
                var event = window["event"] || e;
                event["cancelBubble"] = true;
            };
            img["onmousedown"] = function(e) {
                var event = window["event"] || e;
                event["cancelBubble"] = true;
            };

            //-------
            this._footerControl = document["createElement"]("DIV");
            this._footerControl.style.cssText = MapFooterStyle;
            this._footerControl.innerHTML = MapFooterText;

            this._mapControl.appendChild(this._footerControl);
            //-------

            //-------
            this._logoControl = document["createElement"]("DIV");
            this._logoControl.style.cssText = MapLogoStyle;
            this._logoControl.innerHTML = MapLogoText;
            
            this._mapControl.appendChild(this._logoControl);
            //-------

            img["src"] = LeftArrowImagePath;
            img["alt"] = LeftArrowAltName;
            this["_leftArrowControl"]["appendChild"](img);
            this["_controls"]["appendChild"](this._leftArrowControl);
            this["_rightArrowControl"] = document["createElement"]("DIV");
            this["_rightArrowControl"]["style"]["cssText"] = RightArrowStyle;
            img = document["createElement"]("IMG");
            img["_onclick"] = this["MoveRight"];
            img["_owner"] = this;
            img["onclick"] = function() {
                this["_onclick"]["call"](this._owner, arguments);
            };
            img["ondblclick"] = function(e) {
                var event = window["event"] || e;
                event["cancelBubble"] = true;
            };
            img["onmousemove"] = function(e) {
                var event = window["event"] || e;
                event["cancelBubble"] = true;
            };
            img["onmousedown"] = function(e) {
                var event = window["event"] || e;
                event["cancelBubble"] = true;
            };
            img["src"] = RightArrowImagePath;
            img["alt"] = RightArrowAltName;
            this["_rightArrowControl"]["appendChild"](img);
            this["_controls"]["appendChild"](this._rightArrowControl);
            this["_scaleControl"] = document["createElement"]("DIV");
            this["_scaleControl"]["style"]["cssText"] = ScaleStyle;
            img = document["createElement"]("IMG");
            img["_onclick"] = function(e) {
                this.DisableAllTools();
                this["StartScale"];
            }
            img["_owner"] = this;
            img["onclick"] = function(e) {
                //this["_onclick"]["call"](this._owner, arguments);
                //this._onclick(e);
                this._owner.DisableAllTools();
                this._owner.StartScale();
            };
            img["ondblclick"] = function(e) {
                var event = window["event"] || e;
                event["cancelBubble"] = true;
            };
            img["onmousemove"] = function(e) {
                var event = window["event"] || e;
                event["cancelBubble"] = true;
            };
            img["onmousedown"] = function(e) {
                var event = window["event"] || e;
                event["cancelBubble"] = true;
            };
            img["src"] = ScaleImagePath;
            img["alt"] = ScaleAltName;
            this["_scaleControl"]["appendChild"](img);
            this["_toolControls"]["appendChild"](this._scaleControl);
            this["_zoomPlusControl"] = document["createElement"]("DIV");
            this["_zoomPlusControl"]["style"]["cssText"] = ZoomPlusStyle;
            img = document["createElement"]("IMG");
            //img["_onclick"] = this.ZoomPlus; //this["ZoomPlus"];
            img["_owner"] = this;
            img["onclick"] = function() {
                //this["_onclick"]["call"](this._owner, arguments);
                this._owner.ZoomPlus(ZoomPlusMode)
            };
            img["ondblclick"] = function(e) {
                var event = window["event"] || e;
                event["cancelBubble"] = true;
            };
            img["onmousemove"] = function(e) {
                var event = window["event"] || e;
                event["cancelBubble"] = true;
            };
            img["onmousedown"] = function(e) {
                var event = window["event"] || e;
                event["cancelBubble"] = true;
            };
            img["src"] = ZoomPlusImagePath;
            img["alt"] = ZoomPlusAltName;
            this["_zoomPlusControl"]["appendChild"](img);
            this["_controls"]["appendChild"](this._zoomPlusControl);
            this["_zoomMinusControl"] = document["createElement"]("DIV");
            this["_zoomMinusControl"]["style"]["cssText"] = ZoomMinusStyle;
            img = document["createElement"]("IMG");
            // img["_onclick"] = this.ZoomMinus(ZoomMinusMode); //this["ZoomMinus"];
            img["_owner"] = this;
            img["onclick"] = function() {
                //this["_onclick"]["call"](this._owner, arguments);
                this._owner.ZoomMinus(ZoomMinusMode)
            };
            img["onmousemove"] = function(e) {
                var event = window["event"] || e;
                event["cancelBubble"] = true;
            };
            img["onmousedown"] = function(e) {
                var event = window["event"] || e;
                event["cancelBubble"] = true;
            };
            img["ondblclick"] = function(e) {
                var event = window["event"] || e;
                event["cancelBubble"] = true;
            };
            img["src"] = ZoomMinusImagePath;
            img["alt"] = ZoomMinusAltName;
            this["_zoomMinusControl"]["appendChild"](img);
            this["_controls"]["appendChild"](this._zoomMinusControl);
            this["_UpdateZoomLineBlock"] = function() {
                this["_zoomLineControlBlock"]["style"]["top"] = (this.GetZoom() - MIN_ZOOM_LEVEL) * (Math["floor"](parseInt(this["_zoomLineControl"]["style"]["height"]) - 9) / (MAX_ZOOM_LEVEL - MIN_ZOOM_LEVEL)) + "px";
            };
            this["_OnLineZoom"] = function(e) {
                var obj = getAbsolutePos(this._zoomLineControl);
                var mousePos = mousePageXY(e);
                var ny = mousePos["y"] - obj["y"];
                var newZoom = MIN_ZOOM_LEVEL + Math["floor"](ny * (MAX_ZOOM_LEVEL + 1 - MIN_ZOOM_LEVEL) / (parseInt(this["_zoomLineControl"]["style"]["height"])));
                this.SetZoom(newZoom);
            };
            this["_zoomLineControl"] = document["createElement"]("DIV");
            this["_zoomLineControl"]["style"]["cssText"] = ZoomLineStyle;
            img = document["createElement"]("IMG");
            img["_onclick"] = function(e) {
                this._OnLineZoom(e);
            };
            img["_owner"] = this;
            img["onclick"] = function(e) {
                this["_onclick"]["call"](this._owner, e);
            };
            img["src"] = ZoomLineImagePath;
            img["style"]["height"] = this["_zoomLineControl"]["style"]["height"];
            img["style"]["width"] = this["_zoomLineControl"]["style"]["width"];
            img["ondblclick"] = function(e) {
                var event = window["event"] || e;
                event["cancelBubble"] = true;
            };
            img["onmousemove"] = function(e) { };
            img["onmousedown"] = function(e) {
                var event = window["event"] || e;
                event["cancelBubble"] = true;
            };
            this["_zoomLineControl"]["appendChild"](img);

            //
            this["_noneToolControl"] = document["createElement"]("DIV");
            this["_noneToolControl"]["style"]["cssText"] = NoneToolStyle;
            img = document["createElement"]("IMG");
            img["_owner"] = this;
            img["src"] = NoneToolActiveImagePath;
            img["alt"] = NoneToolAltName;
            img["style"]["height"] = this["_noneToolControl"]["style"]["height"];
            img["style"]["width"] = this["_noneToolControl"]["style"]["width"];
            img["onclick"] = function(e) {
                var event = window["event"] || e;
                this._owner.DisableAllTools();
                this._owner.EnableNoneTool();
                event["cancelBubble"] = true;
            };
            img["onmousemove"] = function(e) {
                var event = window["event"] || e;
                event["cancelBubble"] = true;
            };
            img["onmousedown"] = function(e) {
                var event = window["event"] || e;
                event["cancelBubble"] = true;
            };
            img["ondblclick"] = function(e) {
                var event = window["event"] || e;
                event["cancelBubble"] = true;
            };
            this["_noneToolControl"]["appendChild"](img);
            this["_toolControls"]["appendChild"](this._noneToolControl); //
            //
            if (this["_canvas"]) {

                this["_routeControl"] = document["createElement"]("DIV");
                this["_routeControl"]["style"]["cssText"] = RouteStyle;
                img = document["createElement"]("IMG");
                img["_owner"] = this;
                img["src"] = RouteImagePath;
                img["alt"] = RouteAltName;
                img["style"]["height"] = this["_routeControl"]["style"]["height"];
                img["style"]["width"] = this["_routeControl"]["style"]["width"];
                img["onclick"] = function(e) {
                    var event = window["event"] || e;
                    this._owner.DisableAllTools();
                    //this._owner.SwitchRoute();
                    this._owner.EnableRouteTool();
                    event["cancelBubble"] = true;
                };
                img["onmousemove"] = function(e) {
                    var event = window["event"] || e;
                    event["cancelBubble"] = true;
                };
                img["onmousedown"] = function(e) {
                    var event = window["event"] || e;
                    event["cancelBubble"] = true;
                };
                img["ondblclick"] = function(e) {
                    var event = window["event"] || e;
                    event["cancelBubble"] = true;
                };

                this["_isRouteMode"] = false;
                this["_routeControl"]["appendChild"](img);

                //--
                var byTimeCheckBox = document.createElement("checkbox");
                byTimeCheckBox["id"] = "bytime";
                byTimeCheckBox["checked"] = "true";
                byTimeCheckBox["style"]["display"] = "none";
                this["_routeControl"]["appendChild"](byTimeCheckBox);

                imgByTime = document["createElement"]("IMG");
                imgByTime["id"] = "imgByTime";
                imgByTime["_owner"] = this;
                imgByTime["src"] = RouteByTimeActiveImagePath;
                imgByTime["alt"] = RouteByTimeAltName;
                imgByTime["style"]["height"] = this["_routeControl"]["style"]["height"];
                imgByTime["style"]["width"] = this["_routeControl"]["style"]["width"];
                imgByTime["style"]["display"] = "none";
                imgByTime["onclick"] = function(e) {
                    var event = window["event"] || e;
                    if (!document.getElementById("bytime")["checked"]) {
                        imgByTime["src"] = RouteByTimeActiveImagePath;
                        imgByLength["src"] = RouteByLengthImagePath;
                        document.getElementById("bytime")["checked"] = true;

                        if (map._startPoint && map._finishPoint) {
                            var opt = 1;
                            map._jg.clear();
                            FindRoute(map._startPoint, map._finishPoint, opt, map._onFindRoute);
                        }
                    }
                    event["cancelBubble"] = true;

                };
                imgByTime["onmousemove"] = function(e) {
                    var event = window["event"] || e;
                    event["cancelBubble"] = true;
                };
                imgByTime["onmousedown"] = function(e) {
                    var event = window["event"] || e;
                    event["cancelBubble"] = true;
                };
                imgByTime["ondblclick"] = function(e) {
                    var event = window["event"] || e;
                    event["cancelBubble"] = true;
                };
                this["_routeControl"]["appendChild"](imgByTime);

                imgByLength = document["createElement"]("IMG");
                imgByLength["id"] = "imgByLength";
                imgByLength["_owner"] = this;
                imgByLength["src"] = RouteByLengthImagePath;
                imgByLength["alt"] = RouteByLengthAltName;
                imgByLength["style"]["height"] = this["_routeControl"]["style"]["height"];
                imgByLength["style"]["width"] = this["_routeControl"]["style"]["width"];
                imgByLength["style"]["display"] = "none";
                imgByLength["onclick"] = function() {
                    if (document.getElementById("bytime")["checked"]) {
                        imgByLength["src"] = RouteByLengthActiveImagePath;
                        imgByTime["src"] = RouteByTimeImagePath;
                        document.getElementById("bytime")["checked"] = false;
                        if (map._startPoint && map._finishPoint) {
                            var opt = 0;
                            map._jg.clear();
                            FindRoute(map._startPoint, map._finishPoint, opt, map._onFindRoute);

                        }
                    }

                };
                imgByLength["onmousemove"] = function(e) {
                    var event = window["event"] || e;
                    event["cancelBubble"] = true;
                };
                imgByLength["onmousedown"] = function(e) {
                    var event = window["event"] || e;
                    event["cancelBubble"] = true;
                };
                imgByLength["ondblclick"] = function(e) {
                    var event = window["event"] || e;
                    event["cancelBubble"] = true;
                };
                this["_routeControl"]["appendChild"](imgByLength);

                //--

                this["_toolControls"]["appendChild"](this._routeControl);//

            }
            //
            this["_infoControl"] = document["createElement"]("DIV");
            this["_infoControl"]["style"]["cssText"] = InfoStyle;
            img = document["createElement"]("IMG");
            img["_owner"] = this;
            img["src"] = InfoImagePath;
            img["alt"] = InfoAltName;
            img["onclick"] = function(e) {
                window.open('http://kissa.pro/#LegendTool', '_blank');
                event["cancelBubble"] = true;
            };
            img["onmousemove"] = function(e) {
                var event = window["event"] || e;
                event["cancelBubble"] = true;
            };
            img["onmousedown"] = function(e) {
                var event = window["event"] || e;
                event["cancelBubble"] = true;
            };
            img["ondblclick"] = function(e) {
                var event = window["event"] || e;
                event["cancelBubble"] = true;
            };
            this["_infoControl"]["appendChild"](img);
            this["_toolControls"]["appendChild"](this._infoControl);
            //

            this["_controls_startY"] = 0;
            this["_controls_currY"] = 0;
            this["_controls_fixY"] = 0;
            this["_controls_isDragging"] = false;
            this["_controls_startDrag"] = function(e) {
                var event = window.event || e;
                if (event["preventDefault"]) event["preventDefault"]();
                this["_controls_startY"] = mousePageXY(e)["y"];
                this["_controls_currY"] = mousePageXY(e)["y"];
                this["_controls_isDragging"] = true;
                this["_controls_fixY"] = parseInt(this["_zoomLineControlBlock"]["style"]["top"]);
            };
            this["_controls_drag"] = function(e) {
                if (this["_controls_isDragging"]) {
                    this["_controls_currY"] = mousePageXY(e)["y"];
                    var ny = this["_controls_fixY"] + this["_controls_currY"] - this["_controls_startY"];
                    if ((ny >= 0) && (ny <= parseInt(this["_zoomLineControl"]["style"]["height"]) - parseInt(this["_zoomLineControlBlock"]["style"]["height"]))) {
                        this["_zoomLineControlBlock"]["style"]["top"] = ny + "px";
                    };
                };
            };
            this["_controls_enddrag"] = function(e) {
                if (this["_controls_isDragging"]) {
                    this["_controls_isDragging"] = false;
                    var y = parseInt(this["_zoomLineControlBlock"]["style"]["top"]);
                    var height = parseInt(this["_zoomLineControlBlock"]["style"]["height"]);
                    var newZoom = MIN_ZOOM_LEVEL + Math["floor"](y + height / 2) * (MAX_ZOOM_LEVEL + 1 - MIN_ZOOM_LEVEL) / (parseInt(this["_zoomLineControl"]["style"]["height"]));
                    this.SetZoom(newZoom);
                };
            };
            this["_zoomLineControlBlock"] = document["createElement"]("DIV");
            this["_zoomLineControlBlock"]["style"]["cssText"] = ZoomLineBlockStyle;
            img = document["createElement"]("IMG");
            img["_onclick"] = function() {
                return true;
            };
            img["_owner"] = this;
            img["onclick"] = function() {
                this["_onclick"]["call"](this._owner, arguments);
            };
            img["src"] = ZoomLineBlockImagePath;
            img["galleryImg"] = false;
            img["unselectable"] = true;
            img["style"]["height"] = this["_zoomLineControlBlock"]["style"]["height"];
            img["style"]["width"] = this["_zoomLineControlBlock"]["style"]["width"];
            img["ondblclick"] = function(e) {
                var event = window["event"] || e;
                event["cancelBubble"] = true;
            };
            img["_onmousedown"] = function(e) {
                this._controls_startDrag(e);
            };
            img["onmousedown"] = function(e) {
                this["_onmousedown"]["call"](this._owner, e);
                var event = window["event"] || e;
                event["cancelBubble"] = true;
            };
            this["_zoomLineControlBlock"]["appendChild"](img);
            this["_zoomLineControl"]["appendChild"](this._zoomLineControlBlock);
            this["_controls"]["appendChild"](this._zoomLineControl);
            this._UpdateZoomLineBlock();
            this["_controlsAreVisible"] = true;
        };
        this["HideControls"] = function() {
            this["_mapControl"]["removeChild"](this._controls);
            this["_controlsAreVisible"] = false;
        };

        this["EnableNoneTool"] = function() {
            var img = this._noneToolControl.firstChild;
            img.src = NoneToolActiveImagePath;
            this["_mapControl"]["style"]["cursor"] = "url(" + CursorOpenHand + ")";
        }
        
        this["DisableNoneTool"] = function() {
            var img = this._noneToolControl.firstChild;
            img.src = NoneToolImagePath;
        }

        this["EnableRouteTool"] = function() {
            if (this._canvas) {
                this["_isRouteMode"] = true;
                var img = this._routeControl.firstChild;
                var imgByLength = document.getElementById("imgByLength");
                imgByLength["style"]["display"] = "block";
                var imgByTime = document.getElementById("imgByTime");
                imgByTime["style"]["display"] = "block";
                img.src = AltRouteImagePath;
            }
        }



        this["DisableRouteTool"] = function() {
            if (this._canvas) {
                this["_isRouteMode"] = false;
                var img = this._routeControl.firstChild;
                this.ClearRoute();
                var imgByLength = document.getElementById("imgByLength");
                imgByLength["style"]["display"] = "none";
                var imgByTime = document.getElementById("imgByTime");
                imgByTime["style"]["display"] = "none";
                img.src = RouteImagePath;
            }
        }

        this["DisableAllTools"] = function() {
            this["_mapControl"]["style"]["cursor"] = "default";
            this.DisableNoneTool();
            this.DisableScaleTool();
            this.DisableRouteTool();   
        }

        this["SwitchRoute"] = function() {
            //img["src"] = (this._isRouteMode) ? RouteImagePath : AltRouteImagePath;
            //this["_isRouteMode"] = !this._isRouteMode;
            if (!this._isRouteMode) {
                //                var img = this._routeControl.firstChild;
                //                this.ClearRoute();
                //                var imgByLength = document.getElementById("imgByLength");
                //                imgByLength["style"]["display"] = "none";
                //                var imgByTime = document.getElementById("imgByTime");
                //                imgByTime["style"]["display"] = "none";
                //                img.src = RouteImagePath;
                this.DisableRouteTool();
            }
                 else {
                //                var img = this._routeControl.firstChild;
                //                var imgByLength = document.getElementById("imgByLength");
                //                imgByLength["style"]["display"] = "block";
                //                var imgByTime = document.getElementById("imgByTime");
                //                imgByTime["style"]["display"] = "block";
                //                img.src = AltRouteImagePath;
                this.EnableRouteTool();
            }
        }
        
        this["SetControlsPosition"] = function(x, y) {
            if (this["_controlsAreVisible"]) {
                with (this["_controls"]["style"]) {
                    left = parseInt(x);
                    top = parseInt(y);
                };
            };
        };
        this["X2left"] = function (x) {
            return ((this.GetWidth() / 2) + (x - this.GetMapCenter()["x"]) / kWinToMap[this.GetZoom()]);
        };
        this["Y2top"] = function (y) {
            return ((this.GetHeight() / 2) - (y - this.GetMapCenter()["y"]) / kWinToMap[this.GetZoom()]);
        };
        this["ondblclick"] = function(mouseX, mouseY) {
            if (this["_scaleStarted"] != 0) {
                this.AddLineMarker(mouseX, mouseY, "");
                this["_lineMarkers"][this["_lineMarkerIndex"] - 1].SetDescription(Math["round"](this._GetLineMarkerDistance(0, this["_lineMarkerIndex"] - 1) * 100) / 100 + "\x26nbsp;м");
                this["_scaleStarted"]++;
            } else {
                if (this._isRouteMode) {
                    if (this["_startPoint"] && this["_finishPoint"]) {
                        this.ClearRoute();
                    }
                    if (this["_startPoint"]) {
                        this["_finishPoint"] = new Object();
                        this["_finishPoint"]["X"] = mouseX;
                        this["_finishPoint"]["Y"] = mouseY;
                        this.AddFinishRouteMarker(mouseX, mouseY, "Конец маршрута");
                        var opt = 0;
                        if (document.getElementById("bytime")["checked"])
                            opt = 1;
                        FindRoute(this._startPoint, this._finishPoint, opt, this._onFindRoute);

                    } else {
                        this["_startPoint"] = new Object();
                        this["_startPoint"]["X"] = mouseX;
                        this["_startPoint"]["Y"] = mouseY;
                        this.AddStartRouteMarker(mouseX, mouseY, "Начало маршрута");
                    }
                } else {
                this.ZoomPlus();
                }
            };
            return true;
        };
        this["SetRoute"] = function (route) {
            this["_route"] = route;
        };
        this["UpdateRouteLayer"] = function() {
            if (this["_isRouteMode"]) {
                this._jg.clear();
                if (this["_startRouteMarker"]) this["_startRouteMarker"].UpdateMarker();
                if (this["_finishRouteMarker"]) this["_finishRouteMarker"].UpdateMarker();
                if (this["_route"]) {
                    for (j = 0; j < this._route.lines.length; j++) {
                        var line = this._route.lines[j];
                        for (i = 0; i < line.points.length - 1; i++) {
                            var ax = line.points[i].X;
                            var ay = line.points[i].Y;
                            var bx = line.points[i + 1].X;
                            var by = line.points[i + 1].Y;
                            if (this.IsPointInMapRect(ax, ay) || this.IsPointInMapRect(bx, by))
                                this._jg.drawLine(map.X2left(ax), map.Y2top(ay), map.X2left(bx), map.Y2top(by));
                        }
                    }
                    this._jg.paint();
                }
            }
        };
        this["RecalcRoute"] = function() {
            var opt = 0;
            if (document.getElementById("bytime")["checked"])
                opt = 1;
            map._jg.clear();
            FindRoute(map._startPoint, map._finishPoint, opt, map._onFindRoute);
        };
//       var radio = document.getElementById("bytime");
//       radio["onclick"] = this.RecalcRoute;
//        radio = document.getElementById("bylength");
//       radio["onclick"] = this.RecalcRoute;
        
        this["ClearRoute"] = function () {
            this._jg.clear();
            delete this["_route"];
            this["_startPoint"] = null;
            this["_finishPoint"] = null;
            if (this["_startRouteMarker"]) this["_startRouteMarker"].UnloadMarker();
            delete this["_startRouteMarker"];
            if (this["_finishRouteMarker"]) this["_finishRouteMarker"].UnloadMarker();
            delete this["_finishRouteMarker"];
        };
        this["AddStartRouteMarker"] = function (X, Y, description) {
            this["_startRouteMarker"] = new Marker(this, 0, X, Y, RouteStartImagePath, description, false, true, LINE_MARKER_SHIFT_X, LINE_MARKER_SHIFT_Y);
            this["_startRouteMarker"].UpdateMarker();
        };
        this["AddFinishRouteMarker"] = function (X, Y, description) {
            this["_finishRouteMarker"] = new Marker(this, 1, X, Y, RouteFinishImagePath, description, false, true, LINE_MARKER_SHIFT_X, LINE_MARKER_SHIFT_Y);
            this["_finishRouteMarker"].UpdateMarker();
        };
        this["_onFindRoute"] = function(route) {
            map.SetRoute(route);
            for (j = 0; j < route.lines.length; j++) {
                var line = route.lines[j];
                for (i = 0; i < line.points.length - 1; i++) {
                    var ax = line.points[i].X;
                    var ay = line.points[i].Y;
                    var bx = line.points[i + 1].X;
                    var by = line.points[i + 1].Y;
                    if (map.IsPointInMapRect(ax, ay) || map.IsPointInMapRect(bx, by))
                        map._jg.drawLine(map.X2left(ax), map.Y2top(ay), map.X2left(bx), map.Y2top(by));
                }
            }
            map._jg.paint();
            //            var info = document.getElementById("routeInfo");
            //            var length = parseFloat(route.length);
            //            if (length > 1000) {
            //                info.innerHTML = "<b>Длина маршрута:</b> " + Math.round(length / 10) / 100 + " км";
            //            } else {
            //                info.innerHTML = "<b>Длина маршрута:</b> " + Math.round(length) + " м";
            //            }

            var length = parseFloat(route.length);
            var strLength;
            if (length > 1000) {
                strLength = "Конец маршрута: " + Math.round(length / 10) / 100 + " км";
            } else {
            strLength = "Конец маршрута: " + Math.round(length) + " м";
            }

            map._finishRouteMarker.SetDescription(strLength);
            //map._finishRouteMarker._showTitle = true;

        };        
        this["_mapControl"]["_ondblclick"] = function(e) {
            var mapCoord = this._GetMouseXYOnMap(e);
            //this["ondblclick"](mapCoord["x"], mapCoord["y"]);
        };
        this["_onNavigatorClick"] = function(e) {
            /*
            var mousePos = mousePageXY(e);
            var MapLeft = parseInt(this["_mapControl"]["offsetLeft"]);
            var MapTop = parseInt(this["_mapControl"]["offsetTop"]);
            var NavLeft = parseInt(this["_navigator"]["offsetLeft"]);
            var NavTop = parseInt(this["_navigator"]["offsetTop"]);
            var MapClickX = mousePos["x"] - MapLeft - NavLeft;
            var MapClickY = mousePos["y"] - MapTop - NavTop;
            */

            //document.getElementById("container")["style"]["border"] = "1 solid red";
            //alert(this["_mapControl"]["offsetParent"]["outerHTML"]);
            //alert(window["event"]["offsetX"] + "\r\n" + window["event"]["offsetY"]);
            //alert(e);
            if (!e)
                e = window["event"];

            var offX;
            var offY;
            if (!e.offsetX || !e.offsetY) {
                offX = e.layerX - $(e.target).position().left;
                offY = e.layerY - $(e.target).position().top;
            }

            else {
                offX = e.offsetX;
                offY = e.offsetY;
            }

            //var MapClickX = e["offsetX"];
            //var MapClickY = e["offsetY"];
            var MapClickX = offX;
            var MapClickY = offY;

            var mapPointX = mapCorner1X + MapClickX * (mapCorner2X - mapCorner1X) / parseInt(this["_navigator"]["style"]["width"]);
            var mapPointY = mapCorner2Y - MapClickY * (mapCorner2Y - mapCorner1Y) / parseInt(this["_navigator"]["style"]["height"]);
            this._tilesContainer2.style.display = "none"; 
            this.SetMapCenter(mapPointX, mapPointY);
            this._NavigatorUpdateCross();
        };
        this["_NavigatorUpdateCross"] = function() {
            if (this["_navigatorIsVisible"]) {
                var center = this.GetMapCenter();
                var navX = parseInt(this["_navigator"]["style"]["width"]) * (center["x"] - mapCorner1X) / (mapCorner2X - mapCorner1X);
                var navY = -parseInt(this["_navigator"]["style"]["height"]) * (center["y"] - mapCorner2Y) / (mapCorner2Y - mapCorner1Y);
                this["_navcross"]["style"]["left"] = navX - parseInt(this["_navcross"]["style"]["width"]) / 2 + "px";
                this["_navcross"]["style"]["top"] = navY - parseInt(this["_navcross"]["style"]["height"]) / 2 + "px";
            };
        };
        this["_NavigatorUpdateRect"] = function() {
            if (this["_navigatorIsVisible"]) {
                if (this.GetZoom() < NAVRECT_TO_NAVCROSS_ZOOM) {
                    this["_navcross"]["style"]["display"] = "block";
                    this["_navrect"]["style"]["display"] = "none";
                } else {
                    this["_navcross"]["style"]["display"] = "none";
                    this["_navrect"]["style"]["display"] = "block";
                };
                var rect = this.GetCurrentMapRect();
                var navX1 = parseInt(this["_navigator"]["style"]["width"]) * (rect["Left"] - mapCorner1X) / (mapCorner2X - mapCorner1X);
                var navY1 = -parseInt(this["_navigator"]["style"]["height"]) * (rect["Top"] - mapCorner2Y) / (mapCorner2Y - mapCorner1Y);
                var navX2 = parseInt(this["_navigator"]["style"]["width"]) * (rect["Right"] - mapCorner1X) / (mapCorner2X - mapCorner1X);
                var navY2 = -parseInt(this["_navigator"]["style"]["height"]) * (rect["Bottom"] - mapCorner2Y) / (mapCorner2Y - mapCorner1Y);
                this["_navrect"]["style"]["left"] = navX1 + "px";
                this["_navrect"]["style"]["top"] = navY1 + "px";
                this["_navrect"]["style"]["width"] = Math["round"](navX2 - navX1) + "px";
                this["_navrect"]["style"]["height"] = Math["round"](navY2 - navY1) + "px";
            };
        };
        this["_navigator"] = document["createElement"]("DIV");
        this["_navigatorIsVisible"] = false;
        this["ShowNavigator"] = function() {
            if (this["_navigatorIsVisible"]) {
                return;
            };
            this.AddChild(this._navigator);
            this["_navigator"]["style"]["cssText"] = NavigatorStyle;
            this["_navmap"] = document["createElement"]("DIV");
            img = document["createElement"]("IMG");
            img["_onclick"] = function(e) {
                this._onNavigatorClick(e);
                this._NavigatorUpdateRect();
            };
            img["_owner"] = this;
            img["onclick"] = function(e) {
                this["_onclick"]["call"](this._owner, e);
            };
            img["ondblclick"] = function(e) {
                var event = window["event"] || e;
                event["cancelBubble"] = true;
            };
            img["onmousemove"] = function(e) {
                var event = window["event"] || e;
                event["cancelBubble"] = true;
            };
            img["onmousedown"] = function(e) {
                var event = window["event"] || e;
                event["cancelBubble"] = true;
            };
            img["src"] = NavigatorMapPath;
            img["alt"] = NavigatorMapAltName;
            this["_navmap"]["appendChild"](img);
            this["_navigator"]["appendChild"](this._navmap);
            this["_navcross"] = document["createElement"]("DIV");
            this["_navcross"]["style"]["cssText"] = NavigatorCrossStyle;
            img = document["createElement"]("IMG");
            img["src"] = NavigatorCrossPath;
            this["_navcross"]["appendChild"](img);
            this["_navigator"]["appendChild"](this._navcross);
            this["_navrect"] = document["createElement"]("DIV");
            this["_navrect"]["innerHTML"] = "\x3C!-- --\x3E";
            this["_navrect"]["style"]["cssText"] = NavigatorRectStyle;
            this["_navigator"]["appendChild"](this._navrect);
            this["_navigatorIsVisible"] = true;
            this._NavigatorUpdateCross();
            this._NavigatorUpdateRect();
        };
        this["GetCurrentMapRect"] = function() {
            var Left = this["_mapCenterX"] - (this["_width"] / 2) * kWinToMap[this["_z"]];
            var Right = this["_mapCenterX"] + (this["_width"] / 2) * kWinToMap[this["_z"]];
            var Top = this["_mapCenterY"] + (this["_height"] / 2) * kWinToMap[this["_z"]];
            var Bottom = this["_mapCenterY"] - (this["_height"] / 2) * kWinToMap[this["_z"]];

//           Left = this["_mapCenterX"] - (parseInt(this._mapControl.offsetWidth) / 2) * kWinToMap[this["_z"]];
//           Right = this["_mapCenterX"] + (parseInt(this._mapControl.offsetWidth) / 2) * kWinToMap[this["_z"]];
//           Top = this["_mapCenterY"] + (parseInt(this._mapControl.offsetHeight) / 2) * kWinToMap[this["_z"]];
//           Bottom = this["_mapCenterY"] - (parseInt(this._mapControl.offsetHeight) / 2) * kWinToMap[this["_z"]];
            Rect = new Object();
            Rect["Top"] = Top;
            Rect["Bottom"] = Bottom;
            Rect["Left"] = Left;
            Rect["Right"] = Right;
            return Rect;
        };
        
        this["IsPointInMapRect"] = function(pointX, pointY) {
            var CurrentRect = this.GetCurrentMapRect();
            var InBoundsX = ((CurrentRect["Left"] < pointX) && (pointX < CurrentRect["Right"]));
            var InBoundsY = ((CurrentRect["Bottom"] < pointY) && (pointY < CurrentRect["Top"]));
            return ((InBoundsX) && (InBoundsY));
        };
        this["_markers"] = new Array();
        this["_lineMarkers"] = new Array();
        this["_lineMarkerIndex"] = 0;
        this["_markerIndex"] = 0;
        this["_UpdateLineMarkersDescription"] = function() {
            for (marker in this["_lineMarkers"]) {
                this["_lineMarkers"][marker].SetDescription(Math["round"](this._GetLineMarkerDistance(0, marker) * 100) / 100 + "\x26nbsp;м");
            };
        };
        this["AddMarker"] = function(X, Y, img_path, description, draggable, showTitle) {
            this["_markers"][this["_markerIndex"]] = new Marker(this, this._markerIndex, X, Y, img_path, description, draggable, showTitle);
            this["_markers"][this["_markerIndex"]].UpdateMarker();
            this["_markers"][this["_markerIndex"]]["onEndDrag"] = function(e) {
                var mark = this["_markers"][e];
                if (mark["_isDraggable"]) {
                    var X = mark["_x"];
                    var Y = mark["_y"];
                    var title = mark["_description"];
                    UpdateMarkerPos(X, Y, title);
                }
            };
            this["_markerIndex"]++;
        };
        this["AddLineMarker"] = function(X, Y, description) {
            this["_lineMarkers"][this["_lineMarkerIndex"]] = new Marker(this, this._lineMarkerIndex, X, Y, LINE_MARKER_IMG, description, true, true, LINE_MARKER_SHIFT_X, LINE_MARKER_SHIFT_Y);
            this["_lineMarkers"][this["_lineMarkerIndex"]].UpdateMarker();
            this["_lineMarkers"][this["_lineMarkerIndex"]]["onEndDrag"] = function(e) {
                this.UpdateLineLayer();
                this._UpdateLineMarkersDescription();
            };
            this["_lineMarkers"][this["_lineMarkerIndex"]]["onDrag"] = function(e) {
                this.UpdateLineLayer();
                this._UpdateLineMarkersDescription();
            };
            this["_lineMarkerIndex"]++;
            if (this["_lineMarkerIndex"] > 1) {
                this["_lineArray"][this["_lineMarkerIndex"] - 2] = document["createElement"]("V:LINE");
                this["_lineLayer"]["appendChild"](this["_lineArray"][this["_lineMarkerIndex"] - 2]);
            };
            this.UpdateLineLayer();
        };
        this["UpdateMarkers"] = function() {
            for (marker in this["_markers"]) {
                this["_markers"][marker].UpdateMarker();
            };
        };
        this["UpdateLineMarkers"] = function() {
            for (marker in this["_lineMarkers"]) {
                this["_lineMarkers"][marker].UpdateMarker();
            };
        };
        this["RemoveMarker"] = function(index) {
            this["_markers"][index].UnloadMarker();
            delete this["_markers"][index];
        };
        this["RemoveLineMarker"] = function(index) {
            this["_lineMarkers"][index].UnloadMarker();
            delete this["_lineMarkers"][index];
            this.UpdateLineLayer();
        };
        this["RemoveAllMarkers"] = function() {
            for (marker in this["_markers"]) {
                this["_markers"][marker].UnloadMarker();
                delete this["_markers"][marker];
            };
            this["_markerIndex"] = 0;
        };
        this["RemoveAllLineMarkers"] = function() {
            for (marker in this["_lineMarkers"]) {
                this["_lineMarkers"][marker].UnloadMarker();
                delete this["_lineMarkers"][marker];
            };
            this["_lineMarkerIndex"] = 0;
            this._ClearLineLayer();
        };
        this["_lineLayer"] = document["createElement"]("DIV");
        this["_lineLayer"]["style"]["cssText"] = LineLayerStyle;
        this["_lineArray"] = new Array();
        this["_mapControl"]["appendChild"](this._lineLayer);
        this["UpdateLineLayer"] = function() {
            if ((this["_lineMarkerIndex"] > 1) && (this["_scaleStarted"] != 0)) {
                this._jg.clear(); //
                for (var i = 0; i < this["_lineMarkerIndex"] - 1; i++) {
                    var x1 = parseInt(this["_lineMarkers"][i]["_div"]["style"]["left"]) + parseInt(this["_lineMarkers"][i]["_div"]["clientWidth"]) / 2 + "px";
                    var x2 = parseInt(this["_lineMarkers"][i + 1]["_div"]["style"]["left"]) + parseInt(this["_lineMarkers"][i + 1]["_div"]["clientWidth"]) / 2 + "px";
                    var y1 = parseInt(this["_lineMarkers"][i]["_div"]["style"]["top"]) + parseInt(this["_lineMarkers"][i]["_div"]["clientHeight"]) / 2 + "px";
                    var y2 = parseInt(this["_lineMarkers"][i + 1]["_div"]["style"]["top"]) + parseInt(this["_lineMarkers"][i + 1]["_div"]["clientHeight"]) / 2 + "px";
                    this["_lineArray"][i]["style"]["visibility"] = "hidden";
                    this["_lineArray"][i]["from"] = x1 + "," + y1;
                    this["_lineArray"][i]["to"] = x2 + "," + y2;
                    this["_lineArray"][i]["strokecolor"] = "#123899";
                    this["_lineArray"][i]["strokeweight"] = 2;
                    this["_lineArray"][i]["style"]["visibility"] = "visible";
                    //
                    var ax = this["_lineMarkers"][i]._x;
                    var ay = this["_lineMarkers"][i]._y;
                    var bx = this["_lineMarkers"][i + 1]._x;
                    var by = this["_lineMarkers"][i + 1]._y;
                    if (this.IsPointInMapRect(ax, ay) || this.IsPointInMapRect(bx, by))
                        this._jg.drawLine(map.X2left(ax), map.Y2top(ay), map.X2left(bx), map.Y2top(by));
                    //
                };
                this._jg.paint(); //
            };
            if (this["_isDragging"]) {
                this["_lineLayer"]["style"]["visibility"] = "hidden";
            } else {
                this["_lineLayer"]["style"]["visibility"] = "visible";
            };

        };
        this["_HideLineLayer"] = function() {
            for (var i = 0; i < this["_lineMarkerIndex"] - 1; i++) {
                this["_lineArray"][i]["style"]["visibility"] = "hidden";
            };
        };
        this["_ShowLineLayer"] = function() {
            for (var i = 0; i < this["_lineMarkerIndex"] - 1; i++) {
                this["_lineArray"][i]["style"]["visibility"] = "visible";
            };
        };
        this["_ClearLineLayer"] = function() {
            while (this["_lineLayer"]["childNodes"]["length"] > 0) {
                this["_lineLayer"]["removeChild"](this["_lineLayer"]["firstChild"]);
            };
        };
        this["onmove"] = function() {
            this._NavigatorUpdateCross();
            this._NavigatorUpdateRect();
            this.UpdateMarkers();
            this.UpdateLineMarkers();


            if (this["_canvas"]) {
                this.UpdateRouteLayer();
                this.UpdateLineLayer();
                
            }
        };
        this["OnSetMapList"] = function() {
            return true;
        };
        this["mapList"] = defaultMapList;
        this["mapListString"] = "";
        this["SetMapList"] = function(maplist, notrefresh) {
            var tempList = new Array();
            var maplistArray = maplist.toString().replace(".", "|.").replace("-", "|-").substr(1).split("|");
            for (var i = 0; i < maplistArray.length; i++) {
                tempList[i] = new MapItem(maplistArray[i].substr(1), "", maplistArray[i].substr(0, 1) == "." ? true : false);
            }
            var idx = tempList.length;
            for (var i = 0; i < defaultMapList.length; i++) {
                var b = true;
                for (var j = 0; j < idx; j++) {
                    if (defaultMapList[i].name == tempList[j].name) {
                        b = false;
                        break;
                    }
                }
                if (b) {
                    tempList[idx] = new MapItem(defaultMapList[i].name, "", false);
                    idx++;
                }
            }
            for (var i = 0; i < tempList.length; i++) {
                for (var j = 0; j < defaultMapList.length; j++) {
                    if (tempList[i].name == defaultMapList[j].name) {
                        tempList[i].title = defaultMapList[j].title;
                    }
                }
            }
            this.mapList = tempList;
            this.GenerateMapListString();
            this.UpdateMap();
            if (!notrefresh)
                this.OnSetMapList();
        }
        this["GenerateMapListString"] = function() {
            var res = "";
            for (var i = 0; i < this.mapList.length; i++) {
                res += this.mapList[i].visible ? "." : "-";
                res += this.mapList[i].name;
            }
            this.mapListString = res;
        }
        this.GenerateMapListString();
        this["GetMapList"] = function() {
            return this.mapListString;
        }
    } else {
        alert(ALERT_MAP_CONTROLS_NOT_FOUND);
    };
};

function ExecuteAddressCallback(method, params, success) {
    try {
        $.getJSON(addressUrl + "?method=" + method + "&arg=" + encodeURIComponent(params) + "&callback=?", { info: 'Эти данные отправились на сервер' }, success);
    }
    catch (e) {
        XhttpError();
    }
}
function XhttpError() {
    alert("Ваш браузер не поддерживает эту функцию или установлен высокий уровень настроек безопасности.\nПопробуйте использовать MS Internet Explorer.");
}

function Search(filter, page, success) {
    ExecuteAddressCallback("search", filter + "|" + page, success);
}

function GetStreetsFilter(filter, success) {
    ExecuteAddressCallback("getstreets", filter, success);
}

function GetHouseCoord(houseId, success) {
    ExecuteAddressCallback("gethousecoord", houseId, success);
}

function GetMarkerCoord(houseId, success) {
    ExecuteAddressCallback("getmarkercoord", houseId, success);
}

function GetMarkers(userId, success) {
    ExecuteAddressCallback("getmarkers", userId, success);
}

function DelMarker(id, success) {
    ExecuteAddressCallback("delmarker", id, success);
}

function AddMarker(x, y, title, userId, success) {
    ExecuteAddressCallback("addmarker", title + "|" + x + "|" + y + "|" + userId, success);
}

function UpdateMarkerPos(x, y, title, success) {
    var hfUserId = document.getElementById("hfUserId");
    ExecuteAddressCallback("updatemarkerpos", title + "|" + x + "|" + y + "|" + hfUserId.value, success);
}

function UpdateMarkerTitle(id, title, success) {
    var hfUserId = document.getElementById("hfUserId");
    ExecuteAddressCallback("updatemarkertitle", id + "|" + title + "|" + hfUserId.value, success);
}

function FindRoute(A, B, opt, success) {
    try {
        var ax = encodeURIComponent(Math.round(A.X));
        var ay = encodeURIComponent(Math.round(A.Y));
        var bx = encodeURIComponent(Math.round(B.X));
        var by = encodeURIComponent(Math.round(B.Y));
        var Url = routeUrl + "?ax=" + ax + "&ay=" + ay + "&bx=" + bx + "&by=" + by + "&opt=" + opt + "&callback=?";
        $.getJSON(Url, { info: 'Эти данные отправились на сервер' }, success);
    }
    catch (e) {
        XhttpError();
    }
}

function GetJuridicalPersons(jurName, success) {
    ExecuteAddressCallback("GETJURIDICALPERSONS", jurName + "|", success);
}

function GetAdressIdByJuridicalPersonId(jurId, success) {
    ExecuteAddressCallback("GETADDRESSIDBYJURIDICALPERSONID", jurId, success);
}

function ShowJuridicalPersonById(jurId, success) {
    ExecuteAddressCallback("SHOWJURIDICALPERSONBYID", jurId, success);
}
