﻿/// <reference name="MicrosoftAjax.debug.js" />
/// <reference name="MicrosoftAjaxTimer.debug.js" />
/// <reference name="MicrosoftAjaxWebForms.debug.js" />

/// <reference path="EventControllerBehavior.js" />

Type.registerNamespace("UI.Controls");


UI.Controls.Status = function() {
    /// <summary>Enumeración de los modos en los que se encuetra la carga de delito</summary>
    throw Error.invalidOperation();
}
UI.Controls.Status.prototype = {
    Ready: 0,
    Locating: 1,
    Relocating: 2,
    FillingForm: 3
}
UI.Controls.Status.registerEnum("UI.Controls.Status", false);
//
UI.Controls.EventControllerBehavior = function(element) {
    /// <summary>
    /// Controlador para la carga de eventos
    /// </summmary>
    /// <param name="element" type="Sys.UI.DomElement">The element to attach to</param>
    UI.Controls.EventControllerBehavior.initializeBase(this, [element]);
    // Referencia a Controles y objetos
    this._parentControl = null; // Referencia al control de mapas
    this._container = null;     // contenedor
    this._btnNewEvent = null;   // Referencia al boton para cargar nuevo delito
    this._btnCancel = null;     // Botón para cancelar la operación
    this._panInstruc = null;    // Cuadro para reflejar instrucciones
    // Fields
    this._eventX = null;        // Coordenada X del evento
    this._eventY = null;        // Coordenada Y del evento
    this._status = UI.Controls.Status.Ready; // Modo en que es encuantra la carga
    //
    // Propiedades
    this._EventControllerPanelId = null; // Id del Panel para desarrollar controles
    // Eventos
    this._btnNewEvent$delegates = {
        mousedown: Function.createDelegate(this, this._btnNewEvent_onMouseDownHandler),
        click: Function.createDelegate(this, this._btnNewEvent_onClickHandler)
    };
    this._btnCancel$delegates = {
        mousedown: Function.createDelegate(this, this._btnCancel_onMouseDownHandler),
        click: Function.createDelegate(this, this._btnCancel_onClickHandler)
    };
    this._documentElement$delegates = {
        mousemove: Function.createDelegate(this, this._documentElement_onMouseMoveHandler)
    };
    this._mapControl$onCustomToolMouseDown$delegate = Function.createDelegate(this, this._mapControl_onCustomToolMouseDown);

    this._eventFilter$onFilterChanged$delegate = Function.createDelegate(this, this._eventFilter_onFilterChanged);


}

UI.Controls.EventControllerBehavior.prototype = {
    initialize: function() {
        UI.Controls.EventControllerBehavior.callBaseMethod(this, 'initialize');
        //
        this._parentControl = this.get_element().control;
        this._container = $get(this._EventControllerPanelId);
        // Attach events
        $addHandlers(document.documentElement, this._documentElement$delegates);
        this._parentControl.add_customToolMouseDown(this._mapControl$onCustomToolMouseDown$delegate);
        // Construye elementos
        this.buildControls();
    },
    dispose: function() {
        // Detach Handlers
        $addHandlers(document.documentElement, this._documentElement$delegates);
        this._parentControl.remove_customToolMouseDown(this._mapControl$onCustomToolMouseDown$delegate);
        //Add custom dispose actions here
        UI.Controls.EventControllerBehavior.callBaseMethod(this, 'dispose');
    },
    get_PlugInId: function() {
        /// <value type="string" mayBeNull="false">
        /// Gets de plugIn unique id
        /// </value>
        return 'ui.controls.EventController';
    },
    load: function(container) {
        /// <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 Plugin
        var e = $find('EventFilter');
        if (e) {
            e.add_filterChanged(this._eventFilter$onFilterChanged$delegate);
        }
    },
    unload: function() {
        // Unloads Plugin
        var e = $find('EventFilter');
        if (e) {
            e.remove_filterChanged(this._eventFilter$onFilterChanged$delegate);
        }
    },

    buildControls: function() {
        /// <summary>
        /// Construye los controles contenidos 
        /// </summary>
        /// <returns />
        this._panInstruc = $common.createElementFromTemplate(
        {
            nodeName: "div",
            cssClasses: ["ins_pan_instrucciones"],
            properties: {
                title: "Instrucciones para cargar delito"
            }
        }, this._container);
        this.instruccionPaso1();
        // Boton para crargar delito
        this._btnNewEvent = $common.createElementFromTemplate(
        {
            nodeName: "a",
            cssClasses: ["ins_btn_cargardelito"],
            properties: {
                href: "#",
                innerHtml: "Cargar Nuevo Delito",
                title: "Cargar Nuevo Delito"
            },
            events: this._btnNewEvent$delegates
        }, this._container);

        // Boton para Cancelar carga
        this._btnCancel = $common.createElementFromTemplate(
        {
            nodeName: "a",
            cssClasses: ["ins_btn_cancelardelito"],
            properties: {
                href: "#",
                innerHTML: "Cancelar Localización",
                title: "Cancelar Localización"
            },
            visible: false,
            events: this._btnCancel$delegates
        }, this._container);

        // Div Flotante que contiene el pin para localizar y el tooltip
        this._eventPin = $common.createElementFromTemplate(
        {
            nodeName: "div",
            properties: {
                id: "locatingPin",
                style: {
                    zIndex: 500
                }
            },
            visible: false,
            cssClasses: ["ins_locating"]
        }, document.body);
        // Sombra del pin
        $common.createElementFromTemplate({
            nodeName: "div",
            opacity: 0.4,
            cssClasses: ["ins_pin_locating_shadow"]
        }, this._eventPin);
        // Pin
        $common.createElementFromTemplate({
            nodeName: "div",
            cssClasses: ["ins_pin_locating"]
        }, this._eventPin);
    },
    setStatusLocating: function(sender) {
        /// <summary>
        /// Establece el modo para localizar
        /// </summary>
        /// <returns />
        Sys.UI.DomElement.setVisible(this._eventPin, true);
        Sys.UI.DomElement.setVisible(this._btnNewEvent, false);
        Sys.UI.DomElement.setVisible(this._btnCancel, true);
        this._status = UI.Controls.Status.Locating;
        this.positionLocatingPin(sender);
        // Establece la herramienta de mapa custom
        this._parentControl.setModeCustom('CargaEvento');
        // Instrucciones
        this.instruccionPaso2();
    },
    setStatusRelocating: function(sender) {
        /// <summary>
        /// Establece el modo para localizar
        /// </summary>
        /// <returns />
        Sys.UI.DomElement.setVisible(this._eventPin, true);
        Sys.UI.DomElement.setVisible(this._btnNewEvent, false);
        Sys.UI.DomElement.setVisible(this._btnCancel, true);
        this._status = UI.Controls.Status.Relocating;
        this.positionLocatingPin(sender);
        // Oculta formulario new
        var newForm = $find("NewEventForm");
        if (newForm) newForm.hideForm();
        // Establece la herramienta de mapa custom
        this._parentControl.setModeCustom('CargaEvento');
        // Instrucciones
        this.instruccionPaso2();
    },
    setStatusReady: function(sender) {
        /// <summary>
        /// Establece el modo para localizar
        /// </summary>
        /// <returns />
        Sys.UI.DomElement.setVisible(this._eventPin, false);
        Sys.UI.DomElement.setVisible(this._btnNewEvent, true);
        Sys.UI.DomElement.setVisible(this._btnCancel, false);
        this._status = UI.Controls.Status.Ready;
        // Oculta formulario new
        var newForm = $find("NewEventForm");
        if (newForm) newForm.hideForm();
        newForm.clearForm();
        // Establece la herramienta de mapa a panning
        this._parentControl.setModePan();
        // Instrucciones
        this.instruccionPaso1();
    },
    setStatusFillingForm: function(sender, args) {
        /// <summary>
        /// Establece el modo para llenar el formulario, si el zoom no es suficiente hace un zoom a una escala adecuada
        /// </summary>
        /// <returns />
        var minZoom = 0.000028;
        if (this._parentControl._Zoom <= minZoom) {
            this._status = UI.Controls.Status.FillingForm;
            // Obtiene del argumento la posicion de mapa
            this._eventX = args.MapPosition.x;
            this._eventY = args.MapPosition.y;
            //
            this._parentControl.setModePan();
            // Desplaza punto de click al centro del mapa
            var deltaX = (this._eventX - this._parentControl._CenterX);
            var deltaY = (this._eventY - this._parentControl._CenterY);
            this._parentControl.offsetCenter(deltaX, deltaY);
            //
            // Localiza el pin en el centro del mapa
            var formPos = this._parentControl.worldToMap({ x: this._eventX, y: this._eventY });
            var mapaPos = Sys.UI.DomElement.getLocation(this._parentControl._mapContainer);
            Sys.UI.DomElement.setLocation(this._eventPin, Math.round(formPos.x + mapaPos.x) - 14, Math.round(formPos.y + mapaPos.y) - 36);
            // localiza y muestra formulario para carga
            var newForm = $find("NewEventForm");
            newForm.showForm(
                { x: Math.round(formPos.x + mapaPos.x), y: Math.round(formPos.y + mapaPos.y) },
                { x: this._eventX, y: this._eventY },
                this);
            // Instrucciones
            this.instruccionPaso3();
        } else {
            // Si el zoom fue unsuficiente, se hace un acercamiento
            this._parentControl.changeExtentToCenter(args.MapPosition.x, args.MapPosition.y, minZoom);
        }
    },
    instruccionPaso1: function() {
        /// <summary>
        /// Carga instrucciones para el paso uno
        /// </summary>
        /// <returns />
        var ins;
        ins = "<span>";
        ins += "Para cargar un delito debe primero localizar la zona donde ocurri&oacute;. ";
        ins += "Luego haga clic en el bot&oacute;n <strong>Cargar Delito</strong>.";
        ins += "</span>";
        this._panInstruc.innerHTML = ins;
    },
    instruccionPaso2: function() {
        /// <summary>
        /// Carga instrucciones para el paso dos
        /// </summary>
        /// <returns />
        var ins;
        ins = "<span>";
        ins += "Haga clic en lugar del mapa donde ocurri&oacute; el hecho.";
        ins += "Puede cancelar la operací&oacute;n haciendo clic en el bot&oacute;n <strong>Cancelar</strong>.";
        ins += "</span>";
        this._panInstruc.innerHTML = ins;
    },
    instruccionPaso3: function() {
        /// <summary>
        /// Carga instrucciones para el paso tres
        /// </summary>
        /// <returns />
        var ins;
        ins = "<span>";
        ins += "Complete el formulario con la informaci&oacute;n solicitada.";
        ins += "</span>";
        this._panInstruc.innerHTML = ins;
    },
    positionLocatingPin: function(sender) {
        /// <summary>
        /// Reposiciona el  location pin
        /// </summary>
        /// <returns />
        if (this._status == UI.Controls.Status.Locating || this._status == UI.Controls.Status.Relocating) {
            Sys.UI.DomElement.setLocation(this._eventPin, sender.clientX - 14 + document.documentElement.scrollLeft, sender.clientY - 36 + document.documentElement.scrollTop);
        }
    },
    // Invalida controles y reportes
    invalidate: function() {
        // Actualiza capa de objetos
        var ef = $find('EventFilter');
        var ol = $find('DelitosLayerObjects');
        if (ol) {
            // Cambia los parámetros de la capa de delitos y refresca
            ol.set_Params(Sys.Serialization.JavaScriptSerializer.serialize(ef._CfgFiltro));
            ol.loadData();
        }
        // Actualiza reporte de ultimos
        var ru = $find('ReportUltimos');
        if (ru) {
            ru.programLoadReport(1000);
        }
    },
    //--------------------------------------------------------------------------
    // Acceso a Propiedades
    //--------------------------------------------------------------------------
    get_EventControllerPanelId: function() {
        return this._EventControllerPanelId;
    },
    set_EventControllerPanelId: function(value) {
        if (this._EventControllerPanelId != value) {
            this._EventControllerPanelId = value;
            this.raisePropertyChanged('EventControllerPannelId');
        }
    },
    //--------------------------------------------------------------------------
    // Manejadores de Eventos
    //--------------------------------------------------------------------------
    _btnNewEvent_onMouseDownHandler: function(sender, args) {
        this.setStatusLocating(sender);
    },
    _btnNewEvent_onClickHandler: function(sender, args) {
        sender.preventDefault();
        sender.stopPropagation();
    },
    //
    _btnCancel_onMouseDownHandler: function(sender, args) {
        this.setStatusReady(sender);
    },
    _btnCancel_onClickHandler: function(sender, args) {
        sender.preventDefault();
        sender.stopPropagation();
    },
    //
    _documentElement_onMouseMoveHandler: function(sender, args) {
        this.positionLocatingPin(sender);

    },
    //
    // Al hacer click en el mapa con la herramienta custom seleccionada
    _mapControl_onCustomToolMouseDown: function(sender, args) {
        this.setStatusFillingForm(sender, args);

    },
    // Al cambiar algo en el filtro de eventos a mostrar
    _eventFilter_onFilterChanged: function(sender, args) {
        this.invalidate();
    }

}
UI.Controls.EventControllerBehavior.registerClass('UI.Controls.EventControllerBehavior', AjaxControlToolkit.BehaviorBase, SGis.MapToolkit.IPlugIn);



if(typeof(Sys)!=='undefined')Sys.Application.notifyScriptLoaded();