var map;
var startDialog;
var zoomInDialog;
var mapContent;
var checkBoxes = {};
var geocoder;

var iconData = [{imageURL:'http://mapsinternational.co.uk/msi/images/purple.png', width: 18, height: 39},
            {imageURL:'http://mapsinternational.co.uk/msi/images/green.png', width: 18, height: 39},
            {imageURL:'http://mapsinternational.co.uk/msi/images/shadow.png', width: 46, height: 39}];
var icons = [];
var markers = [];

var tiles = [];
var tileRequests = new Hash();
var requestCount = 0;
var markers = [];
var searchResults = [];
var showSearchResults = false;
var accreditedOnly = 0; 
var proj;

function initMap(){
	var mapDiv = $("map");
	startDialog = $("mapStartDialog");
	zoomInDialog = $("zoomInDialog");        
	checkBoxes.mapCheckAccredited = {elem: document.getElementById("mapCheckAccredited"), checked: false};
	checkBoxes.mapCheckNonAccredited = {elem: document.getElementById("mapCheckNonAccredited"), checked: false};
	map = new GMap2(mapDiv);
	map.setCenter(new GLatLng(53.407,-3), 12);
	map.addControl(new GSmallMapControl());
	geocoder = new GClientGeocoder();
  
	icons.push(createIcon(iconData[0], iconData[2]));  
	icons.push(createIcon(iconData[1], iconData[2]));    
	
	proj = new GMercatorProjection(20);
	markerManager = new GMarkerManager(map);
	
	GEvent.addListener(map, "moveend", getMarkersByTile);
	GEvent.addListener(map, "zoomend", checkMapState);
}



function startCheckClick(elem){
    var id = elem.id;
    
    if (id=='mapCheckAccredited'){
        if($('mapAccreditedText').getStyle('display')=='none'){
            new Effect.BlindDown('mapAccreditedText', {duration: 0.5});
        } else {
            new Effect.BlindUp('mapAccreditedText', {duration: 0.5});   
        }
        if($('mapNonAccreditedText').getStyle('display')=='block'){
            new Effect.BlindUp('mapNonAccreditedText', {duration: 0.5});           
        }
    } else if (id=='mapCheckNonAccredited'){
        if($('mapNonAccreditedText').getStyle('display')=='none'){
            new Effect.BlindDown('mapNonAccreditedText', {duration: 0.5});
        } else {
            new Effect.BlindUp('mapNonAccreditedText', {duration: 0.5});   
        }
        if($('mapAccreditedText').getStyle('display')=='block'){
            new Effect.BlindUp('mapAccreditedText', {duration: 0.5});           
        }    

    }
    
    if (checkBoxes[id].checked){
        toggleCheck(checkBoxes[id], false);
    } else {
        toggleCheck(checkBoxes[id], true);
    }
    
    for (var property in checkBoxes){
        if(property!=id){
            toggleCheck(checkBoxes[property], false)
        }
    }    
}

function loadMapData(){
    if(!checkBoxes.mapCheckAccredited.checked && !checkBoxes.mapCheckNonAccredited.checked){
        $('mapStartMessage').update('Please select a club type.');
        return;
    }
   
   //hide the start dialog and the map text
    new Effect.Fade(startDialog);
    new Effect.Fade('MapIntroText');
    new Effect.Appear('mapSideBarContent');
 
    if(checkBoxes.mapCheckAccredited.checked){
        accreditedOnly = 1;
    }else {
        accreditedOnly = 0;
    }
	
    makePostRequest('populate', generateRequestID(), '', populateForm);
//    map.setZoom(11);
    getMarkersByTile();

}


function toggleCheck (chkObj, active){  
    var className = chkObj.elem.className;
    className = className.slice(0, (className.length-1));
    if (active){
        chkObj.elem.className = className + 'A'
    } else{
        chkObj.elem.className = className + 'I'
    }
    chkObj.checked = active;
}


function makePostRequest(action, reqID, theData, theFunction){
    
	if(action == "getMarkersByTile"){						//Need to ensure the curent search crireria is maintained when new markers are retrieved
		var sportID = $('mapSportSelect').value;
		var areaID = $('mapAreaSelect').value;
		var postcode = $('mapPostcodeText').value;
	    if(sportID=='empty'){
			sportID = "";
		}
		if(areaID=='empty'){
			areaID = "";
		}	
		if((sportID != "") && (areaID != "")){
			params = {action:action, theData: theData, reqID: reqID, accreditedOnly: accreditedOnly, sportID: sportID, areaID: areaID};
		}else if((sportID != "") && (areaID == "")){		
			params = {action:action, theData: theData, reqID: reqID, accreditedOnly: accreditedOnly, sportID: sportID};
		}else if((sportID == "") && (areaID != "")){		
			params = {action:action, theData: theData, reqID: reqID, accreditedOnly: accreditedOnly, areaID: areaID};
		}else{
			params = {action:action, theData: theData, reqID: reqID, accreditedOnly: accreditedOnly};
		}
	}else{
		params = {action:action, theData: theData, reqID: reqID, accreditedOnly: accreditedOnly};
	}
	
	var url = 'ajax/getMapData.php';
	new Ajax.Request(url, {
		method: 'post',
		parameters: params,
		onSuccess: theFunction
	});
	         
}

function getClubsByArea(){
    var areaID = $('mapAreaSelect').value;
    if(!areaID){return;}
 
    makePostRequest('getClubsByAreaID', 0, areaID, displaySearchResults);
    
    //flags that all markers will be shown.
    showSearchResults = false;
    removeSearchResults();
    showMarkers(markers);
    
    
}

function clubSearch(){
    var sportID = $('mapSportSelect').value;
    var areaID = $('mapAreaSelect').value;
    var postcode = $('mapPostcodeText').value;
    
   // if((sportID=='empty') && (sportID=='empty') && (areaID=='empty')){return;}
  
    //flags that only search results will be shown.
    showSearchResults = true;

    //select by sportid and areaid. area id overrides postcode.
    
    //need to make geocode request if postcode is not empty and areaid is empty
    if((areaID=='empty')&&!(postcode=='')){
        geocoder.getLocations(postcode, function(response){getSearchResults(response, false, sportID)});        
    } else {	
      getSearchResults(false, areaID, sportID);
    }
  
	//var json = transport.responseText.evalJSON();
    //var results = json.data;
    //var reqID = json.reqID;
	
    //done after request made to make most of being asynchronous
    hideMarkers(markers);
    removeSearchResults(); 

}

function getSearchResults(response, areaID, sportID){
    var x, y, params={accreditedOnly: accreditedOnly, action: 'clubSearch', reqID:0};
    if (response){
        if (response.Placemark){
            y = response.Placemark[0].Point.coordinates[1];
            x = response.Placemark[0].Point.coordinates[0];
            params.x = x;
            params.y = y;
        }    
    }
    
    if(sportID && (sportID!='empty')){params.sportID = sportID};
    if(areaID && (areaID!='empty')){params.areaID = areaID};
    
	//alert(String(params.x) + "," + String(params.y) + "," + String(params.areaID) + "," + String(params.sportID))	
    var url = 'ajax/getMapData.php';
    new Ajax.Request(url, {
        method: 'post',
        parameters: params,
        onSuccess: displaySearchResults
    });      
}

function removeSearchResults(){
      for (var i=0; i<searchResults.length; i++){
        GEvent.removeListener(searchResults[i].listenerHandle);
        map.removeOverlay(searchResults[i]);
      } 
}

function removeSearchResultsOnClick(evt){

	//Changed - Just run a full on filtered search
    //$('mapSportSelect').value = "";  ///"--all club types--";
    //$('mapAreaSelect').value = "kdsnslk"; //"--all areas--";
    //$('mapPostcodeText').value = "";

	$('mapSportSelect').options[0].selected = true;
	$('mapAreaSelect').options[0].selected = true;
	$('mapPostcodeText').value = "";
	
	clubSearch();
	/*
    removeSearchResults();
    showMarkers(markers);
    evt.style.display = 'none';
    showSearchResults = false;
    //check the map state(don't show all markers unless at correct zoom)
    checkMapState(0, map.getZoom());
	*/
}

function displaySearchResults(transport){

    var json = transport.responseText.evalJSON();
    var results = json.data;
    var action = json.action; 
	//alert(results)
    var searchTd = $('searchResultsText');
    var mapSearchResults = $('mapSearchResults');
    mapSearchResults.style.display = 'block';   
    
    var msg;
    if(!results.length){
        showSearchResults = false;        
        searchTd.update("No clubs were found.");  // Click here to show all clubs.");
        return;
    }
    if(results.length ==1){
        msg = "1 club found.";   // Click here to show all clubs.";
    }else{
        msg = results.length+" clubs found.";  // Click here to show all clubs."
    }
    searchTd.update(msg);

    var markerData, listener, x, y, minY=10000, minX=10000, maxX=-10000, maxY=-10000;
    for (var i=0; i<results.length; i++){
        markerData=results[i];
        x = markerData.x;
        y = markerData.y;
        minX = Math.min(x,minX);
        minY = Math.min(y,minY);
        maxX = Math.max(x,maxX);
        maxY = Math.max(y,maxY);
        
            var marker = createMarker(new GLatLng(y,x), icons[markerData.acc]);
            marker.uid = markerData.uid;
            listener = GEvent.addListener(marker, 'click', function(){getSearchMarkerInfo(this.uid)});
            marker.listenerHandle = listener;
            map.addOverlay(marker);
            searchResults.push(marker);
        
    }
    
    //zoom to the bounds
    var bounds = new GLatLngBounds(new GLatLng(minY, minX), new GLatLng(maxY, maxX));
    //get record the lowest zoom level at which the bounds fit in the map.
    var startZoom = map.getBoundsZoomLevel(bounds);
    map.setCenter(bounds.getCenter(), startZoom);
}

function populateForm(transport){
    var select = $('mapAreaSelect');
    var json = transport.responseText.evalJSON();
    populateSelect(json.areas, '--all areas--','mapAreaSelect');
    populateSelect(json.clubTypes, '--all club types--', 'mapSportSelect');
}

function populateSelect(data, defaultText, selectID){
    var select = $(selectID);
    select.appendChild(new Element('option', {value: 'empty'}).update(defaultText));    
    for (var i=0; i<data.length; i++){
        select.appendChild(new Element('option', {value: data[i].uid}).update(data[i].value));
    }
}

function getMarkerInfo(uid) {
    makePostRequest('getMarkerInfoByUID', 'req', uid, openNormalMarkerWindow);
}
function getSearchMarkerInfo(uid) {
    makePostRequest('getMarkerInfoByUID', 'req', uid, openSearchMarkerWindow);
}

function openNormalMarkerWindow(transport) {  
    openMarkerInfo(transport, markers);
}
function openSearchMarkerWindow(transport) {  
    openMarkerInfo(transport, searchResults);
}

function openMarkerInfo(transport, theMarkers){
    var response = transport.responseText.evalJSON();	
    var response = response[0];
    var address = [response.address];
    var clubTitle = response.title;
    var uid = response.uid;
    var contact = [];
	var clubsessions = [];
	var volunteer = [];
    
	//if (response.title){contact.push(response.title);}
	if (response.telephone){contact.push(response.telephone);}
	if (response.email){contact.push('<a href="mailto:'+response.email+'">'+response.email+'</a>');} 
    if (response.address){contact.push(response.address + ", " + response.postcode);}
    if (response.website){contact.push('<a target="_blank" href="http://'+response.website+'">'+response.website+'</a>');}
      
	if (response.volname){volunteer.push(response.volname);}
	if (response.voltelephone){volunteer.push(response.voltelephone);}
	if (response.volemail){volunteer.push('<a href="mailto:'+response.volemail+'">'+response.volemail+'</a>');} 
    if (response.voladdress){volunteer.push(response.voladdress);}
	
	if (response.maleadult == 't'){clubsessions.push("Male Adult (16 +)");}
	if (response.femaleadult == 't'){clubsessions.push("Female Adult (16 +)");}
	if (response.malejunoir == 't'){clubsessions.push("Male Junior (5-16 years)");} 
    if (response.femalejunoir == 't'){clubsessions.push("Female Junior (5-16 years)");}
	if (response.disability == 't'){clubsessions.push("Disability");}	  
	  
	  
	//Store on Hidden for print functionality
	//Clear first
	$('ptitle').value = "";
	$('ptelephone').value = "";
	$('pemail').value = "";
    $('paddress').value = "";
    $('pwebsite').value = "";
	$('pvolname').value = "";
	$('pvoltelephone').value = "";
	$('pvolemail').value = ""; 
    $('pvoladdress').value = "";
	$('pmaleadult').value = "";
	$('pfemaleadult').value = "";
	$('pmalejunoir').value = "";
    $('pfemalejunoir').value = "";
	$('pdisability').value = "";
	
	if (response.title){$('ptitle').value = response.title;}
	if (response.telephone){$('ptelephone').value = response.telephone;}
	if (response.email){$('pemail').value = '<a href="mailto:'+response.email+'">'+response.email+'</a>';} 
    if (response.address){$('paddress').value = response.address + ", " + response.postcode;}
    if (response.website){$('pwebsite').value = '<a target="_blank" href="http://'+response.website+'">'+response.website+'</a>';}
      
	if (response.volname){$('pvolname').value = response.volname;}
	if (response.voltelephone){$('pvoltelephone').value = response.voltelephone;}
	if (response.volemail){$('pvolemail').value = '<a href="mailto:'+response.volemail+'">'+response.volemail+'</a>';} 
    if (response.voladdress){$('pvoladdress').value = response.voladdress;}
	
	if (response.maleadult == 't'){$('pmaleadult').value = "Male Adult (16 +)";}
	if (response.femaleadult == 't'){$('pfemaleadult').value = "Female Adult (16 +)";}
	if (response.malejunoir == 't'){$('pmalejunoir').value = "Male Junior (5-16 years)";} 
    if (response.femalejunoir == 't'){$('pfemalejunoir').value = "Female Junior (5-16 years)";}
	if (response.disability == 't'){$('pdisability').value = "Disability";}
	  
   for (var i=0; i<theMarkers.length; i++) {
      if (theMarkers[i].uid == uid) {
        var theMarker = theMarkers[i];
        theMarker.openInfoWindowTabsHtml([new GInfoWindowTab("Club",getTabMarkup(response.title, contact)),new GInfoWindowTab("Sessions", getTabMarkup("Club Sessions", clubsessions)),new GInfoWindowTab("Volunteer", getTabMarkup("Volunteer Co-ordinator", volunteer))],{maxWidth:800});
        return;
      }
   }
 }
 
 function getTabMarkup(title, content){
    
    var contentRows = '';
    if(!title){title=''};
    
    for (var i=0;i<content.length; i++){
        if(content[i]) {
            contentRows += '<tr><td class="mapInfoTabContent">'+content[i]+'</td></tr>';
        }
    }
    
	if(content.length == 0){
		title="";
	}
    var html = '<table class="mapInfoTabTable"><tr><td class="mapInfoTabTitle">'+title+'</td></tr>'+contentRows;
	
	//Show print info link if necessary
	if(content.length > 0){
		html += '<tr><td align="right"><br/><br/><a href="javascript:printInfo();">Print Information</a></td></tr>';
	}	
	html += '</table>';
    return html;
}

function createMarker(point, iconOpts) {

    if(!iconOpts) {return false;}

    var marker = new GMarker(point, iconOpts);

    return marker;
}

function createIcon(iconOpts, shadowOpts){
	theIcon = new GIcon();
	theIcon.image = iconOpts.imageURL;
	theIcon.iconSize = new GSize(iconOpts.width, iconOpts.height);
	theIcon.iconAnchor = new GPoint((iconOpts.width/2), iconOpts.height);
	theIcon.shadow = shadowOpts.imageURL;
	theIcon.shadowSize = new GSize(shadowOpts.width, shadowOpts.height);
	theIcon.infoWindowAnchor = new GPoint((iconOpts.width/2), 0);
	return theIcon;
}

function getMarkersByTile(){
    var zoomLevel = map.getZoom();
    if (zoomLevel<11){
        //Show info window saying zoom in!
        return;
    }
    
    var theZoom = 12;
    var extent = map.getBounds();
    var sw = extent.getSouthWest();
    var ne = extent.getNorthEast();

    //get top right corner
    var pixelPointNw = proj.fromLatLngToPixel(new GLatLng(ne.y, sw.x), theZoom);
    //get bottom left corner
    var pixelPointSe = proj.fromLatLngToPixel(new GLatLng(sw.y, ne.x), theZoom);

    //get top right tile name
    var tileNameX = Math.floor(pixelPointNw.x / 256);
    var tileNameY = Math.floor(pixelPointNw.y / 256);

    //number of pixels in top left tile NOT shown on the map
    var modX = pixelPointNw.x % 256;
    var modY = pixelPointNw.y % 256;

    //map dimensions in pixels
    var dX = pixelPointSe.x - pixelPointNw.x;
    var dY = pixelPointSe.y - pixelPointNw.y;

    //the number of pixels taken up by a tile in the frame will be the map width minus the amount of the
    //top left tile that is in the frame.
    //divide by 256 and round up to get the extra number of tiles in the frame.
    //add 1 to include the first tile!

    //number of tiles wide the map is
    var dXTiles = Math.ceil((dX - (256-modX))/256)+1;
    //number of tiles high the map is
    var dYTiles = Math.ceil((dY - (256-modY))/256)+1;

    var pixelSw, pixelNe, nw, se, tileName;
    var requestTiles = [];
    
    var k = 0;
    var clubCount = 0;
    
    for (var i=0; i<dXTiles; i++) {
        for (var j=0; j<dYTiles; j++) {
            tileName = "'"+(tileNameX + i) + "~" + (tileNameY + j)+"'";
            //if the tile isn't loaded put it into a request
            if (!tiles[tileName]){
                requestTiles[k] = tileName;
                k++;
            }
        }
    }
    
    //no need to make a request
    if(requestTiles.length){
        for(var i=0;i<requestTiles.length; i++){
            tiles[requestTiles[i]]=true;
        }
        var reqID = generateRequestID();
        tileRequests.set(reqID, requestTiles);
        makePostRequest('getMarkersByTile', reqID, requestTiles.join(','), updateMap);
    }

}


function updateMap(transport){
    var zoomLevel = map.getZoom();
    var showMarkers = true;
    if (zoomLevel<12){
        //Show info window saying zoom in!
        showMarkers = false;
    }
       
    var markerData, x, y;
    var json = transport.responseText.evalJSON();
    var results = json.data;
    var reqID = json.reqID;
    
    for (var i=0; i<results.length; i++){
        markerData=results[i];
        x = markerData.x;
        y = markerData.y;
        var marker = createMarker(new GLatLng(y,x), icons[markerData.acc]);
        marker.uid = markerData.uid;
        GEvent.addListener(marker, 'click', function(){getMarkerInfo(this.uid)});
        map.addOverlay(marker);
        markers.push(marker);
    }
}

function zoomOnDlgClick(){
    map.setZoom(11);
}

function checkMapState(oldLevel,newLevel){
    //amxDebug(oldLevel,newLevel)
    
    //if search results are being shown, don't mess with the markers.
    if(showSearchResults){return;}
    
    if (newLevel<11){
       //zoomed out too far
       hideMarkers(markers);
       zoomInDialog.style.display = 'block'; 
    } else if((newLevel>10)){
        showMarkers(markers);
        zoomInDialog.style.display = 'none';        
    }
}

function hideMarkers(theMarkers){
      for (var i=0; i<theMarkers.length; i++){
        theMarkers[i].hide();
      }
}

function showMarkers(theMarkers){
      for (var i=0; i<theMarkers.length; i++){
        theMarkers[i].show();
      }
}

function generateRequestID(){
    return 'req'+requestCount++;
}


function amxDebug(evt, msg){
    $('debug1').innerHTML = '<table><tr><td>'+evt+'</td><td>'+msg+'</td></tr></table>';
}

//get all tiles
function printTiles(){
    
    var theZoom = 12;
    var extent = map.getBounds();
    var sw = extent.getSouthWest();
    var ne = extent.getNorthEast();

    //get top right corner
    var pixelPointNw = proj.fromLatLngToPixel(new GLatLng(ne.y, sw.x), theZoom);
    //get bottom left corner
    var pixelPointSe = proj.fromLatLngToPixel(new GLatLng(sw.y, ne.x), theZoom);

    //get top right tile name
    var tileNameX = Math.floor(pixelPointNw.x / 256);
    var tileNameY = Math.floor(pixelPointNw.y / 256);

    //number of pixels in top left tile NOT shown on the map
    var modX = pixelPointNw.x % 256;
    var modY = pixelPointNw.y % 256;

    //map dimensions in pixels
    var dX = pixelPointSe.x - pixelPointNw.x;
    var dY = pixelPointSe.y - pixelPointNw.y;

    //the number of pixels taken up by a tile in the frame will be the map width minus the amount of the
    //top left tile that is in the frame.
    //divide by 256 and round up to get the extra number of tiles in the frame.
    //add 1 to include the first tile!

    //number of tiles wide the map is
    var dXTiles = Math.ceil((dX - (256-modX))/256)+1;
    //number of tiles high the map is
    var dYTiles = Math.ceil((dY - (256-modY))/256)+1;

    
    document.write('count: '+(dXTiles*dYTiles)+'<br>'+'zoom: '+map.getZoom()+'<br> thezoom: '+theZoom+'<br>')
    var tnX, tnY, pixelSw, pixelNe, nw, se;
    for (var i=0; i<dXTiles; i++) {
        for (var j=0; j<dYTiles; j++) {

        tileX = tileNameX + i
        tileY = tileNameY + j
        
          pixelSw = new GPoint((tileX*256), (tileY*256));
          pixelNe = new GPoint(((tileX+1)*256),((tileY+1)*256));
          nw = proj.fromPixelToLatLng(pixelSw, theZoom, false);
          se = proj.fromPixelToLatLng(pixelNe, theZoom, false);
          
          //document.write(tileX+', '+tileY+', '+nw.x+', '+se.y+', '+se.x+', '+nw.y+'<br>');
        document.write("insert into tiles values('"+tileX+"~"+tileY+"', SetSRID(st_makebox2d(st_makepoint("+nw.x+","+se.y+"),st_makepoint("+se.x+", "+nw.y+")), 4326));");
        }
    }

}

//-----Clear postcode when selecting area and vice-versa
function clearInput(toClear){
	if(toClear == "postcode"){					//Clear postcode box
		$('mapPostcodeText').value = "";
	}else if(toClear == "area"){				//Reset area selection
		$('mapAreaSelect').options[0].selected = true;
		$('mapPostcodeText').value = "";
	}
}


function printInfo(){
	document.frmsearch.action = "print.asp";
	document.frmsearch.target = "_blank";
	document.frmsearch.submit();



	//Open in new window;
	//theURL = "print.html?" + thePrintInfo;	
	//winName = "Printinfo";
	//features = "toolbar=yes,scrollbars=yes,resizable=yes,width=500,height=500";
	//var theWin = window.open(theURL,winName,features);		
	//theWin.focus();									//Ensure map window is visible on top

}

//--------------------------End of script