// Array de marcas global.
var marcas_global;
var topics_marcas_global;

// Marca global para la nube de un nuevo punto.
var nueva_marca_global;

// String con el titulo de la categoria actual.
var titulo_categ_global;

// Entero con el id de la categoria actual.
var id_categoria_global;

// Datos XML de las categorias/puntos.
var xml_global;

var map;
var geocoder;
var address;

            
// Funcion para cargar el XML con los datos e inicializar todo.
function cargar_xml(id, topic) {
    GDownloadUrl(GEOK_DIR_BASE + GEOK_PATH_XML + "/?sid=" + getCookie("sesion_phpbb"), function(data, responseCode) {
        xml_global = GXml.parse(data);
        crear_mapa(id);
        crear_categorias();        
        ajustar_mapa_a_pantalla();
        if (topic != 0) mostrar_marca_nube(id, topic);
    });
}

// Funcion para inicializar las variables globales.
function inicializar_global() {
    marcas_global = new Array();
    topics_marcas_global = new Array();
    titulo_categ_global = "";
    geocoder = new GClientGeocoder();
}         

// Para mostrar la nube de una marca por su topic.
function mostrar_marca_nube(forum, topic) {
	var i = 0;
	var encontrado = false;
	
	// Buscamos la marca en el array de topics.
	while (i < topics_marcas_global.length && !encontrado) {
		encontrado = (topics_marcas_global[i] == topic);
		i++;
	}
	
	if (encontrado) {		
		pulsar_categoria(forum);	
		mostrar_marca(marcas_global[i - 1], forum, topic, "");   
	}
}

// Función para eliminar el nodo de una marca
// de la estructura del XML y quitarlo del mapa.
function eliminar_marca_xml(id_topic, id_forum) {
	var marcas = xml_global.getElementsByTagName("marker");
	var i = 0;
	var encontrado = false;
	
	// Buscamos la marca en la estructura DOM.
	while (i < marcas.length && !encontrado) {
		encontrado = (parseInt(marcas[i].getAttribute("topic")) == id_topic);
		i++;
	}
		
	// Si la encontramos, la eliminamos de la estructura y 
	// ocultamos el punto del mapa.
	if (encontrado) {
		// Eliminamos la marca de la estructura DOM y
		// regeneramos la lista de categorías.
		marcas[i - 1].parentNode.removeChild(marcas[i - 1]);	
		crear_categorias();
		if (getCookie("cat") == id_forum) Muestra(id_forum);
		
		// Buscamos la marca en el mapa.
		i = 0;
		encontrado = false;		
		while (i < marcas_global.length && !encontrado) {
			encontrado = (topics_marcas_global[i] == id_topic);
			i++;
		}
		
		// La ocultamos si la encontramos.
		if (encontrado) {
			marcas_global[i - 1].closeInfoWindow();
			marcas_global[i - 1].hide();
		}
	}	
}

// Funcion que se llama al pulsar sobre el enlace de una marca
// en la lista de categorias.
function pulsar_marca(id, marca, id_forum, id_topic) {
    if (id_categoria_global != id) {
        crear_mapa(id);
        crear_categorias();
    }    
    mostrar_marca(marcas_global[marca], id_forum, id_topic, "");    
    Muestra(id);
}

// Funcion que se llama al pulsar sobre el enlace de una categoria
// en la lista de categorias.
function pulsar_categoria(id) {
    crear_mapa(id);
    if (id_categoria_global != id) {
        crear_categorias();
    }
    setCookie("cat", id, 5);
}

// Función para mostrar la información de una
// marca existente abriendo su nube.

function mostrar_marca(marca, id_forum, id_topic, opciones) {
	// Pedimos el contenido al servidor.
    var mensaje = plt_ObtenerContenidoMarca(marca, id_forum, id_topic);	
}

// Funcion para crear una marca personalizada en el mapa:
//
// objeto: es el objeto de tipo GIcon usado como icono base para las sobras.
// point: es el punto (objeto de tipo GLatLng) en el mapa.
// index: indice de la marca (de 0 a n).
// datos: array asociativo con los datos adicionales de la marca.
// max: es el contenido que pasamos para que aparezca al maximizar el globo. Este parámetro puede ser una cadena de HTML

function createMarker(datos, objeto, point, index, max) {

	// Creamos el icono.
    var letteredIcon = new GIcon(objeto);

    // URL del icono de la marca.
    letteredIcon.image = datos["urlbase"] + "." + datos["extension"];

    var marker = new GMarker(point, {icon: letteredIcon});

    //Evento para cuando se haga clic en la marca aparezca la nube
    GEvent.addListener(marker, "click", function() {    	
    	mostrar_marca(marker, datos["id_forum"], datos["id_topic"], "");
    });

    // retornamos el nuevo objeto creado con la marca.
    return marker;
}
   
// Funcion de creacion del mapa.
function crear_mapa(id) {
    
    // Comprobamos si el navegador es compatible con la API de Google Maps.
    if (GBrowserIsCompatible()) {

        // Descargamos antes.
        GUnload();

        // Inicializamos variables globales.
        inicializar_global();

        // Creamos el objeto del mapa (v2.0) y lo asignamos al elemento div con id="map".
        map = new GMap2(document.getElementById("map"));

        // Configuramos el mapa y sus controles.

        //obtenemos el nodo global
        var xml_nodoGlobal = xml_global.documentElement.getElementsByTagName("global");

        var nodo_centro=xml_nodoGlobal[0].getElementsByTagName("centro");
        
        var coordenada_x=nodo_centro[0].getAttribute("coord_x");
        var coordenada_y=nodo_centro[0].getAttribute("coord_y");
        var zoom=nodo_centro[0].getAttribute("zoom");

        var nodo_limites=xml_nodoGlobal[0].getElementsByTagName("limites");
        var li_inf_x=nodo_limites[0].getAttribute("inf_x");
        var li_inf_y=nodo_limites[0].getAttribute("inf_y");
        var li_sup_x=nodo_limites[0].getAttribute("sup_x");
        var li_sup_y=nodo_limites[0].getAttribute("sup_y");

        var nodo_zoom=xml_nodoGlobal[0].getElementsByTagName("zoom");
        var zoom_min=nodo_zoom[0].getAttribute("min");
        var zoom_max=nodo_zoom[0].getAttribute("max");

        var center = new GLatLng(parseFloat(coordenada_x),parseFloat(coordenada_y));
        map.setCenter(center, parseInt(zoom));
        var restricter = new TRestricter(map);
        restricter.zoomLevels(parseInt(zoom_min), parseInt(zoom_max));
        restricter.restrict( new GLatLng(parseFloat(li_inf_x),parseFloat(li_inf_y)) , new GLatLng(parseFloat(li_sup_x),parseFloat(li_sup_y)));

        //map.setMapType(G_HYBRID_TYPE);
        //map.setMapType(G_PHYSICAL_MAP);
        //map.addMapType(G_PHYSICAL_MAP);
        map.setMapType(G_NORMAL_MAP);
        var topRightTiposMapa = new GControlPosition(G_ANCHOR_TOP_RIGHT, new GSize(78,28));
        map.addControl(new GMapTypeControl(),topRightTiposMapa);
        var topRightZoom = new GControlPosition(G_ANCHOR_TOP_RIGHT, new GSize(10,10));
        map.addControl(new GLargeMapControl(),topRightZoom);

       //PREPARAMOS LOS CONTROLES PARA LA BARRA DE BUSQUEDA
           var options = {
                linkTarget : GSearch.LINK_TARGET_BLANK,
                searchFormHint : "Buscar en el mapa...",
                suppressInitialResultSelection : true
            };

            var searchcontrol = new google.maps.LocalSearch(options);

            var topRightBusqueda = new GControlPosition(G_ANCHOR_TOP_RIGHT, new GSize(80,50));
            map.addControl(searchcontrol,topRightBusqueda);
        //FIN CONTROLES BUSQUEDA


        map.enableScrollWheelZoom();

        // Obtenemos los nodos de las categorias.
        var xml_categorias = xml_global.documentElement.getElementsByTagName("categoria");
        var nodo_categoria;

        // Buscamos la categoria con el id correcto.
        titulo_categ_global = "";
        for (var i = 0; i < xml_categorias.length; i++) {
            nodo_categoria = xml_categorias[i];
            if (nodo_categoria.getAttribute("id") == id) {
                titulo_categ_global = nodo_categoria.getAttribute("titulo");
                break;
            }
        }
        
        if (titulo_categ_global != "") {
        	// Obtenemos la plantilla del XML.
        	var xml_plantilla = xml_global.documentElement.getElementsByTagName("plantilla");
        	
            // Guardamos el id de la categoria.
            id_categoria_global = i;

            // Obtenemos los elementos nombrados con etiquetas "centro"
            var xml_centro = nodo_categoria.getElementsByTagName("centro");

            // Especificamos las coordenadas del centro del mapa.
            map.setCenter(new GLatLng(parseFloat(xml_centro[0].getAttribute("lat")), parseFloat(xml_centro[0].getAttribute("lng"))), parseInt(xml_centro[0].getAttribute("zoom")));

            // Obtenemos los elementos nombrados con etiquetas "iconobase" e "icono",
            // con los datos de configuracion del icono base y de los iconos personalizados.
            var xml_iconobase = nodo_categoria.getElementsByTagName("iconobase");
            var xml_icono = nodo_categoria.getElementsByTagName("icono");

            // Creamos un icono base con la configuracion.
            var baseIcon = new GIcon(G_DEFAULT_ICON);
            baseIcon.shadow = xml_iconobase[0].getAttribute("nombre");
            baseIcon.iconSize = new GSize(parseInt(xml_iconobase[0].getAttribute("ancho")), parseInt(xml_iconobase[0].getAttribute("alto")));
            baseIcon.shadowSize = new GSize(parseInt(xml_iconobase[0].getAttribute("s_ancho")), parseInt(xml_iconobase[0].getAttribute("s_alto")));
            baseIcon.iconAnchor = new GPoint(parseInt(xml_iconobase[0].getAttribute("ancla_x")), parseInt(xml_iconobase[0].getAttribute("ancla_y")));
            baseIcon.infoWindowAnchor = new GPoint(parseInt(xml_iconobase[0].getAttribute("i_ancla_x")), parseInt(xml_iconobase[0].getAttribute("i_ancla_y")));

            // Obtenemos los elementos nombrados con etiquetas "marker".
            var xml_markers = nodo_categoria.getElementsByTagName("marker");

            // Aqui almacenaremos el objeto de la marca recien creada.
            var nuevo_marker;

            // Hacemos un bucle para anyadir todas las marcas al mapa.
            for (var i = 0; i < xml_markers.length; i++) {
                            
                // Creamos el punto con la info. de las coordenadas.
                var point = new GLatLng(parseFloat(xml_markers[i].getAttribute("lat")), parseFloat(xml_markers[i].getAttribute("lng")));
               
                // Array donde almacenaremos los datos adicionales
                // de la marca.
                var datos_adic = new Object();
                                                
                datos_adic["id_topic"] = parseInt(xml_markers[i].getAttribute("topic"));
                datos_adic["id_forum"] = parseInt(xml_markers[i].getAttribute("forum"));
                datos_adic["urlbase"] = xml_icono[0].getAttribute("urlbase") + xml_icono[0].getAttribute("nombre");
                datos_adic["extension"] = xml_icono[0].getAttribute("ext");
                
                // Obtenemos la marca.
                nuevo_marker = createMarker(datos_adic, baseIcon, point, i, "");
                
                // La anyadimos al array de marcas.
                marcas_global.push(nuevo_marker);
                topics_marcas_global.push(datos_adic["id_topic"]);

                // Anyadimos la marca al mapa.
                map.addOverlay(nuevo_marker);
            }
        }
    }

    if (GBrowserIsCompatible()) {
        if($("#map")[0]) {      
            GEvent.addListener(map, 'click', function(overlay, point){
            	if (point) {
            		// Quitamos la marca anterior del mapa.
            		if (nueva_marca_global) map.removeOverlay(nueva_marca_global);
            		
            		// Creamos un icono para la marca.
                    var icono = new GIcon(G_DEFAULT_ICON);
                    icono.iconSize = new GSize(20, 34);
                    icono.shadowSize = new GSize(37, 34);
                    icono.iconAnchor = new GPoint(10, 34);
                    icono.infoWindowAnchor = new GPoint(10, 34);

                    // Creamos la nueva marca y la añadimos al mapa.
            		nueva_marca_global = new GMarker(point, {icon: icono});
                    map.addOverlay(nueva_marca_global);
                    map.getCenter(point);
                    
                    // Pedimos la plantilla al servidor.
                    plt_ObtenerFormAltaMarca(nueva_marca_global, getCookie("cat"));
                }
            });
            
            GEvent.addListener(map.getInfoWindow(), 'closeclick', function(){ 
            	if (nueva_marca_global) { map.removeOverlay(nueva_marca_global); }
            });
        }
    }

}
//function pedirPlantilla(response){
//    // Creamos un icono para la marca.
//    var icono = new GIcon(G_DEFAULT_ICON);
//    icono.iconSize = new GSize(20, 34);
//    icono.shadowSize = new GSize(37, 34);
//    icono.iconAnchor = new GPoint(10, 34);
//    icono.infoWindowAnchor = new GPoint(10, 34);
//
//    var place = response.Placemark[0];
//    var point = new GLatLng(place.Point.coordinates[1],
//                            place.Point.coordinates[0]);
//
//    nueva_marca_global = new GMarker(point, {icon: icono});
//    map.addOverlay(nueva_marca_global);
//    map.getCenter(point);
//    
//}


//RESTRICCIONES DE DESPLAZAMIENTO Y ZOOM

// Constructor
TRestricter = function (map) {
  this.map = map;
}

// Función que activa la limitación del desplazamiento entre la esquina inferior izquierda
// y la esquina superior derecha
TRestricter.prototype.restrict = function (sw, ne) {
  this.map._allowedBounds = new GLatLngBounds(sw, ne);
  GEvent.addListener(this.map, 'move', this.checkBounds);
}

// Función que desactiva la limitación del desplazamiento
TRestricter.prototype.unrestrict = function () {
  this.map._allowedBounds = null;
}

// Listener encargado de comprobar el desplazamiento
TRestricter.prototype.checkBounds = function() {
  if (!this._allowedBounds || this._allowedBounds.contains(this.getCenter())) return;
  var x = Math.min(Math.max(this.getCenter().lng(), this._allowedBounds.getSouthWest().lng()), this._allowedBounds.getNorthEast().lng());
  var y = Math.min(Math.max(this.getCenter().lat(), this._allowedBounds.getSouthWest().lat()), this._allowedBounds.getNorthEast().lat());
  this.setCenter(new GLatLng(y,x));
}

// Establece los límites de zoom del mapa
TRestricter.prototype.zoomLevels = function (min, max) {
  var array = this.map.getMapTypes() || [];
  for (var i=0; i<array.length; i++) {
    array[i].getMinimumResolution = function () { return min };
    array[i].getMaximumResolution = function () { return max };
  }
}

//FIN DE RESTRICCIONES DE DESPLAZAMIENTO Y ZOOM


// Función que se encarga de crear el listado de categorías.
            
function crear_categorias() {
    var xml_categorias = xml_global.documentElement.getElementsByTagName("categoria");
    var xml_marcas;

    // Obtenemos el objeto DOM de la capa para la lista de categorias.
    var area_div = document.getElementById("lista_categorias");

    // Limpiamos la capa antes de crear la lista.
    for (var k = 0; k < area_div.childNodes.length; k++) {
        area_div.removeChild(area_div.childNodes[0]);
    }

    // Nivel 1: categorias
    // Nivel 2: marcas
    var nivel_1 = document.createElement("ul")
    var nivel_2;

    var elem_li;
    var elem_a;
    var muestraCapa_a;
    var id_categoria;
    var path = GEOK_DIR_BASE + "/" + GEOK_PATH_IMAGENES + "/";

    //Definimos el UL sin estilo
    nivel_1.style.listStyleType = "none";
    nivel_1.style.margin = "0px";
 		nivel_1.style.padding = "0px";
		
    // Nivel 1 (categorias).
    for (var i = 0; i < xml_categorias.length; i++) {
        id_categoria = parseInt(xml_categorias[i].getAttribute("id"));
        elem_li = document.createElement("li");
        elem_a = document.createElement("a");
        elem_a.innerHTML = "&nbsp;" + xml_categorias[i].getElementsByTagName("titulo")[0].firstChild.data;

        elem_li.style.padding = "2px";
        muestraCapa_a = document.createElement("a");
                
        //Damos formato al +/-
        muestraCapa_a.innerHTML = "<img src='" + path + "b_plus.png' border='0' />";
        muestraCapa_a.setAttribute("id", "Opc"+id_categoria);
        muestraCapa_a.setAttribute("href", "javascript:Muestra(" + id_categoria + ");");
        muestraCapa_a.setAttribute("title", "Expandir");
        elem_li.appendChild(muestraCapa_a);

        elem_a.setAttribute("href", "javascript: pulsar_categoria(" + id_categoria + ");");

        //NUEVO
        //Funciona Safari, IE y Firefox, no en Opera:
        var clase = document.all ? "className" : "class";
        //elem_a.setAttribute(clase, "enlace_categorias");
				
        //color_categoria = i + 1;
        // elem_a.setAttribute(clase, "categoria"+color_categoria);
        elem_a.setAttribute(clase, "categoria");

        //elem_a.setAttribute("href", "javascript: crear_mapa(" + id_categoria + ")" +
        //   (id_categoria_global == id_categoria ? "" : "; crear_categorias();"));

        elem_li.appendChild(elem_a);
        nivel_2 = nivel_1.appendChild(elem_li).appendChild(document.createElement("ul"))
        xml_marcas = xml_categorias[i].getElementsByTagName("marker");


        // Nivel 2 (marcas).
        for (var j = 0; j < xml_marcas.length; j++) {
            elem_li = document.createElement("li");
            elem_a = document.createElement("a");
            elem_a.innerHTML = xml_marcas[j].firstChild.data;

                        
            //Nuevo
            elem_li.style.padding = "2px";
            nivel_2.style.listStyleType = "none";
		
           // color_marca = i + 1;

            //elem_a.setAttribute(clase, "enlace_marcas");
           // elem_a.setAttribute(clase, "enlace_categoria"+color_marca);
 						elem_a.setAttribute(clase, "enlace_categoria");
            nivel_2.setAttribute("id", "SubOpc"+id_categoria);
            nivel_2.setAttribute("title", "Ver");

            nivel_2.style.display = 'none';
            nivel_2.style.listStyleImage="url('" + path + "b_marcas.gif')";

            elem_a.setAttribute("href", "javascript: pulsar_marca(" + id_categoria + 
           		", " + j + ", " + xml_marcas[j].getAttribute("forum") + 
           		", " + xml_marcas[j].getAttribute("topic") + ");");

            elem_li.appendChild(elem_a);
            nivel_2.appendChild(elem_li);
        }
    }

    area_div.appendChild(nivel_1);
}

// Función que muestra el listado de puntos de una categoría.

function Muestra(id)
{

    document.getElementById("Opc"+id).innerHTML = "<img src='" + GEOK_DIR_BASE + "/" + GEOK_PATH_IMAGENES + "/b_minus.png' border='0' />";
    document.getElementById("Opc"+id).setAttribute("href", "javascript:Oculta(" + id + ");");
    document.getElementById("Opc"+id).setAttribute("title", "Cerrar");
    document.getElementById("SubOpc"+id).style.display='block';
}

// Función que oculta el listado de puntos de una categoría.

function Oculta(id)
{
    document.getElementById("Opc"+id).innerHTML = "<img src='" + GEOK_DIR_BASE + "/" + GEOK_PATH_IMAGENES + "/b_plus.png' border='0' />";
    document.getElementById("Opc"+id).setAttribute("href", "javascript:Muestra(" + id + ");");
    document.getElementById("Opc"+id).setAttribute("title", "Expandir");
    document.getElementById("SubOpc"+id).style.display = 'none';
}            

// Función que se encarga de ajustar el tamaño de la capa que contiene el
// mapa al tamaño de la ventana del navegador.

function ajustar_mapa_a_pantalla() {
	var width, height;
	
	if (typeof(window.innerWidth) != "undefined") {
		width = window.innerWidth;
		height = window.innerHeight;
	} else if (typeof(document.documentElement) != "undefined"
		&& typeof(document.documentElement.clientWidth) != "undefined" 
		&& document.documentElement.clientWidth != 0) {
	        width = document.documentElement.clientWidth;
	        height = document.documentElement.clientHeight;
	} else {
		width = document.getElementsByTagName("body")[0].clientWidth;
		height = document.getElementsByTagName("body")[0].clientHeight;
	}
	
	// Establecemos la altura mínima del mapa.
	if (GEOK_ALTURA_MIN_MAPA > 0 && height < GEOK_ALTURA_MIN_MAPA) height = GEOK_ALTURA_MIN_MAPA;
	
	// En función del navegador, habría que restar una cantidad 
	// distinta al alto/ancho...
	document.getElementById("map").style.width = width + "px";
	document.getElementById("map").style.height = height + "px";
}

