﻿/// <reference name="MicrosoftAjax.debug.js" />
/// <reference name="MicrosoftAjaxTimer.debug.js" />
/// <reference name="MicrosoftAjaxWebForms.debug.js" />
/// <reference path="../Map/MapBehavior.js"/>

Type.registerNamespace("SGis.MapToolkit");

SGis.MapToolkit.OvMapStatus = function() {
    /// <summary>Enumeración de los modos en los que se encuetra el mapa</summary>
    throw Error.invalidOperation();
}
SGis.MapToolkit.OvMapStatus.prototype = {
    Ready: 0,
    MapPanning: 1,
    FencePanning: 2
}
SGis.MapToolkit.OvMapStatus.registerEnum("SGis.MapToolkit.OvMapStatus", false);


SGis.MapToolkit.OvMapBehavior = function(element) {
    SGis.MapToolkit.OvMapBehavior.initializeBase(this, [element]);
    // Referencia a Controles y objetos
    this._ovMapContainer = null;  // contenedor de este control
    this._mapControl = null;
    this._mapContainer = null;    // Referencia al contenedor de mapas
    this._parentControl = null;   // Referencia al control de mapas
    this._mapFrame = null;        // Recuadro del mapa
    this._mapCollapser = null;    // Boton para colapsar
    this._lyrMap = [];             // Elementos de layers imagenes 0 y 1
    this._mapFence = null;                  // representa a una layer utilizada como caja para propositos generales (zoom por ejemplo)
    this._mapFenceBackground = null;
    this._mapFenceBorder = null;
    // Propiedades    
    this._IsCollapsed = false;          // Bandera que indica si el control esta colapsado
    this._ServicePath = null;           // Ruta del servicio
    this._ServiceMethod = null;         // Método para acceder al mapa
    // Miembros Privados
    this._ovWidth = 120;                // Mapa Overview - Ancho
    this._ovHeight = 120;               // Mapa Overview - Alto
    this._ovImgWidth = 240;             // Mapa Overview - Ancho de la imagen subyacente
    this._ovImgHeight = 240;            // Mapa Overview - Alto de la imagen subjacente
    this._ovZoomRelation = 2;         // Relación entre el zoom actual y el del mapa overview, debe ser > 1
    this._ovZoom = 0;                   // Zoom del mapa
    this._ovZoomMax = -1;               // Zoom Máximo para mapa overview, -1 = sin límite
    this._ovZoomMin = -1;               // Zoom Mínimo para mapa overview, -1 = sin límite
    this._mapWidth = null;              // Ancho del mapa principal
    this._mapHeight = null;             // Alto del mapa principal.
    this._ovMarginWidth = 8;            // Margen a dejar entre el mapa ov y el mapa general
    this._isLoaded = false;             // Bandera para indicar si el control ha sido cargado (inicializado)
    this._currentMap = 0;               // Una layer se usa de backup mientras la otra se muestra
    this._serviceTimeOut = 20000; // Tiempo de espera máxio para time out
    this._requestNumber = 0;      // Bandera para determinar el numero de request al servidor para descartar respuestas asincronicas cuando hay una posterior
    this._isDirty = false;        // Bandera que indica si el mapa esta sucio
    this._ovStatus = SGis.MapToolkit.OvMapStatus.Ready;
    this._startOvMapDrag = null;        // Se define cuando se está haciendo drag sobre el mapa overview
    this._endOvMapDrag = null;          // Se define mientras se hace el drag sobre el mapa overview
    // Animadores para Coordenadas y dimensiones 
    this._aniChangeX = null;
    this._aniChangeY = null;
    this._aniChange = null;
    //
    this._aniOvPanX = null;
    this._aniOvPanY = null;
    this._aniOvPan = null;

    // Eventos
    this._mapFrame$delegates = {
        mousedown: Function.createDelegate(this, this._mapFrame_onMouseDownHandler),
        mouseup: Function.createDelegate(this, this._mapFrame_onMouseUpHandler),
        mouseout: Function.createDelegate(this, this._mapFrame_onMouseOutHandler),
        mousemove: Function.createDelegate(this, this._mapFrame_onMouseMoveHandler)
    }
    this._mapCollapser$delegates = {
        mousedown: Function.createDelegate(this, this._mapCollapser_onMouseDownHandler)
    }
    this._mapControl$onMapExtentChanged$delegate = Function.createDelegate(this, this._mapControl_onMapExtentChanged);
    this._lyrMap0$delegates = {
        load: Function.createDelegate(this, this._lyrMap0_onLoadHandler)
    }
    this._lyrMap1$delegates = {
        load: Function.createDelegate(this, this._lyrMap1_onLoadHandler)
    }
}

SGis.MapToolkit.OvMapBehavior.prototype = {
    initialize: function() {
        SGis.MapToolkit.OvMapBehavior.callBaseMethod(this, 'initialize');
        //
        this._mapContainer = this.get_element().control._mapContainer;
        this._mapControl = this.get_element();
        this._parentControl = this.get_element().control;
        // Attach event handlers
        this.add_propertyChanged(Function.createDelegate(this, this._onPropertyChanged));
        this._parentControl.add_mapExtentChanged(this._mapControl$onMapExtentChanged$delegate);
        // Crea controles
        this.buildAll();
        // Inicializa animaciones
        this._aniChangeX = new AjaxControlToolkit.Animation.LengthAnimation(null, null, null, "style", "width", 0, 0, "px");
        this._aniChangeY = new AjaxControlToolkit.Animation.LengthAnimation(null, null, null, "style", "height", 0, 0, "px"); ;
        this._aniChange = new AjaxControlToolkit.Animation.ParallelAnimation(this._ovMapContainer, .10, 100, [this._aniChangeX, this._aniChangeY]); ;
        //
        this._aniOvPanX = new AjaxControlToolkit.Animation.LengthAnimation(null, null, null, "style", null, 0, 0, "px");
        this._aniOvPanY = new AjaxControlToolkit.Animation.LengthAnimation(null, null, null, "style", null, 0, 0, "px");
        this._aniOvPan = new AjaxControlToolkit.Animation.ParallelAnimation(null, .15, null, [this._aniOvPanX, this._aniOvPanY]);
    },


    dispose: function() {
        this._parentControl.remove_mapExtentChanged(this._mapControl$onMapExtentChanged$delegate);
        //Add custom dispose actions here
        SGis.MapToolkit.OvMapBehavior.callBaseMethod(this, 'dispose');
    },
    get_PlugInId: function() {
        /// <value type="string" mayBeNull="false">
        /// Gets de plugIn unique id
        /// </value>
        return 'sgis.ovmap';
    },
    /// <summary>
    // loads the current plugin into the main map container, creates menu, toolbar, atach events, etc
    /// </summary>
    /// <param name="container" type="SGis.MapToolkit.MapControl">
    /// The map control container
    /// </param>
    load: function(container) {
        if (this._isLoaded) return;
        this._isLoaded = true;
        this.resetLayers();

    },
    unload: function() {
        Sys.Debug.trace('Unloading ovmap');
    },
    buildAll: function() {
        this.buildOvMapContainer();
        this.buildMapFrame();
        this.buildMapCollapser();
        this.buildMapLayers();
        this.buildMapFence();
    },

    buildOvMapContainer: function() {
        this._ovMapContainer = $common.createElementFromTemplate(
        {
            nodeName: "div",
            cssClasses: ["sgmap_ov_container"]
        }, this._mapControl);
    },
    buildMapFrame: function() {
        this._mapFrame = $common.createElementFromTemplate(
        {
            nodeName: "div",
            cssClasses: ["sgmap_ov_mapframe"],
            events: this._mapFrame$delegates
        }, this._ovMapContainer);
    },
    buildMapCollapser: function() {
        this._mapCollapser = $common.createElementFromTemplate(
        {
            nodeName: "div",
            cssClasses: ["sgmap_ov_collapser_off"],
            events: this._mapCollapser$delegates
        }, this._mapControl);
    },
    buildMapLayers: function() {

        for (i = 0; i < 2; i++) {
            this._lyrMap[i] = $common.createElementFromTemplate({
                nodeName: "IMG",
                properties: {
                    id: "lyrOv" + i,
                    style: {
                        position: "absolute",
                        visibility: "hidden",
                        zIndex: 10
                    }
                }
            }, this._mapFrame);
            this._lyrMap[i].startPos = new Object();
        }
        $addHandlers(this._lyrMap[0], this._lyrMap0$delegates);
        $addHandlers(this._lyrMap[1], this._lyrMap1$delegates);
    },
    // Construye una reja para propositos generales
    buildMapFence: function() {
        this._mapFence = $common.createElementFromTemplate({
            nodeName: "div",
            properties: {
                id: "OvMapFence",
                style: {
                    position: "absolute",
                    visibility: "hidden",
                    zIndex: 50
                }
            },
            cssClasses: ["sgmap_mapcontrol_mapfence_container"],
            visible: false
        }, this._mapFrame);
        this._mapFence.startPos = new Object();
        this._mapFenceBackground = $common.createElementFromTemplate({
            nodeName: "div",
            cssClasses: ["sgmap_mapcontrol_mapfence_background"],
            opacity: .2
        }, this._mapFence);
        this._mapFenceBorder = $common.createElementFromTemplate({
            nodeName: "div",
            cssClasses: ["sgmap_mapcontrol_mapfence_border"]
        }, this._mapFence);
    },
    // Resetea posición y tamaño de layers
    resetLayers: function() {
        // Sys.Debug.trace("OvMap.resetLayers");
        // Actualiza tamaño del mapa
        var size = WebForm_GetElementPosition(this._mapContainer);
        this._mapWidth = size.width;
        this._mapHeight = size.height;
        // Resetea mapas
        this.resetOvMap(true);
        // Carga contenido
        this.loadData();
    },
    // Inicializa el mapa overview
    resetOvMap: function(hide) {
        this._ovStatus = SGis.MapToolkit.OvMapStatus.Ready;
        if (hide) {
            this.visibleMap().style.visibility = "hidden";
        }
        var img = this.invisibleMap();
        var dx = 0;
        var dy = 0;

        if (img.resultGetMap) {
            dx = (this._parentControl._CenterX - img.resultGetMap.CenterX) / this._ovZoom;
            dy = (this._parentControl._CenterY - img.resultGetMap.CenterY) / this._ovZoom;
        }
        img.startPos.x = -1 * Math.round((this._ovImgWidth - this._ovWidth) / 2 + dx);
        img.startPos.y = -1 * Math.round((this._ovImgHeight - this._ovHeight) / 2 - dy);
        img.startPos.centerX = this._parentControl._CenterX;
        img.startPos.centerY = this._parentControl._CenterY;
        Sys.UI.DomElement.setLocation(img, img.startPos.x, img.startPos.y);
        this._ovZoom = this._parentControl._Zoom * this._ovZoomRelation;
        if (this._ovZoom > this._ovZoomMax && this._ovZoomMax > 0) { this._ovZoom = this._ovZoomMax; }
        if (this._ovZoom < this._ovZoomMin && this._ovZoomMin > 0) { this._ovZoom = this._ovZoomMin; }
        // Para que el zoom del overview sea real, es necesario un multiplicarlo por la relación ancho imagen, ancho contenedor
        var zoomH = this._ovZoom * this._mapWidth / this._ovWidth * this._ovImgWidth / this._ovWidth;
        var zoomV = this._ovZoom * this._mapHeight / this._ovHeight * this._ovImgHeight / this._ovHeight;
        if (zoomH > zoomV) { this._ovZoom = zoomV; } else { this._ovZoom = zoomH; }
        //
        img.startPos.zoom = this._ovZoom;
        img.startPos.parentZoom = this._parentControl._Zoom; // Zoom del padre
        // Resetea Reja
        this.resetOvFence();

    },
    // Reestablece el tamaño de la reja del mapa overview 
    resetOvFence: function() {
        if (this._mapFence && this._parentControl._Zoom > 0 && this._ovZoom > 0) {
            var elt = this._mapFence;
            var w = Math.round((this._mapWidth / this._ovZoom * this._parentControl._Zoom));
            var h = Math.round((this._mapHeight / this._ovZoom * this._parentControl._Zoom));
            var x = Math.round((this._ovWidth - w) / 2);
            var y = Math.round((this._ovHeight - h) / 2);
            elt.startPos.x = x;
            elt.startPos.y = y;
            $common.setLocation(elt, { x: x, y: y });
            $common.setSize(elt, { width: w, height: h });
            $common.setSize(this._mapFenceBorder, { width: w, height: h });
            $common.setVisible(elt, true);
        }
    },
    // Obtiene el mapa visible
    visibleMap: function() {
        return this._lyrMap[this._currentMap];
    },
    // Obtiene el mapa invisible
    invisibleMap: function() {
        return this._lyrMap[this._currentMap == 0 ? 1 : 0];
    },
    loadData: function() {
        this.invokeGetMapWebService();
    },
    // Invoca al servicio web para obtener mapa en forma asincrónica
    invokeGetMapWebService: function() {
        this._requestNumber++;
        Sys.Net.WebServiceProxy.invoke(this._ServicePath, this._ServiceMethod, false,
                { centerX: this._parentControl._CenterX, centerY: this._parentControl._CenterY, zoom: this._ovZoom, imgWidth: this._ovImgWidth, imgHeight: this._ovImgHeight },
                Function.createDelegate(this, this.onGetMapMethodComplete),
                Function.createDelegate(this, this.onGetMapMethodError), { requestNumber: this._requestNumber }, this._serviceTimeOut);

    },
    // Se completo invocación al web service - GetMap
    onGetMapMethodComplete: function(result, userContext, methodName) {
        // Verifica que sea el ultimo request, ignora resultado si no
        if (this._requestNumber != userContext.requestNumber) return;
        // Si el resultado es invalido debe mostrar el error y no procesar mas
        if (!result.IsValid) return;
        this._isDirty = false;
        // Aplica cambios al mapa invisible para mostrarlo una vez cargado
        var map = this.invisibleMap();
        map.resultGetMap = result; // Se guarda el resultado del mapa dentro de la layer para porder dibujarla en base a valores actuales de centro y zoom
        // 
        map.src = result.Url;
        //
        this.resetOvMap(false);
    },
    // Error al invocar web service
    onGetMapMethodError: function(webServiceError, userContext, methodName) {
        // Verifica que sea el ultimo request, ignora resultado si no
        if (this._requestNumber != userContext.requestNumber) return;
        // Call failed
        var strError;
        if (webServiceError.get_timedOut()) {
            strError = "Tiempo de espera excedido.";
        } else {
            strError = "Error al llamar Servicio Web: " + webServiceError.get_statusCode() + " " + webServiceError.get_message();
        }
        Sys.Debug.trace("OvMap: " + strError);
    },
    // Intercambia imagenes de mapas
    swapImgMaps: function() {
        this._currentMap = this._currentMap == 0 ? 1 : 0;
        $common.setVisible(this.visibleMap(), true);
        $common.setVisible(this.invisibleMap(), false);

    },
    // Determina si es necesario redibujar el mapa, cuando se encuentra fuera de la ventana donde se ve
    reloadIfNeeded: function() {
        var map = this.visibleMap();
        var reload = true;
        if (map.startPos) {
            var pos = map.startPos;
            if (this._isDirty || pos.x > 0 || pos.y > 0 || Math.abs(pos.x) > (this._ovImgWidth - this._ovWidth) / 2 || Math.abs(pos.x) > (this._ovImgHeight - this._ovHeight) / 2) {
                reload = true;
            } else {
                reload = false;
            }
        }
        if (reload) this.loadData();
        this.resetOvFence();
    },
    // Realiza el paneo y zoom animado de el mapa principal y el overview
    animateZoomPan: function() {

        // si ha cambiado el zoom, no anima
        var map = this.visibleMap();
        if (map.resultGetMap !== null && typeof (map.resultGetMap) !== 'undefined' && map.startPos.parentZoom === this._parentControl._Zoom) {
            // Determina Delta de desplazamientos en pixeles
            var dx = (this._parentControl._CenterX - map.resultGetMap.CenterX) / this._ovZoom;
            var dy = (this._parentControl._CenterY - map.resultGetMap.CenterY) / this._ovZoom;

            if (map.startPos) {
                var endPos = new Object();
                endPos.x = Math.round((this._ovImgWidth - this._ovWidth) / -2 - dx);
                endPos.y = Math.round((this._ovImgHeight - this._ovHeight) / -2 + dy);
                endPos.parentZoom = map.startPos.parentZoom;
                this._aniOvPanX.set_propertyKey("left");
                this._aniOvPanX.set_target(map);
                this._aniOvPanX.set_startValue(map.startPos.x);
                this._aniOvPanX.set_endValue(endPos.x);
                this._aniOvPanY.set_propertyKey("top");
                this._aniOvPanY.set_target(map);
                this._aniOvPanY.set_startValue(map.startPos.y);
                this._aniOvPanY.set_endValue(endPos.y);
                var endHandler = Function.createDelegate(this, function() {
                    this._aniOvPan.remove_ended(endHandler);
                    this.reloadIfNeeded();
                });
                map.startPos = endPos;  // La posición final pasa a ser la pos. inicial
                this._aniOvPan.add_ended(endHandler);
                this._aniOvPan.play();
                return;
            }

        }
        // Si no se anima, se carga directamente un mapa nuevo
        $common.setVisible(this.visibleMap(), false);
        this.resetLayers();
    },
    // Médoto auxiliar para el comienzo del panning del mapa miniatura
    actionOvPanningStart: function(evt) {
        // Determina si va a mover el mapa de fondo o la fence
        var pos = $sgutils.getRelativeEventLocation(evt, this._mapFence);
        var rec = $common.getBounds(this._mapFence);
        if (pos.x < 0 || pos.x > rec.width || pos.y < 0 || pos.y > rec.height) {

            this._ovStatus = SGis.MapToolkit.OvMapStatus.MapPanning;
            //var target = this.visibleMap();
            //this._locOvMap = new Sys.UI.Point($common.parseUnit(target.style.left).size, $common.parseUnit(target.style.top).size);
        }
        else {
            this._ovStatus = SGis.MapToolkit.OvMapStatus.FencePanning;
            //this._MapAction = SGis.MapToolkit.MapAction.OvFencePanning;
            //this._locOvMap = new Sys.UI.Point($common.parseUnit(this._ovFence.style.left).size, $common.parseUnit(this._ovFence.style.top).size);
        }
        this._startOvMapDrag = $sgutils.getEventClientLocation(evt);
        this._endOvMapDrag = null;
    },
    // Método auxiliar para movimiento de paneo del mapa overview
    actionOvPanningMove: function(evt) {
        this._endOvMapDrag = $sgutils.getEventClientLocation(evt);
        var dx = Math.round(this._endOvMapDrag.x - this._startOvMapDrag.x);
        var dy = Math.round(this._endOvMapDrag.y - this._startOvMapDrag.y);
        switch (this._ovStatus) {
            case SGis.MapToolkit.OvMapStatus.MapPanning:
                if (this._startOvMapDrag) {
                    var t = this.visibleMap();
                    $common.setLocation(t, { x: t.startPos.x + dx, y: t.startPos.y + dy });
                    this._mapFrame.style.cursor = 'move';
                }
                break;
            case SGis.MapToolkit.OvMapStatus.FencePanning:
                if (this._startOvMapDrag) {
                    var f = this._mapFence;
                    $common.setLocation(f, { x: f.startPos.x + dx, y: f.startPos.y + dy });
                    this._mapFrame.style.cursor = 'move';
                }
                break;
        }
    },
    // Método auxiliar para finalizar el paneo del mapa overview
    actionOvPanningEnd: function() {
        if (this._endOvMapDrag && this._startOvMapDrag) {
            var dx = Math.round(this._endOvMapDrag.x - this._startOvMapDrag.x);
            var dy = Math.round(this._endOvMapDrag.y - this._startOvMapDrag.y);
            switch (this._ovStatus) {
                case SGis.MapToolkit.OvMapStatus.MapPanning:
                    if (this._startOvMapDrag && this._endOvMapDrag) {
                        var v = this.visibleMap();
                        v.startPos.x = v.startPos.x + dx;
                        v.startPos.y = v.startPos.y + dy;
                        $common.setLocation(v, { x: v.startPos.x, y: v.startPos.y });
                        // recentrar
                        var rel = this._parentControl._Zoom / this._ovZoom;
                        // Reestablece nuevo centro del mapa principal
                        this._parentControl.offsetCenter((this._parentControl._Zoom * (dx / rel) * -1), (this._parentControl._Zoom * (dy / rel)));
                    }
                    break;
                case SGis.MapToolkit.OvMapStatus.FencePanning:
                    if (this._startOvMapDrag && this._endOvMapDrag) {
                        var f = this._mapFence;
                        f.startPos.x = f.startPos.x + dx;
                        f.startPos.y = f.startPos.y + dy;
                        // recentrar
                        var rel = this._parentControl._Zoom / this._ovZoom;
                        this._mapFence.style.visibility = 'hidden';
                        this._parentControl.offsetCenter(this._parentControl._Zoom * (dx / rel), (this._parentControl._Zoom * (dy / rel) * -1));
                    }
                    break;
            }
            this._startOvMapDrag = null;
            this._endOvMapDrag = null;
            this._mapFrame.style.cursor = 'auto';
        }
        this._ovStatus = SGis.MapToolkit.OvMapStatus.Ready;
        return;


    },

    //--------------------------------------------------------------------------
    // PROPIEDADES
    //--------------------------------------------------------------------------
    get_ServicePath: function() {
        return this._ServicePath;
    },
    set_ServicePath: function(value) {
        if (this._ServicePath != value) {
            this._ServicePath = value;
            this.raisePropertyChanged('ServicePath');
        }
    },
    get_IsCollapsed: function() {
        return this._IsCollapsed;
    },
    set_IsCollapsed: function(value) {
        if (this._IsCollapsed != value) {
            this._IsCollapsed = value;
            this.raisePropertyChanged('IsCollapsed');
        }
    },
    get_ServiceMethod: function() {
        return this._ServiceMethod;
    },
    set_ServiceMethod: function(value) {
        if (this._ServiceMethod != value) {
            this._ServiceMethod = value;
            this.raisePropertyChanged('ServiceMethod');
        }
    },

    //--------------------------------------------------------------------------
    // Manejadores de Eventos
    //--------------------------------------------------------------------------
    // Mueve el mose sobre el Mapa
    _mapCollapser_onMouseDownHandler: function(evt) {
        this.set_IsCollapsed(!this._IsCollapsed);
        evt.preventDefault();
    },
    // Al cambiar la extensión del mapa
    _mapControl_onMapExtentChanged: function(sender, args) {
        // animación del mapa overview
        this.animateZoomPan();
    },
    // Termina carga de imagen para mapa 1
    _lyrMap0_onLoadHandler: function(evt) {
        this.swapImgMaps();
    },
    // Termina carga de imagen para mapa 2
    _lyrMap1_onLoadHandler: function(evt) {
        this.swapImgMaps();
    },
    // Click sobre el mapa overview, paneo
    _mapFrame_onMouseDownHandler: function(evt) {
        if (this._parentControl._MapStatus == SGis.MapToolkit.MapStatus.Ready && this._ovStatus === SGis.MapToolkit.OvMapStatus.Ready) {
            this.actionOvPanningStart(evt);
            evt.preventDefault();
        }
    },
    // Suelta el mouse sobre el mapaOverview, fin de drag, zoom, etc
    _mapFrame_onMouseUpHandler: function(evt) {
        if (this._ovStatus !== SGis.MapToolkit.OvMapStatus.Ready) {
            this.actionOvPanningEnd();
            evt.preventDefault();
        }
    },
    // Mueve el mouse sobre el Mapa Overview
    _mapFrame_onMouseMoveHandler: function(evt) {

        if (this._ovStatus == SGis.MapToolkit.MapStatus.Ready) {
            return;
        }
        this.actionOvPanningMove(evt);
        evt.preventDefault();
    },
    // Cuando el mouse sale del mapa ov, cancela operación de drag, si se estaba haciendo
    _mapFrame_onMouseOutHandler: function(evt) {

        if (this._ovStatus == SGis.MapToolkit.MapStatus.Ready) {
            return;
        }
        var rec = $common.getBounds(this._mapFrame);
        var pos = $sgutils.getRelativeEventLocation(evt, this._mapFrame)
        if (pos.x < 0 || pos.x > rec.width - 2 || pos.y < 0 || pos.y > rec.height - 2) {
            this.actionOvPanningEnd();

        }
        evt.preventDefault();

    },
    // Al cambiar propiedades 
    _onPropertyChanged: function(sender, args) {
        var propname = args.get_propertyName();
        if (propname == "IsCollapsed") {
            if (this._IsCollapsed) {
                this._aniChangeX.set_endValue(0);
                this._aniChangeX.set_startValue(this._ovWidth + this._ovMarginWidth);
                this._aniChangeY.set_endValue(0);
                this._aniChangeY.set_startValue(this._ovHeight + this._ovMarginWidth);
            } else {
                this._aniChangeX.set_startValue(0);
                this._aniChangeX.set_endValue(this._ovWidth + this._ovMarginWidth);
                this._aniChangeY.set_startValue(0);
                this._aniChangeY.set_endValue(this._ovHeight + this._ovMarginWidth);
            }
            var endHandler = Function.createDelegate(this, function() {
                if (this._IsCollapsed) {
                    if (Sys.UI.DomElement.containsCssClass(this._mapCollapser, "sgmap_ov_collapser_off")) {
                        Sys.UI.DomElement.removeCssClass(this._mapCollapser, "sgmap_ov_collapser_off");
                    }
                    Sys.UI.DomElement.addCssClass(this._mapCollapser, "sgmap_ov_collapser_on");
                }
                else {
                    if (Sys.UI.DomElement.containsCssClass(this._mapCollapser, "sgmap_ov_collapser_on")) {
                        Sys.UI.DomElement.removeCssClass(this._mapCollapser, "sgmap_ov_collapser_on");
                    }
                    Sys.UI.DomElement.addCssClass(this._mapCollapser, "sgmap_ov_collapser_off");
                }
                this._aniChange.remove_ended(endHandler);
            });
            this._aniChange.add_ended(endHandler);
            this._aniChange.play();
        }
    }


}
SGis.MapToolkit.OvMapBehavior.registerClass('SGis.MapToolkit.OvMapBehavior', AjaxControlToolkit.BehaviorBase, SGis.MapToolkit.IPlugIn);



if(typeof(Sys)!=='undefined')Sys.Application.notifyScriptLoaded();