/* 
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
function defineGMapsIcons() {
	HUSA_DEFAULT_ICON = new GIcon(G_DEFAULT_ICON, approot+'img/mapas/_defaultIcon.png');
	HUSA_DEFAULT_ICON.shadow = approot+'img/mapas/_shadow.png';
	HUSA_DEFAULT_ICON.transparent = approot+'img/mapas/_transparent.png';
	HUSA_DEFAULT_ICON.iconSize = new GSize(25, 25);
	HUSA_DEFAULT_ICON.shadowSize = new GSize(25, 25);
	HUSA_DEFAULT_ICON.iconAnchor = new GPoint(12, 12);
	HUSA_DEFAULT_ICON.infoWindowAnchor = new GPoint(25, 0);
	HUSA_DEFAULT_ICON.imageMap = [8,0, 0,8, 0,17, 8,24, 17,24, 24,17, 24,8, 17,0];

	HUSA_HOTEL_ICON = new GIcon(HUSA_DEFAULT_ICON, approot+'img/mapas/hotel.png');
	HUSA_HOTEL_ICON.shadow = '';
	HUSA_HOTEL_ICON.transparent = approot+'img/mapas/hotelTransparent.png';
	HUSA_HOTEL_ICON.iconSize = new GSize(28, 35);
	HUSA_HOTEL_ICON.shadowSize = new GSize(28, 35);
	HUSA_HOTEL_ICON.iconAnchor = new GPoint(15, 31);
	HUSA_HOTEL_ICON.infoWindowAnchor = new GPoint(29, 8);
	HUSA_HOTEL_ICON.imageMap = [0,0, 6,9, 4,15, 15,34, 27,16, 21,5, 8,5];

	HUSA_CURRENT_HOTEL_ICON = new GIcon(HUSA_HOTEL_ICON, approot+'img/mapas/_hotel.png');
	HUSA_CURRENT_HOTEL_ICON.transparent = approot+'img/mapas/_hotelTransparent.png';
	HUSA_CURRENT_HOTEL_ICON.iconSize = new GSize(42, 52);
	HUSA_CURRENT_HOTEL_ICON.shadowSize = new GSize(42, 52);
	HUSA_CURRENT_HOTEL_ICON.iconAnchor = new GPoint(24, 50);
	HUSA_CURRENT_HOTEL_ICON.infoWindowAnchor = new GPoint(47, 15);
	HUSA_CURRENT_HOTEL_ICON.imageMap = [0,0, 9,14, 6,32, 22,52, 41,26, 28,5, 14,8];
}

// definimos un objeto mapa global para ejecutar metodos que nos interesen
// center tiene que ser un Array con latitud y longitud (en este orden)
function Mapa(elem, center, o) {
	// iniciamos variables internas
	var _t  = this,
		_el = this.elem = typeof elem == 'string' ? document.getElementById(elem) : elem,
		_o  = this.options = o || {};
		styleCache = $(_el).css('display') || '';
	_t.markers = {}; // gestion de marcadores para acceder a ellos externamente
	_t.mappedZone = [] // zona mapeada con marcadores
	if (typeof HUSA_DEFAULT_ICON == 'undefined') {
		defineGMapsIcons();
	}

	// definimos las opciones por defecto
	_o.mapTypes = _o.mapTypes || [G_NORMAL_MAP, G_SATELLITE_MAP, G_HYBRID_MAP];
	_o.zoom = _o.zoom || 13;
	_o.zoomControl = (_o.zoomControl===undefined)? new GSmallZoomControl3D() : _o.zoomControl;
	_o.mapTypeControl = (_o.mapTypeControl===undefined) ? new GMenuMapTypeControl() : _o.mapTypeControl;

	// nos aseguramos que el elemento tiene display:block
	$(_el).css({
		display:'block'
	});
	// creamos el nuevo objeto GMap2, lo asignamos a this.GMap y revertimos el atributo style del elemento
	_t.GMap = new GMap2( _el, {mapTypes: _o.mapTypes} );
	_t.GMap.setCenter(new GLatLng(center[0], center[1]), _o.zoom);
	$(_el).css('display', styleCache);

	// definimos UI, esto tal vez se cambie mas adelante para permitir customizacion
	if(_o.zoomControl) _t.GMap.addControl(_o.zoomControl);
	if (_o.mapTypeControl) _t.GMap.addControl(_o.mapTypeControl);

	// preparamos el reseteo de markers en caso de clearOverlays()
	GEvent.addListener(_t.GMap, 'clearoverlays', function(){
		_t.markers = {};
		_t.mappedZone = [];
	});

	// preparamos un evento de asignacion de eventos + extenderDOM para las ventanas
	GEvent.addListener(_t.GMap, 'infowindowopen', function() {
		var elem = mapa.GMap.getInfoWindow().getContentContainers()[0];
		prepararEventos(elem);
	})

}

Mapa.prototype.objectToOverlays = function(obj) {
	/*
	imprime un overlay para cada atributo dentro del objeto, el formato de este debe ser:
	obj={
		'hotel-666': {id:666, type:'hotel', name:'Lorem ipsum', lat:40.0, lng:0.0, cat: 'GL', img: approot+'img/_HOTELPEQUE.jpg', address: 'Gran Via de les Corts Catalanes, 668<br/>08010 Barcelona<br/>Tel. +34.93.510.11.30<br/>Fax. +34.93.318.01.48', web: 'http://www.hotelpalacebarcelona'},
		'otro-777': {id:777, type:'otro', name:'Dolor sit', lat:40.0, lng:0.01, icon:'', text:'Together forever and ever blah blah'}
	}
	*/
	var _map = this.GMap,
		newZone = null,
		tempGLatLng;
	for (i in obj) {
		// evitamos que se repitan registros
		if (this.markers[i]) continue;
		// evitamos que se creen puntos sin datos
		if (obj[i].lat == null || obj[i].lng == null) continue;
		// extendemos la zona que ocupan los puntos creados
		tempGLatLng = new GLatLng(obj[i].lat, obj[i].lng);
		if (newZone) {
			newZone.extend(tempGLatLng);
		}
		else {
			newZone = new GLatLngBounds(tempGLatLng);
		}
		// en primer lugar creamos un nuevo objeto GMarker a partir latitud, longitud y tipo de objeto
		var icono = (obj[i].current) ? HUSA_CURRENT_HOTEL_ICON : (obj[i].type == 'hotel' ? HUSA_HOTEL_ICON : new GIcon(HUSA_DEFAULT_ICON, obj[i].icon))
		this.markers[i] = new GMarker(tempGLatLng,
			{icon: icono}
		);
		this.GMap.addOverlay(this.markers[i]);
		// como propiedad del marcador guardamos una referencia al objeto que lo ha creado para utilizarlo onclick
		this.markers[i].markerInfo = obj[i];
		GEvent.addListener(this.markers[i], 'click', function() {
			this.openInfoWindow(buildInfoWindow(this.markerInfo));
		});
	}
	// Control de nueva zona mapeada
	// si esta funcion se ha llamado desde updateViewport nunca deberia anyadir una nueva zona
	// porque se ha anyadida ya en la funcion anterior
	if (newZone) this.extendMappedZone(newZone);
}

Mapa.prototype.feedMapWithJSON = function(JSONurl, additionalParams, updateCallback) {
	var _t = this, // para referencias futuras
		_map = _t.GMap, // id. que ant.
		additionalParams = additionalParams || '',
		updateCallback = updateCallback || (typeof additionalParams == 'function')? additionalParams : function() {};
	// iniciamos la zona mapeada con un unico punto, anyadimos listener y llamamos por primera vez
	_t.mappedZone = [];
	GEvent.addListener(_map, 'moveend', function(){
		_t.JSON2Overlays(JSONurl, additionalParams, updateCallback)
	});
}

Mapa.prototype.JSON2Overlays = function(JSONurl, additionalParams, updateCallback) {
	var _t = this, // para referencias futuras
		_map = _t.GMap, // id. que ant.
		additionalParams = additionalParams || '',
		updateCallback = updateCallback || (typeof additionalParams == 'function')? additionalParams : function() {},
		bounds = _map.getBounds(),
		NEWS, bigNEWS;
	// si el "viewport" esta dentro de la zona mapeada devolvemos false y NO hacemos llamada AJAX

	// de otro modo calculamos las nuevas coordenadas del mapeado
	NEWS = {N:bounds.getNorthEast().lat(),E:bounds.getNorthEast().lng(),W:bounds.getSouthWest().lng(),S:bounds.getSouthWest().lat()},
	bigNEWS = {
		N: NEWS.N * 2 - NEWS.S,
		E: NEWS.E * 2 - NEWS.W,
		W: NEWS.W * 2 - NEWS.E,
		S: NEWS.S * 2 - NEWS.N
	}
	if (_t.isZoneInMappedZone(bounds)) {
		return false;
	} else {
		_t.extendMappedZone(bigNEWS.N, bigNEWS.E, bigNEWS.W, bigNEWS.S);
	}
	$.ajax({
		type: 'get',
		dataType: 'json',
		url: JSONurl,
		global:false,
		data: 'n=' + bigNEWS.N + '&e=' + bigNEWS.E + '&w=' + bigNEWS.W + '&s=' + bigNEWS.S + '&' + additionalParams,
		complete: function(respuesta) {
			if (respuesta.status == 200) {
				_t.objectToOverlays(JSON.parse(respuesta.responseText));
				updateCallback();
			} else {
				try{console.log('ERROR: response.status != 200')}catch(e){};
			}
		}
	});


}

Mapa.prototype.extendMappedZone = function(N, E, W, S) {
	var _mZ     = this.mappedZone,
		newZone;
	// podemos pasar como primer argumento una zona
	if (N.extend) {
		newZone = N;
	}
	// o pasar cuatro argumentos con los puntos cardinales
	else {
		newZone = new GLatLngBounds(new GLatLng(N, E));
		newZone.extend(new GLatLng(S, W));
	}
	// comprobamos por si acaso que no la tengamos
	if (this.isZoneInMappedZone(newZone)) {
		return false;
	}
	// si no la incluimos y devolvemos newZone
	else {
		_mZ.push(newZone);
		return newZone;
	}
}

Mapa.prototype.isZoneInMappedZone = function(zone) {
	// si ya tenemos la zona mapeada devolvemos false
	var _mZ = this.mappedZone;
	for (var i=0,l=_mZ.length;i<l;++i){
		if (_mZ[i].containsBounds(zone)) return true;
	}
	return false;
}

Mapa.prototype.setZoomOnMarkers = function() {
	var _markers = this.markers;
	var limites = new GLatLngBounds();
	var flag = false;

	for($i in _markers){
		flag = true;
		limites.extend(_markers[$i].getLatLng())
	}
	if(flag)
		this.GMap.setCenter(limites.getCenter(),this.GMap.getBoundsZoomLevel(limites) - 1);

	return this;
}

// funcion que devuelve un String de HTML para pintar dentro del InfoWindow
function buildInfoWindow(info) {
	if (info.type != 'hotel') {
		return ['<div class="hotelInfoGMap"><h4>', info.name, '</h4>', info.text, '</div>'].join('');
	}

	var catMap = new Array();
	catMap[0] = 0;
	catMap[1] = 1;
	catMap[2] = 2;
	catMap[3] = 3;
	catMap[4] = 4;
	catMap[5] = 5;
	catMap[6] = 'GL';
	catMap[7] = 'empty';
	catMap[8] = 'empty';

	var a = [];
	a.push('<div class="hotelInfoGMap">');
		a.push('<h4><a href="', approot, lang, info.reservar.replace(/(.+\/)(v\/.+)/g,'/nuestros-hoteles/hotel/$2'), '">', info.name, ' <img src="img/stars/', catMap[info.cat], '.gif" alt="', info.cat, '" /></a></h4>');
		if (info.img) {
			a.push('<img height="74" class="imgHotel" src="', info.img, '" alt="', info.name, '" />');	
		}
		a.push('<address>', info.address, '<br />', info.poblacion, '<br /><a href="mailto:', info.email, '">', info.email, '</a><br />', info.telefono, '<br />',  '</address>');
	a.push('</div>');

	a.push('<div class="hotelAccionesGMap clearfix">');
		a.push('<ul class="inlineList floatLeft">');
			if (info.web) {
				a.push('<li><a href="', info.web, '">', txtWeb, '</a></li> ');
			}

			a.push('<li><a rel="external" target="_blank" href="http://maps.google.es/maps?f=d&amp;daddr=', info.lat, ' ', info.lng, '">', txtComoLlegar, '</a></li> ');
			a.push('<li><a href="', info.reservar ,'">', txtReservar, '</a>');
            if (info.ulyses) {
                a.push('<input name="c" type="hidden" value="' + info.ulyses + '" />');
            }
            a.push('<input name="n" type="hidden" value="' + info.name + '" />');
			a.push('</li> ');
		a.push('</ul>');
		a.push('<span class="floatRight">');
		a.push('<a href="', approot, 'ajax/addToGPS.php?id=' + info.id + '&lang=', lang, '" class="addToGPS"><img src="', approot, 'img/icoGPS.png" alt="', txtEnviarGPS, '" title="', txtEnviarGPS, '" /></a>');
		a.push('<a href="', approot, 'ajax/generarKml.php?id=' + info.id + '"><img src="', approot, 'img/icoKML.gif" alt="', txtGenerarKML, '" title="', txtGenerarKML, '" /></a>');
		a.push('<a href="javascript:print();"><img src="', approot, 'img/icoPrint.gif" alt="', txtImprimir, '" title="', txtImprimir, '" /></a>');
		a.push('</span>');
		a.push('</div>');
	return a.join('');
}
