/*jslint browser: true, devel:true, forin: true */
// --- INICIALIZACION ---
function initRouteForm(scope) {
	var oScope = scope || document,
		$contenedor = jQuery('#caja-rutas', oScope),
		$selector = jQuery('div.caja-rutas-selector a', $contenedor),
		$map = jQuery('#divMapa', oScope),
		sAnchor = document.location.href.getAnchor(),
		reRouteSelected = /-\d+$/g;
		
	// init styles
	if (sAnchor && jQuery(sAnchor.replace(reRouteSelected, ''), $contenedor).length){
    $contenedor.css('left', '0');
    $map.css('marginLeft', '320px');
    jQuery('#desplegar-caja-rutas', oScope).addClass('active');
  }
	else {
		$contenedor.css('left', '-320px');
		$map.css('marginLeft', '0');
		jQuery('#desplegar-caja-rutas', oScope).removeClass('active');
	}
	jQuery('#nueva-ruta-form fieldset').filter('.ruta-repeticion, .ruta-info-adicional').hide();
	
	// cache de input values in case subwindows are switched
	cacheInputs($contenedor);
	
	// init periodicity selector
	jQuery('fieldset.ruta-repeticion :radio', oScope).each(function () {
		var $t = jQuery(this);
		$t.closest('label').next('div')[$t.is(':checked') ? 'show' : 'hide']();
	});
	 
	// select change event AND custom event for fieldset.definir-punto that trigger the actual route search
	jQuery('select[name*=optimizacion]', oScope).change(checkFullRoute);
	jQuery('fieldset.definir-punto', oScope).bind('pointchange', checkFullRoute);

	// init #gestiona-ruta-form hidden data
	jQuery('#gestiona-ruta-form form').each(function () {
		var $form = jQuery(this),
			$fieldPunto = $form.find('fieldset.definir-punto'),
			sWkt = $form.find('input[name*=wkt]').val(),
			oOrigenDestino = getStartEndFromWkt( sWkt );
		 $form.data('oRuta', sWkt);
		 $fieldPunto.eq(0).data('oPoint', oOrigenDestino.origen);
		 $fieldPunto.eq(1).data('oPoint', oOrigenDestino.destino);
	});
  
    // checking if something inside #gestiona-ruta-form is to be shown inmediately
    if (reRouteSelected.test(sAnchor) && jQuery(sAnchor, $contenedor).is('form')) {
		(function recursiveCercaliaCheck() {
        if (cercalia && cercalia.createFeature && cercalia.createMarker && cercalia.controls && cercalia.controls.map) {
				var $panel = jQuery(sAnchor),
				    $button = $panel.closest('li').find('a.showPanel:first');
				if (!$panel.is('.shown')) {
					$button.click();
				} else {
					$panel.trigger('show');
				}
			} else {
			    setTimeout(recursiveCercaliaCheck, 100);
			}
		})();
    }
    
    // checking if something inside #busca-ruta-form is to be shown inmediately
    if ((/\/ruta\/\d+/g).test(document.location.href)) {
        (function recursiveCercaliaCheck(){
            if (cercalia && cercalia.createFeature && cercalia.createMarker && cercalia.controls && cercalia.controls.map) {
				jQuery('#busca-ruta-form ul.resultados-rutas a.showPanel:first').click();
            }
            else {
                setTimeout(recursiveCercaliaCheck, 100);
            }
        })();
    }
	
  // init subtab selector
  $selector.filter('[href*='+ sAnchor.replace(reRouteSelected, '') +']').addClass('active').siblings().removeClass('active');
  if ($selector.filter('.active').length!==1) {
    $selector.eq(0).addClass('active').nextAll().removeClass('active');
  }
  $selector.filter('.active').click();
	
	// make sure ajax loader exists and is hidden
	handleMapAjax('hide');
}

// --- DEFINICION DE EVENTOS ---
jQuery(function($){
    // evento para desplegar/plegar la pestanya de rutas entera
    jQuery('#desplegar-caja-rutas').bind('click', function(){
        var $t = jQuery(this).toggleClass('active'), nDir = ($t.hasClass('active') ? '+' : '-') + '=320';
        jQuery('#caja-rutas').animate({
            left: nDir
        }, 400);
        jQuery('#divMapa').animate({
            marginLeft: nDir
        }, 400);
        
    });
    
    // evento para mostrar/ocultar las secciones del interior de la pestanya ruta
    jQuery('div.caja-rutas-selector a').bind('click', function(){
        var $t = jQuery(this), $toShow, $toHide;
        // gestion de clases del menu:
        $t.addClass('active').siblings().removeClass('active');
        // gestion de visibilidad de los DIV
        $toShow = jQuery($t.attr('href').getAnchor()).show();
        $toHide = $toShow.siblings().not('div.caja-rutas-selector').hide();
        if (cercalia) {
            $toHide.trigger('sectionchange');
        }
        return false;
    });
    
    // evento para mostrar/ocultar los DIVs de periodicidad
    jQuery('fieldset.ruta-repeticion label:has(:radio)').bind('click', function(){
        revertToCacheInputs(jQuery(this).next('div').slideDown().siblings('div').slideUp());
    });
    
    // evento de busqueda de rutas por ciudad (ajax pino)
    // al enviar el formulario cancelamos el bubbling y metemos una llamada en AJAX
    // a un JSON, parseamos
    jQuery('#busca-ruta-form form').bind('submit', function(){
        var $t = jQuery(this), $text = $t.find(':text');
        // eliminamos los resultados anteriores:
        $t.next('.resultados-rutas').slideUp('fast', function(){
            var $p = jQuery(this);
            $p.find('div.panel.shown').trigger('hide');
            $p.remove();
        });
        // comprobamos si los valores son iguales a la cache (que en este caso es algo asi como "escriba la ciudad de origen")
        if ($text.eq(0).val() === $text.eq(0).data('cache') || $text.eq(0).val() === $text.eq(0).data('cache')) {
            // y lo paramos si es asi
            return false;
        }
        // llamada en AJAX:
				handleMapAjax('show');
        jQuery.ajax({
            url: $t.attr('action'),
            type: 'GET',
            data: $t.serialize(),
            cache: false,
            // el callback realiza el parseo del JSON y reasigna eventos:
            complete: parseRouteSearch
        });
        return false;
    });
    
    // Editar los campos de direccion
    jQuery('fieldset.definir-punto :input').bind('focus', checkPointChange).bind('keyup', function recursiveCheck(){
        var $t = jQuery(this);
        clearTimeout($t.data('timer'));
        $t.data('timer', setTimeout(function(){
            checkPointChange.apply($t);
        }, 1250));
        
    }).bind('change', function(){
        var $t = jQuery(this);
        if (!$t.val()) {
            checkFullAddress($t.closest('fieldset'));
            $t.data('checkchanged', $t.val());
        }
    });
		
		jQuery('#nueva-ruta-form :reset').bind('click', function () {
			var $form = jQuery(this).closest('form');
			$form.find(':text').val('');
			$form.find('fieldset.definir-punto').data('oPoint', null);
			checkFullRoute({currentTarget:this});
			return false;
		});
    
    // Mantener solo un resultado de .resultados-rutas activo
    jQuery('.resultados-rutas .panel').bind('show', function(){
        var $li = jQuery(this).closest('li');
        $li.siblings().find('a.showPanel.active').click();
        drawRouteWkt($li.find('input[name*=wkt]').val());
    }).bind('hide', function(){
        cercalia.deleteFeatures();
        cercalia.deleteMarkers("origen");
        cercalia.deleteMarkers("destino");
    });
    
    // Mostrar/ocultar ruta en "Mis rutas" cuando se despliega
    jQuery('#gestiona-ruta-form form.panel').bind('show', function(){
        jQuery(this).closest('li').show().siblings().hide();
        cercalia.deleteFeatures();
        cercalia.deleteMarkers("origen");
        cercalia.deleteMarkers("destino");
        drawRouteWkt(jQuery(this).find('input[name*=wkt]').val());
    }).bind('hide', function(){
			  jQuery(this).closest('li').siblings().show();
        cercalia.deleteFeatures();
        cercalia.deleteMarkers("origen");
        cercalia.deleteMarkers("destino");
    });
		
		// Auto-cerrar el panel si le damos a cancelar
		jQuery('#gestiona-ruta-form button[type=reset]').bind('click', function () {
			  jQuery(this).closest('li').find('a.showPanel.active').click();
		});
    
    // Form validation!
    jQuery('#nueva-ruta-form form').bind('submit', checkRouteSubmission);
    jQuery('#gestiona-ruta-form form').bind('submit', checkRouteSubmission);
    
    // Los siguientes tres eventos estan pensados para limpiar y resetear formularios cuando se cambia de seccion
    // Evento personalizado para #nueva-ruta-form
    jQuery('#nueva-ruta-form').bind('sectionchange', function(){
        revertToCacheInputs(this);
    });
    // Evento personalizado para #resultados-rutas
    jQuery('#busca-ruta-form').bind('sectionchange', function(){
        revertToCacheInputs(this);
        jQuery(this).find('.resultados-rutas').find('div.panel.shown').trigger('hide').end().remove();
    });
    // Evento personalizado para #gestiona-ruta-form
    jQuery('#gestiona-ruta-form').bind('sectionchange', function(){
        revertToCacheInputs(this);
        jQuery(this).find('a.showPanel.active').click();
    });
    
    // Evento de pulsar un link que lleva a una ruta concreta desde fuera de
	// todo el tinglado
	jQuery('a[href*=gestiona-ruta-form-]').bind('click', function() {
		var $form = jQuery(jQuery(this).attr('href').getAnchor());
		if ($form.length) {
			jQuery('#caja-rutas-inner a[href*=gestiona-ruta-form]:first').not('.active').click();
			setTimeout(function () {
				$form.closest('li').find('a.showPanel:first').not('.active').click();
			}, 1000);
			jQuery('#desplegar-caja-rutas:not(.active)').click();
			return false;
		}
	});
    
    // mostrar/ocultar prediccion meteo
    jQuery('#toggle-weather').bind('click', function() {
        localidadesPoi = !localidadesPoi;
        if (localidadesPoi) {
            Poi.codigos_activos.push("D00A13AB");
            ApiAbertis.mostrarPoiCodigo('D00A13AB'); 
        }
        else {
            Poi.desactivar("D00A13AB");
        }
    })[localidadesPoi?'addClass':'removeClass']('active');
	if (typeof transitAct === 'undefined') transitAct = false;
	jQuery('#toggle-traffic').bind('click', function () {
		if(transitAct){
			cercalia.layerLocalitatsPNOA.setVisibility(false);
			cercalia.getMap().baseLayer.hideTrafficOverlay();
			transitAct = false;
		}
		else{
		 	cercalia.layerLocalitatsPNOA.setVisibility(true);
			cercalia.getMap().baseLayer.showTrafficOverlay();
			transitAct = true;
		}
	})[transitAct?'addClass':'removeClass']('active');
});

// --- HELPER FUNCTIONS ---
function checkPointChange(){
    var $t = jQuery(this), $fieldset = $t.closest('fieldset'), $input = $fieldset.find(':input'), sVal = $t.val();
    if ($t.data('checkchanged') !== sVal && sVal.length > 2) {
        $t.data('checkchanged', sVal);
        // marcamos el fieldset como no-valido, y eliminamos los resultados que ya habia
        $fieldset.data('oPoint', false).trigger('pointchange');
        if ($input.filter('input[name*=ciudad]').val()) {
            checkFullAddress($fieldset);
        }
    }
}
/**
 * Takes the inputs from a fieldset and calls cercalia to check if the results return an error, 1 or
 * even more candidates
 * @param {jQuery element} $fieldset
 */
function checkFullAddress($fieldset){
    var $input = $fieldset.find(':input'),
		    aDireccion = $input.filter('input[name*=calle]').val().split(','),
				oGeoInfo = {
		        ctryc: $input.filter('select[name*=pais]').val(),
		        ctn: $input.filter('input[name*=ciudad]').val(),
		        stn: unescape(jQuery.trim(aDireccion[0]) || ''),
		        stnum: jQuery.trim(aDireccion[1]) || null
		    };
    // hacemos la llamada a la API
		handleMapAjax('show');
    cercalia.geocoding(oGeoInfo, function(r){
        handleMapAjax('hide');
        var datos = r.candidates, $prevResults = jQuery('.resultados-puntos', $fieldset), aHtml = [], i, l;
        // AJAX correcto
        if (datos && datos.length === 1 && datos[0].ge && $fieldset.data('oPoint') != datos[0].ge) {
            // hay solo un candidato
            // pues lo pintamos y finalizamos limpiando resultados de haberlos, hala
            if (jQuery(document.activeElement).closest('fieldset').get(0) === $fieldset.get(0)) {
                // si el elemento activo esta en el $fieldset solo trasladamos el dato al $fieldset
                $fieldset.data('oPoint', datos[0].ge).trigger('pointchange');
            }
            else {
                // si no, hacemos todo el proceso de printado
                objectToInputs(datos[0].ge, $fieldset);
            }
            $prevResults.slideUp('fast', function(){
                jQuery(this).remove();
            });
            return;
        }
        else 
            if (datos && datos.length > 1) {
                // si hay mas de un candidato hacemos un listadico
                aHtml.push('<div class="resultados-puntos"><strong>', texts[lang].talVezQuisoDecir, '</strong><ul>');
                for (i = 0, l = datos.length; i < l; ++i) {
                    aHtml.push('<li>');
                    aHtml.push(datos[i].desc);
                    aHtml.push('</li>');
                    // si el objeto GeoEntity no tiene asignado un houseNumber le ponemos el input de usuario
                    datos[i].ge.houseNumber = datos[i].ge.houseNumber || oGeoInfo.stnum;
                }
                aHtml.push('</ul>');
            }
            else {
                // si no hay datos 
                aHtml.push('<ul class="resultados-puntos sin-resultados" style="display:none"><li>');
                aHtml.push(texts[lang].noHayResultados);
                aHtml.push('</li></ul></div>');
            }
        // insertamos el listado
        // eliminando los resultados de busqueda de puntos en caso de haberlos
        if ($prevResults.length) {
            $prevResults.replaceWith(aHtml.join(''));
        }
        else {
            jQuery(aHtml.join('')).hide().appendTo($fieldset).slideDown();
        }
        // y preparamos los eventos para incrustarlos en el campo		
        jQuery('.resultados-puntos', $fieldset).not('.sin-resultados').find('li').click(function(){
            var $t = jQuery(this), obj = datos[$t.closest('ul').children().index($t)];
            objectToInputs(obj.ge, $fieldset);
            jQuery('div.resultados-puntos', $fieldset).slideUp('fast', function(){
                jQuery(this).remove();
            });
        });
    });
}

/**
 * Checks the information inside a FORM and draws a new route related to it if needed
 * @param {Object} ev DOM Event Object (only currentTarget is relevant to define the scope, so it can be called passing an object with this property)
 */
function checkFullRoute(ev){
    var $form = jQuery(ev.currentTarget).closest('form'), $fieldset = $form.find('fieldset'), $origen = $fieldset.filter('fieldset.definir-punto').eq(0), $destino = $origen.next(), $masInfo = $fieldset.filter('.ruta-repeticion, .ruta-info-adicional'), oOrigen = $origen.data('oPoint'), oDestino = $destino.data('oPoint'), sOptimizacion = $origen.parent().find('select[name*=optimizacion]').val();
    // ocultamos la ruta dibujada por el formulario antes de calcular la nueva
    cercalia.deleteFeatures();
    cercalia.deleteRoute($form.data('oRuta'));
    $form.data('oRuta', null);
    cercalia.deleteMarkers("origen");
    cercalia.deleteMarkers("destino");
		jQuery('#descriptivo-ruta').remove();
    $form.find('input[name*=wkt]').val('');
    $form.find('input[name*=tiempo]').val('');
    $form.find('input[name*=distancia]').val('');
    $form.find('input[name*=coste]').val('');
    // y comprobamos si ambos puntos estan guays y el formulario es visible para mostrar la ruta
    if (oOrigen && oDestino && $form.is(':visible')) {
        // aqui definimos la nueva ruta y volvemos a limpiar la anterior por si mientras cargaba el AJAX se ha pintado otra
        $form.data('oRuta', null);
        cercalia.deleteMarkers("origen");
        cercalia.deleteMarkers("destino");
        // debemos traducir nuestros String de optimizacion ('p', 'd' o 't') a lo que pide Cercalia
        sOptimizacion = {
            'p': 'money',
            'd': 'distance',
            't': 'time'
        }[sOptimizacion];
        // pillo esta configuracion de la ruta del ejemplo de Cercalia
        var routeParams = {
            weight: sOptimizacion,
            tolerance: 25,
            poitolerance: 25,
            xml: false,
            report: true,
            lang: lang,
            reorder: false,
            intoll: [2, -1],
            poiwkt: true,
            infoxml: 1
        };
        var lineStyle = {
            strokeWidth: 6,
            strokeColor: "#735D94",
            strokeOpacity: 0.7,
            fillOpacity: 0.8
        };
        var stopList = [{
            x: oOrigen.x,
            y: oOrigen.y
        }, {
            x: oDestino.x,
            y: oDestino.y
        }];
		handleMapAjax('show');
        cercalia.calculateRoute(stopList, routeParams, lineStyle, false, function(datos){
            handleMapAjax('hide');
            var ruta = datos.ruta, markerStyle = {
		                icon: appRoot + 'img/A.gif',
		                width: 23,
		                height: 46,
		                visible: false,
		                minimized: false,
		                cssTitle: "contTitolPopup",
		                noHideOthers: true,
		                position: "tr",
		                panMapIfOutOfView: false,
		                offsetY: -20,
		                offsetX: 0
                },
			nLastIndex = ruta.stoplist.length - 1;
			// mostramos la ventana de informacion adicional
            $masInfo.show();
            // anyadimos el primer marcador
            cercalia.createMarker("origen", ruta.stoplist[0].x, ruta.stoplist[0].y, "EPSG:54004", markerStyle);
            // redefinimos un par de variables y anyadimos el segundo
            markerStyle.icon = appRoot + 'img/B.gif';
            cercalia.createMarker("destino", ruta.stoplist[nLastIndex].x, ruta.stoplist[nLastIndex].y, "EPSG:54004", markerStyle);
            // guardamos el objeto ruta en su sitio y actualizamos campos pertinentes
            $form.data('oRuta', ruta);
            $form.find('input[name*=wkt]').val(ruta.wkt[0]);
            $form.find('input[name*=tiempo]').val(ruta.time);
            $form.find('input[name*=distancia]').val([ruta.distance, 'Km'].join(''));
            $form.find('input[name*=coste]').val([ruta.coste_v1 || '0', '€, ', ruta.coste_v2 || '0', '€, ', ruta.coste_v3 || '0', '€'].join(''));
						parseRouteDetails(ruta.stages[0].substages);
        }, true);
    }
    else {
        revertToCacheInputs($masInfo.hide());
    }
}

/**
 * Checks if point and route objects are correctly attached to the form
 * @return {Boolean} if false the form submission is cancelled and the event stops bubbling
 */
function checkRouteSubmission(){
    var $form = jQuery(this), $fieldPunto = $form.find('fieldset.definir-punto');
    // comprobamos los puntos
    if (!$fieldPunto.eq(0).data('oPoint') || !$fieldPunto.eq(1).data('oPoint')) {
        if (!$fieldPunto.eq(0).data('oPoint')) {
            checkFullAddress($fieldPunto.eq(0));
        }
        if (!$fieldPunto.eq(1).data('oPoint')) {
            checkFullAddress($fieldPunto.eq(1));
        }
    }
    else if (!$form.data('oRuta')) {
        checkFullRoute($form.children().eq(0));
    }
    else {
        return true;
    }
    return false;
}

/**
 * Takes a WKT-like definition of route (point to point, comma separated) and draws it into the map, printing two markers in the process
 * @param {String} sWkt
 */
function drawRouteWkt(sWkt){
    var oOrigenDestino = getStartEndFromWkt(sWkt), oOrigen = oOrigenDestino.origen, oDestino = oOrigenDestino.destino,
        markerStyle = {
        icon: appRoot + 'img/A.gif',
        width: 23,
        height: 46,
        visible: false,
        minimized: false,
        cssTitle: "contTitolPopup",
        noHideOthers: true,
        position: "tr",
        panMapIfOutOfView: false,
        offsetY: -20,
        offsetX: 0
    },
    sSrs = "EPSG:54004";
    // creamos la ruta y los puntos
    cercalia.createFeature(sWkt, sSrs, {
        strokeWidth: 6,
        strokeColor: "#735D94",
        strokeOpacity: 0.7,
        fillOpacity: 0.8
    });
    cercalia.createMarker("origen", oOrigen.x, oOrigen.y, sSrs, markerStyle);
    markerStyle.icon = appRoot + 'img/B.gif';
    cercalia.createMarker("destino", oDestino.x, oDestino.y, sSrs, markerStyle);
    // parseInt de todas las variables de oOrigenDestino para poder operar matematicamente
    oOrigen.x = parseInt(oOrigen.x, 10);
    oOrigen.y = parseInt(oOrigen.y, 10);
    oDestino.x = parseInt(oDestino.x, 10);
    oDestino.y = parseInt(oDestino.y, 10);
    cercalia.setCenter({
        x: (oOrigen.x + oDestino.x) / 2,
        y: (oOrigen.y + oDestino.y) / 2,
        srs: sSrs
    }, 3);
    cercalia.zoomToExtent({
        x1: Math.min(oOrigen.x, oDestino.x),
        y1: Math.min(oOrigen.y, oDestino.y),
        x2: Math.max(oOrigen.x, oDestino.x),
        y2: Math.max(oOrigen.y, oDestino.y)
    }, sSrs)
}

/**
 * Takes a WKT-like definition of route and returns its start and end coordinates
 * @param {String} sWkt
 * @return {Object} obj containing both origin and arrival coordinates in x and y properties
 */
function getStartEndFromWkt(sWkt){
    var obj = {
        origen: {},
        destino: {}
    }
	if (sWkt.indexOf('MULTILINESTRING') > -1) {
		// si es un MULTILINESTRING primero despiezamos todo quitando los puntos intermedios
		var aDespiece = sWkt.replace(/[A-Z]+.*\(\((.+)\)\)/g, '$1').split('), ('), i, j, l, m;
		for (i = 0, l = aDespiece.length; i<l; ++i) {
			aDespiece[i] = aDespiece[i].replace(/^(\d+\s\d+,).+(\s\d+\s\d+)$/g, '$1$2').split(', ');
		}
        // ahora comparamos uno a uno para averiguar el inicio
        for (i = 0, l = aDespiece.length; i < l; ++i) {
            for (j = 0, m = aDespiece.length; j < m; ++j) {
                if (aDespiece[i][0] == aDespiece[j][1]) {
                    break;
                }
            }
            if (!aDespiece[j] || aDespiece[i][0] != aDespiece[j][1]) {
                break;
            }
        }
        obj.origen.x = aDespiece[i][0].split(' ')[0];
        obj.origen.y = aDespiece[i][0].split(' ')[1];
        // ahora comparamos uno a uno para averiguar el final
        for (i = 0, l = aDespiece.length; i < l; ++i) {
            for (j = 0, m = aDespiece.length; j < m; ++j) {
                if (aDespiece[i][1] == aDespiece[j][0]) {
                    break;
                }
            }
            if (!aDespiece[j] || aDespiece[i][1] != aDespiece[j][0]) {
                break;
            }
        }
        obj.destino.x = aDespiece[i][1].split(' ')[0];
        obj.destino.y = aDespiece[i][1].split(' ')[1];
	}
	else {
		var aDespiece = sWkt.replace(/.+\((.+)\).*/g, '$1').replace(/\s*,\s*/g, ',').split(','),
	        nLastIndex = aDespiece.length - 1;
	    // definimos los puntos a partir del despiece de la geometria
	    obj.origen.x = aDespiece[0].split(' ')[0];
	    obj.origen.y = aDespiece[0].split(' ')[1];
	    obj.destino.x = aDespiece[nLastIndex].split(' ')[0];
	    obj.destino.y = (aDespiece[nLastIndex].split(' ')[1] || '').replace(/\D/g, '');	
	}
    return obj;
}

/**
 * Takes a GeoEntity object and inserts it into a fieldset, providing it has the required fields
 * @param {Object} obj               GeoEntity object, gotten from cercalia's API 
 * @param {jQuery element} $fieldset the fieldset whose values are to be updated
 * @see checkFullAddress
 */
function objectToInputs(obj, $fieldset){
    var $input = $fieldset.find(':input');
    // actualizamos los valores
    $input.filter('input[name*=calle]').val([obj.street, obj.houseNumber].filter(function(elem){
        return elem;
    }).join(', '));
    $input.filter('input[name*=ciudad]').val(obj.city);
    $input.filter('select[name*=pais]').val(obj.countryId);
    // marcamos el fieldset como válido
    $fieldset.data('oPoint', obj).trigger('pointchange');
}

/**
 * Takes an AJAX response from the routes form (#busca-ruta-form form) and parses into HTML next to it
 * @param {Object} xhr XML-HTTP-Response object to be parsed
 * @param {String} txt text status of AJAX call
 */
function parseRouteSearch(xhr, txt){
	  handleMapAjax('hide');
    if (txt !== 'success') {
        alert(texts[lang].formError);
        return false;
    }
    var $form = jQuery('#busca-ruta-form form'),
		    $resultadosAnt = $form.find('.resultados-rutas'), 
				rutas = jQuery.parseJSON(xhr.responseText), 
				ruta = null, 
				aHtml = [], 
				aNombreDias = (jQuery.datepicker ? jQuery.datepicker._defaults.dayNamesMin : ['Do', 'Lu', 'Ma', 'Mi', 'Ju', 'Vi', 'S&aacute;']), 
				nIniSem = parseInt((jQuery.datepicker ? jQuery.datepicker._defaults.firstDay : 1), 10),
        nDse, // entero para iterar las semanas
        nDia, // entero para iterar las semanas
        nId;
		if (rutas.mensaje) {
        aHtml.push('<div class="resultados-rutas"><p>', rutas.mensaje, '</p></div>');
        if ($resultadosAnt.length) {
            $resultadosAnt.slideUp('fast', function(){
                extendDOM($resultadosAnt.replaceWith(aHtml.join('')).slideDown('fast'));
            });
        }
        else {
            extendDOM(jQuery(aHtml.join('')).insertAfter($form).slideDown('fast'));
        }
		} else {
        // si no hay mensaje empezamos a construir el elemento:
		    aHtml.push('<ul class="resultados-rutas" style="display:none;">');
		    for (nId in rutas) {
		        ruta = rutas[nId];
		        aHtml.push('<li id="ruta-', nId, '">');
		        aHtml.push('<h3 class="nombre-ruta"><a class="showPanel">');
		        // direccion origen y destino:
		        aHtml.push('<strong>', [ruta.origen.calle, ruta.origen.ciudad, ruta.origen.pais].join(', '), ' → ', [ruta.destino.calle, ruta.destino.ciudad, ruta.destino.pais].join(', '), '</strong>');
		        // es periodica?
		        if (ruta.periodicidad === "1" && ruta.semanal.semana) {
		            // si es periodica miramos la semana:
		            aHtml.push(texts[lang].periodicidad);
		            for (nDse = 0; nDse < 7; ++nDse) {
		                nDia = (nDse + nIniSem) % 7;
		                if (ruta.semanal.semana[nDia] === '1') {
		                    aHtml.push(aNombreDias[nDia], ' - ');
		                }
		                else {
		                    aHtml.push('<del>', aNombreDias[nDia], '</del>', ' - ');
		                }
		            }
		            aHtml.pop(); // me encanta como suena este metodo
		        }
		        else 
		            if (ruta.periodicidad === "0" && ruta.fecha) {
		                // si no es periodica printamos la fecha en la que se dara:
		                aHtml.push(texts[lang].fecha, ruta.fecha);
		            }
		        aHtml.push('</a></h3>');
		        // detalles de ruta:
		        aHtml.push('<div class="panel"><dl>');
		        aHtml.push('<dt>', texts[lang].duracionDelRecorrido, '</dt>');
		        aHtml.push('<dd>', ruta.tiempo, '</dd>');
		        aHtml.push('<dt>', texts[lang].distancia, ' km</dt>');
		        aHtml.push('<dd>', ruta.distancia, '</dd>');
		        aHtml.push('<dt>', texts[lang].coste, '</dt>');
		        aHtml.push('<dd>', ruta.coste.replace(/(\d+)/gi, '$1 &euro;') , '</dd>');
		        aHtml.push('</dl>');
		        aHtml.push('<p><a rel="shadowbox" href="', appRoot, 'contactoRutaForm.php?id_ruta=', ruta.idruta, '&amp;lang=', lang, '">', texts[lang].contactarPropietario, '</a></p>');
		        aHtml.push('</div>');
		        aHtml.push('<input type="hidden" name="wkt" value="', (ruta.trazado || ruta.wkt), '" />');
		        aHtml.push('</li>');
		    }
		    aHtml.push('</ul>');
		    // join the array, apply the DOM extensions and input cache and insert after the form
		    if ($resultadosAnt.length) {
		        $resultadosAnt.slideUp('fast', function(){
		            cacheInputs(extendDOM($resultadosAnt.replaceWith(aHtml.join('')).slideDown('fast')));
		        });
		    }
		    else {
		        cacheInputs(extendDOM(jQuery(aHtml.join('')).insertAfter($form).slideDown('fast')));
		    }
		}
}

function parseRouteDetails(aStages) {
	var aHtml = [], sHtml, $fieldPunto = jQuery('fieldset.definir-punto:visible'), oStage, aSenyalesTemp, i, j, l, m;
	aHtml.push('<ul id="descriptivo-ruta">');
	for (i= 0, l = aStages.length; i<l; ++i) {
		oStage = aStages[i];
		aHtml.push('<li><span class="substage-step">', (i+1), '</span><p>');
		// descripcion y tiempo
		aHtml.push(' <span class="substage-description">', oStage.desc, '</span></p>');
		aHtml.push('<p class="substage-time">');
		if (typeof oStage.time === 'string') {
			oStage.time = oStage.time.split(':');
			if (oStage.time[0] > 0) {
				aHtml.push(parseInt(oStage.time[0], 10), texts[lang]['abbrHoras']);
			}
			if (oStage.time[0] === '00' && oStage.time[1] === '00') {
				// si no hay ni horas ni minutos ponemos una aproximacion a un minuto
				aHtml.push('~1', texts[lang]['abbrMinutos']);
			}
			else {
				aHtml.push(parseInt(oStage.time[1], 10), texts[lang]['abbrMinutos']);
			}
		}
		// icono del paso de ruta
		aHtml.push('<img class="substage-icon" ');
    if (oStage.type === 'G') {
      aHtml.push('src="img/detalle-ruta/ferri.gif" alt="', texts[lang]['ferry'], '" />');
    }
    else if (oStage.type === 'R') {
      aHtml.push('src="img/detalle-ruta/rotonda.gif" alt="', texts[lang]['rotonda'], '" />');
    }
    else if (oStage.angle >= 10 && oStage.angle < 45) {
      aHtml.push('src="img/detalle-ruta/mantener_izquierda.gif" alt="" />');
    }
    else if (oStage.angle >= 45 && oStage.angle < 180) {
      aHtml.push('src="img/detalle-ruta/girar_izquierda.gif" alt="" />');
    }
    else if (oStage.angle >= 180 && oStage.angle < 315) {
      aHtml.push('src="img/detalle-ruta/girar_derecha.gif" alt="" />');
    }
    else if (oStage.angle >= 315 && oStage.angle < 315) {
      aHtml.push('src="img/detalle-ruta/mantener_derecha.gif" alt="" />');
    }
    else {
      aHtml.push('src="img/detalle-ruta/recto.gif" alt="" />');
    }
    // senyal de salida de autopista y tal
    if (
		    oStage.signal && oStage.signal.length &&
				(oStage.type === 'A' || oStage.type === 'I' || oStage.type === 'J' || oStage.type === 'K' || oStage.type === 'L' || oStage.type === 'S')
		) {
        aHtml.push('<div class="senyales-trafico">');
        for (j = 0, m = oStage.signal.length; j<m; ++j) {
            if (oStage.signal[j].type === '4E') {
							  aHtml.push(
								    '<div class="senyal-vial salida">',
								    '<div class="tipo-senyal">', texts[lang].salida, '</div>',
										'<div class="senyal-cartel ', (oStage.type==='A'?'senyal-autopista':'senyal-carretera'), '">', oStage.signal[j].value, '</div>',
										'</div>'
								);
								break;
						}
        }
        aHtml.push('</div>');
    }
    aHtml.push('</li>');
	}
	aHtml.push('</ul>');
	sHtml = aHtml.join('')
	// replace both occurrences of coordinates with the desired data
	.replace(/<b>[^<]*<\/b>/, '<strong>' + [$fieldPunto.eq(0).find('input[name*=calle]').val(), $fieldPunto.eq(0).find('input[name*=ciudad]').val(), $fieldPunto.eq(0).find('select[name*=pais]').find('option:selected').text()].filter(function (elem) {return elem}).join(', ') + '</strong>')
	.replace(/<b>[^<]*<\/b>/, '<strong>' + [$fieldPunto.eq(1).find('input[name*=calle]').val(), $fieldPunto.eq(1).find('input[name*=ciudad]').val(), $fieldPunto.eq(1).find('select[name*=pais]').find('option:selected').text()].filter(function (elem) {return elem}).join(', ') + '</strong>')
	jQuery('#descriptivo-ruta').remove();
	jQuery('#submapa').append(sHtml)
}

/**
 * stores in a local variable the current value of all form elements inside the scope
 * @param {Object} scope
 */
function cacheInputs(scope) {
	jQuery(':input', scope).each(function () {
		var $t = jQuery(this);
		$t.data('cache', $t.val());
	});
}

/**
 * sets the value of each form element inside scope to its stored cache  
 * @param {Object} scope
 */
function revertToCacheInputs(scope){
    jQuery(':input', scope).each(function(){
        var $t = jQuery(this);
        if ($t.val() !== $t.data('cache')) {
            $t.val($t.data('cache') || '');
        }
    }).change();
}

function handleMapAjax(s) {
    var $container = jQuery('#divMapa'),
        $loader = $container.children('.ajax-load');
    if (!$loader.length) {
        $loader = jQuery('<div class="ajax-load" />').appendTo($container);
		}
		$loader[s === 'show' ? s : 'hide']();
}

// launch app
jQuery(function(){
    initRouteForm(document);
});

jQuery('input[name="horario"]').live('focus', function() {
   var $t = jQuery(this);
   $t.data('cache',$t.data('cache') || $t.val()) 
   if($t.val() === $t.data('cache')) {
       $t.val(''); 
   }
}).live('blur', function() {
   if($t.val() === '') {
       $t.val($t.data('cache'));
   }
});

