// JavaScript Document

var autoRefresh = true;
var loadOnDrag = false;




function ajaxLoadPubs(lng, lat, radius){
	
	var searchUrl = '/modules/ajax_gateway/new_g_mapspubs.php?lat=' + lat + '&lng=' + lng + '&radius=1';
    
	var req = new Request.HTML({
		method: 'get',
		url: searchUrl,
		data: { 'do' : '1' },
		onRequest: function(){
			showLoadingBar();
			geopoints = new Array();
		},
		evalResponse: true,
		update:  $('list-view-holder'), 
		onComplete: function(response) { 
			
			cacheMarkers();
			
			hideLoadingBar();
			
		}
	}).send();
	
	
}



function setupMap(centerX, centerY, radius, stroke, color){
	
	radius = typeof(radius) != 'undefined' ? radius : 1;
	stroke = typeof(stroke) != 'undefined' ? stroke : 0.5;
	color = typeof(color) != 'undefined' ? color : '#0099da';
	
	map.centerUpdate = true;
	map.markerOpts = {};

	
  	drawCircle(centerX, centerY, radius, stroke, color);
  	
  
  	
  	if(hasLoaded == false){
  		
  		
  		
	  	map.zoomBounds = new GLatLngBounds();
	  	drawCircleBounds(centerX, centerY, radius);
	  	map.zoomBoundsLevel = map.getBoundsZoomLevel(map.zoomBounds);
	  	hasLoaded = true;
	  
  	} else {
  		
  
  		
  		 if(filterByRadius == false){
  			 
  		
  		
  			 map.zoomBoundsLevel = map.getZoom();
  			 
  		 } else {
  			 
  			
  			 
	  			map.zoomBounds = new GLatLngBounds();
	  		  	drawCircleBounds(centerX, centerY, radius);
	  		  	map.zoomBoundsLevel = map.getBoundsZoomLevel(map.zoomBounds);
  			 
  			 filterByRadius = false; // uninitialize the filetr by radius as it only needs to work on the page load.
  		 }
  		
  	}
  	
  	map.setCenter(new GLatLng(centerX,centerY),map.zoomBoundsLevel);

  	
  
  		
  		
		  	GEvent.addListener(map, "dragend", function() {
		  		
		  		if(loadOnDrag == true){
			  		if(map.centerUpdate === true){
					
			  				loadMarkers(true);
			  		}
		  		} else {
		  			if($('getmorepubs').innerHTML == '') {
			  			$('getmorepubs').set('html', '<a href="#">Find more pubs</a>');
			  			$('getmorepubs').setStyle('display', 'block');
			  			$('getmorepubs').addEvent('click', function(event){
			  				submitMap();
			  				event.stop();
			  			});
		  			}

		  		}
  
		    });
  		
	  	
	  	loadMarkers(false);
 
}

function loadMarkers(getMoreMarkers) {
    
	showLoadingBar();
    

    // this would be where we load the ajax update in again
	
	getMoreMarkers = typeof(getMoreMarkers) != 'undefined' ? getMoreMarkers : false;
	
	if(getMoreMarkers === true){
		
		this_lat = map.getCenter().lat();
		this_lng = map.getCenter().lng();
		
		 
		ajaxLoadPubs(this_lat, this_lng);
		
	} else {
		
		cacheMarkers();
		
		
	}
	
	
	
	
}


function cacheMarkers() {
 
    markerObjects = new Array();
    
    var c = geopoints.length;
    for (var i = c-1; i >= 0; i--) {
          
    	
    		var pubId = geopoints[i][2];
    		var nameUTF8 = geopoints[i][3];
    		var description = buildHtmlInfo(geopoints[i]);
    		var point = new GLatLng(geopoints[i][0], geopoints[i][1]);
            markerObjects[i] = new Object();
            markerObjects[i]["pubId"] = pubId;
            markerObjects[i]["marker"] = getMarker(point, {title:nameUTF8, icon:geopoints[i][9]}, description);
            markerObjects[i]["features"] = geopoints[i][10];   
            markerObjects[i]['point'] = point;
            markerObjects[i]['radius'] = parseFloat(geopoints[i][11]);
  
    }

    refreshMap();
 
}

function buildHtmlInfo(gp){
	
	var str = '';
	str = str + '<div class="mdiv"><h2><a href="' + gp[4] + '">' + gp[3] + '</a></h2><p class="blue">' + gp[11] + ' miles away</p>';
	if(gp[6] != ''){
		str = str + gp[6];
	}
	
	str = str + '<div class="mdh"><p>' + gp[5] + '</p></div><div class="spacer"></div>';
	return str;
	
}

function zoomToFitMarkers(){
	
	var latlngbounds = new GLatLngBounds( );
	var c = geopoints.length;
    for (var i = c-1; i >= 0; i--) {
    	
    		//console.log(geopoints[i][1]);
    	    latlngbounds.extend( new GLatLng(geopoints[i][0], geopoints[i][1]));
    	    
    }
    
    
    var z = map.getBoundsZoomLevel( latlngbounds );
    
    if(z > 16){
    	z = 16;
    }
    	  
    map.setCenter( latlngbounds.getCenter( ),  z);
    
    loadMarkers();
    
    

}


function getMarker(latlng, markerOptions, description) {
   var marker = new GMarker(latlng, markerOptions);
    
   GEvent.addListener(marker, "click", function() { map.openInfoWindowHtml(latlng, description, map.markerOpts); });
   GEvent.addListener(marker, "infowindowopen", function() { map.centerUpdate = true; });
   GEvent.addListener(marker, "infowindowclose", function() { map.centerUpdate = false; }); 
    
   return marker;
}


function refreshMap() {
	

	
	 if (markerCluster != null) {
	       markerCluster.clearMarkers();
	      
	    } 
	
	 refreshMapMarkers();
	
	
    var mcOptions = { gridSize: 45, maxZoom: 13};
    markerCluster = new MarkerClusterer(map, markerArray, mcOptions);
    
      
   // updatePubCount();
    
    
  showMapTab();
    
    hideLoadingBar();
	    
}

function updatePubCount(){
	
	
	  var bounds = map.getBounds();
	  var c = markerObjects.length;
	  var cc = 0;
	  
	  for(var i = c-1; i>=0; i--){
		  
		  var pnt = markerObjects[i];
		  //check if point is inside the viewing area of the map
		  var flag = true;
		  // if the map has been initialised then we need to check bounds
		  // if th map has not been initialised then we don't need to check the bounds
		  // we are filtering all pubs in the list
		  if(hasLoaded == true &&  bounds.containsLatLng( pnt.point ) == true){
			  cc++;
		  } 


	  }
	  
	 

	  //$('map-inline-message').set('html', 'Showing <strong>' + cc + '</strong> pubs');
}

function refreshMapMarkers(){
		
	pubNumber = 0;
	markerArray = [];
	
	
	for (var i = markerObjects.length-1; i >= 0; i--) {
        var marker = markerObjects[i]["marker"];
        
        if (checkFeatures( markerObjects[i]["features"] )== true) {
            markerArray.push(marker);
            pubNumber++;
        }
       
       // markerArray.push(marker);
      //  pubNumber++;
	}
	
}

function checkFeatures(features){
	

	
	var p = properties.length;
	
	
    var showMarker = false;
    
    if(p > 0){
    	if(features.length > 0){
    		var a = features.intersect(properties);
    		if(a.length == p){
    			showMarker = true;
    			
    		}
    	} else {
    		showMarker = false;
    		
    	}
    } else {
    	showMarker = true;
    	
    }
	
	return showMarker;
	
}


function drawCircle(lat, lng, radius, stroke, sColor) {
	

	if(map.circle){
		map.clearOverlays();
	}

	
	radius = radius + ((radius/100) * 20);
	 
	  // Degrees to radians 
	  var d2r = Math.PI / 180;
	  // Radians to degrees
	 var r2d = 180 / Math.PI;
	  // Earth radius is 3,963 miles
	 var cLat = (radius / 3963) * r2d;
	  var cLng = cLat / Math.cos(lat * d2r);
	 
	  // Store points in array 
	  var points = [];
	 
	  // Calculate the points
	  // Work around 360 points on circle
	  for (var i=0; i < 720; i++) {
	 
	    var theta = Math.PI * (i/360);
	    // Calculate next X point 
	    circleX = lng + (cLng * Math.cos(theta));            
	    // Calculate next Y point 
	    circleY = lat + (cLat * Math.sin(theta));
	    // Add point to array 
	    points.push(new GPoint(circleX, circleY));
	  };
	 
	  // Add points to map 
	  map.circle = new GPolygon(points, sColor, stroke, 0.5, sColor, 0.05);
	  //map.addOverlay(new GPolyline(points, sColor, stroke));
	  map.addOverlay(map.circle);
}

function drawCircleBounds(lat, lng, radius) {
	  radius = radius + ((radius/100) * 10);
	  var d2r = Math.PI / 180;
	  var r2d = 180 / Math.PI;
	  var cLat = (radius / 3963) * r2d;
	  var cLng = cLat / Math.cos(lat * d2r);
	  var points = [];
	  for (var i=0; i < 4; i++) {
	    var theta = Math.PI * (i/2);
	    circleX = lng + (cLng * Math.cos(theta));            
	    circleY = lat + (cLat * Math.sin(theta));
	    map.zoomBounds.extend((new GLatLng(circleY, circleX)));
	  };
	  // debug
	  map.circle = new GPolygon(points, '#000000', 1, 0.5, '#000000', 0.15);
	map.addOverlay(map.circle);
}




function showHidePubs(property, which) {

	
	
	
	if(autoRefresh == true){
		
		
		property = property * 1;
		
		if(which) {
			h = 1;
			if(property in oc(properties)) {
			}else{
				properties.push(property);
			}
		}else{
			h = 0;
			if(property in oc(properties)) {
				properties.remove(property);
			}
		}
		
	
		if( $('list-view-holder').getStyle('display') == 'block'){
			
			
			updateListView();
		} else {
			refreshMap();
		}
		
	} else {
		
		
		submitMap();		
	}

}

function submitMap(){
	
	this_lat = map.getCenter().lat();
	this_lng = map.getCenter().lng();
	//console.log(filterByRadius);
	if(filterByRadius === true) {
		$('lat').set('value', this_lat);
		$('lng').set('value', this_lng);
	}
	checkDisplayMode();
	
	$('findapostcode').submit();
}

function checkDisplayMode(){
	
	if($('map-view-holder').getStyle('display') == 'block'){
		var action = $('findapostcode').getProperty('action');
		action = action.replace('/q/listview-true/', '/');
		//console.log(action);
		$('findapostcode').setProperty('action', action);
	}
	
}

function oc(a) {
  var o = {};
  for(var i=0;i<a.length;i++) {
    o[a[i]]= '';
  }
  return o;
}

Array.prototype.remove = function(itemsToRemove) {

    if (!/Array/.test(itemsToRemove.constructor)) {
        itemsToRemove = [ itemsToRemove ];
    }

    var j;
    for (var i = 0; i < itemsToRemove.length; i++) {
        j = 0;
        while (j < this.length) {
            if (this[j] == itemsToRemove[i]) {
                this.splice(j, 1);
            } else {
                j++;
            }
        }
    }
}

Array.prototype.compare = function(testArr) {
    if (this.length != testArr.length) return false;
    for (var i = 0; i < testArr.length; i++) {
        if (this[i].compare) { 
            if (!this[i].compare(testArr[i])) return false;
        }
        if (this[i] !== testArr[i]) return false;
    }
    return true;
}


window.addEvent('domready', function() {
	
		$('map-search-submit').addEvent('click', function(){
			$('lat').set('value', '');
			$('lng').set('value', '');
		});
	
	
	
		$('map-view-tab').addEvent('click', function(event){
			$('map-view-holder').setStyle('display', 'block');
			$('list-view-holder').setStyle('display', 'none');
			$('map-view-tab').addClass('current');
			$('list-view-tab').removeClass('current');
		
			//toogleStyleIfExists('map-inline-message','display', 'none');
			
			
			
			map.checkResize();
			
			if(this_lat == -1000){
				
				
				
				zoomToFitMarkers();
				
			} else {
			
				setupMap(this_lat, this_lng, searchRadius); 
				
				
				
				if(zoomToFitFlag === true){
	
					zoomToFitMarkers();
					
					
				}
			}
			
		
			
			event.stop();

			//toogleStyleIfExists('map-inline-message','display', 'none');
		
		});
	$('list-view-tab').addEvent('click', function(event){
		
		$('map-view-holder').setStyle('display', 'none');
		$('list-view-holder').setStyle('display', 'block');
		$('map-view-tab').removeClass('current');
		$('list-view-tab').addClass('current');
		
		
		
		updateListView();

		//toogleStyleIfExists('map-inline-message','display', 'block');
		
		
		
		event.stop();


		
	});


	
} );

function showMapTab(){
	
	  $('map-view-tab-li').setStyle('display', 'block');
	
}


function updateListView(){
	
	
	//console.log('updateListView line 571');
	
	
	/*
	 if(map.pg == undefined){
		map.pg = new PaginateClass({
			targetElement: 'p.pagination',
			list: $('location-list').getElements('li.dl2li')
		});
	 } else {
		 // this is a refresh so we need to empty the array of items to be made visible
		 map.pg.filterList = new Array();
	 }
	 // this should work but for some reason the pagination gets confused with
	 // the filtering in edge cases
	 */

	 map.pg = new PaginateClass({
			targetElement: 'p.pagination',
			list: $('location-list').getElements('li.dl2li')
		});
	
	  var bounds = map.getBounds();
	  var p = properties.length;
	  
	
	  
	  var c = markerObjects.length;
	  var cc = 0;
	  
	  
	  for(var i = c-1; i>=0; i--){
		  
		  var pnt = markerObjects[i];
		  
		
		  
		  
		 
		  
		  //check if point is inside the viewing area of the map
		  var flag = true;
		  // enable filtering by distance on the list view maps (specifically SYL)
		  var radius = true;
		  // if the map has been initialised then we need to check bounds
		  // if th map has not been initialised then we don't need to check the bounds
		  // we are filtering all pubs in the list
		  if(hasLoaded == true && filterByRadius == false){
			  flag = bounds.containsLatLng( pnt.point );
		  } 
		  
		  if(filterByRadius == true){
			  if(pnt.radius <= searchRadius){
				  radius = true;
			  } else {
				  radius = false;
			  }
		  } 
		  
		  //console.log(flag + ' - ' + checkFeatures( pnt.features ) + ' - ' + radius);
			 	
		  if((flag  == true) && ( checkFeatures( pnt.features ) == true) && (radius == true)){
			
			  cc++;
			  
			  map.pg.filterList.push('li-' + pnt.pubId);
			  
			  

		  } else {
			  
		
			  
			  
		  }
	  }
	  
	  //console.log(map.pg.filterList);	  
	  map.pg.setup();
	  
	  showMapTab();
	  
	  //  filterByRadius = false; // uninitialize the filetr by radius as it only needs to work on the page load.
	  // moved to setup();

	//$('map-inline-message').set('html', 'Showing <strong>' + cc + '</strong> pubs');
	  
	  
	 if($('loading-pubs')){
	  $('loading-pubs').setStyle('display', 'none');
	 }
	
	return true;
	
}



/**
 * Check if an element exists and if so toggle it.
 * @param elem 		id of element to be toggled
 * @param style 	e.g. display, visibility
 * @param attr 		e.g. block, hidden
 * @return true / false
 */
function toogleStyleIfExists(elem, style, attr){
	
	if($(elem) == null){	
		return false;
	} else {
		$(elem).setStyle(style, attr);
		return true;
	}
	
}


	


	
	
	



var PaginateClass = new Class({
    Implements: [Options],
    
    options: {
	    perPage:25,
	    targetElement: 'div.pagination',
	    list: null
    },
    
    numItems: 0,
    filterLength: 0,
    pages:1,
    currentPage: 1,
    filterList: new Array(),
    
    initialize: function(options) { 
    	

    	
    	

    	
    
    	
    	this.setOptions(options);
    	
    
    	this.numItems = this.options.list.length;
    },
    
    setOptions: function(options) {
		for(var i in options) {
			this.options[i] = options[i];
		}
	},
	
	calculatePagination: function(){
		
		this.filterLength = this.filterList.length;
		
		if(this.filterLength > this.options.perPage){
    		this.pages = Math.floor(this.filterLength / this.options.perPage);
    		
    		if(this.filterLength > (this.options.perPage * this.pages)){
	    		if(this.filterLength % this.options.perPage != 0){
	    			 this.pages = this.pages + 1;
	    		}
    		}
    	}
	},
	
	filterItems : function(page){
		
		if($('uyl-member-pubs'))
		{
			if(page == 1)
				$('uyl-member-pubs').setStyle('display','block');
			else
				$('uyl-member-pubs').setStyle('display','none');
		}
		
		end = page * this.options.perPage;
		start = end + 1 - this.options.perPage;
		
		if(end > this.filterLength){
			end = this.filterLength;
		}
		
	
		
		this.currentPage = page;
		
		
		
	
	
		var j = 0; // count of the actual items we need to display
		

	
		for(i = 0; i < this.numItems; i++){
			
			
			var id = this.options.list[i].getProperty('id');
			
	
			
			
			if(this.filterList.contains(id) == true){
	
				if(j + 1 >= start && j < end){

				
					
					$(id).setStyle('display', 'block');
				} else {
					$(id).setStyle('display', 'none');
				}
				j++;
	
			} else {
				
				$(id).setStyle('display', 'none');
			}
			
			
		}
		
		this.buildPagination(start, end);
		
	},
	
	setup : function(){

		if(this.filterList == null){
			this.filterList = this.options.list;
		}
		
		this.calculatePagination();
		this.filterItems(1);
	},
    
    buildPagination : function(start, end) {
		


        $$(this.options.targetElement).each(function(el) {
        	
            el.empty();
            
            if(this.filterLength == 0){
            	start = 0;
            }
            
            el.appendText('Showing ' + start + ' to ' + end + ' of ' + this.filterLength + ' results. ');
            
            if(this.pages > 1){
            	el.appendText(' Page: ');
	            for(var i = 1; i<= this.pages; i++) {
	            	if(i == this.currentPage){
	            		el.appendText(' [' + i + ']');
	            	} else {
	            		el.appendText(' ');
		                var a = new Element('a', {
		                    text: i,
		                    title: 'Page: ' + i,
		                    events: {
		                        click: function(e) {
		                		
		                          this.filterItems(e.target.retrieve("index"));
		                        }.bind(this)
		                    }
		               
		                }).store("index", i).inject(el);
	            	}
	            }
            }
                    
        }.bind(this));
        
        return true;
    }
});


