var map;
    var dIcon;
    var allPlaces;
    var currentPhotos;
    var photoPages;
    var currentPage;
    var totalPages;
    var totalPhotos;
    var currentPlacesSearch;
    
    $(document).ready(init);
    
    function init(){
      $('#dateFilter').hide();
      $('#doSearch').click(hDoSearch);
      $('#placeSearchForm').submit(hSearchSubmit);
      //$('#dateFrom').attachDatepicker({dateFormat:'dd-mm-yy'});
      //$('#dateTo').attachDatepicker({dateFormat:'dd-mm-yy'});
      $('#dateFrom').attachDatepicker();
      $('#dateTo').attachDatepicker();

      $('#doDateFilter').click(hApplyDateFilter);
      $('#clearDateFilter').click(hClearDateFilter);
      createIcon();
      createMap();
      getPlaces();
    }
    
    function createMap() {
      if (GBrowserIsCompatible()) {
        map = new GMap2(document.getElementById('mapCanvas'));
        map.addControl(new GSmallMapControl());
        map.setCenter(new GLatLng(54.4725, -4.454044),5);
        map.setMapType(G_HYBRID_MAP);
      }
    }
      
     /********************************************
     * Get all places
     *******************************************/   
    function getPlaces(){
      $.getJSON("http://www.restatedesign.com/flickr/json/getplaces.php?jsoncallback=?",cbGetPlaces);
    }
    
    function cbGetPlaces(data){
      allPlaces = data;
      for(placeId in allPlaces){
        console.log(allPlaces[placeId]);
        point = new GLatLng(allPlaces[placeId].lat,allPlaces[placeId].lon);
        map.addOverlay(createMarker(point,allPlaces[placeId].name,placeId));
      }
    }
    
    /********************************************
     * Get photos by place id
     *******************************************/         
    function getPhotosByPlaceId(placeId){
      $('#thumbs .imageFrame').remove();
      $('#thumbs p').remove();
      $('#thumbs').addClass('loading');
      $.getJSON("http://www.restatedesign.com/flickr/json/getphotosbyplaceid.php?q=" + placeId + "&jsoncallback=?",cbGetPhotosByPlaceId);
    }
    
    function cbGetPhotosByPlaceId(data){
      $('#thumbs').removeClass('loading');
      setCurrentPhotos(data);
    }
    
    /********************************************
     * Get photos near place id
     *******************************************/  
    function getPhotosNearPlaceId(placeId){
      $('#thumbs .imageFrame').remove();
      $('#thumbs p').remove();
      $('#thumbs').addClass('loading');
      $.getJSON("http://www.restatedesign.com/flickr/json/getphotosnearplaceid.php?q=" + placeId + "&jsoncallback=?",cbGetPhotosNearPlaceId);
    }
    
    function cbGetPhotosNearPlaceId(data){
      $('#thumbs').removeClass('loading');
      setCurrentPhotos(data);
    }
    
    
    
    /********************************************
     * Marker and icon creation
     *******************************************/
    function createIcon(){
      dIcon = new GIcon();
      dIcon.image = "img/icon.png";
      dIcon.shadow = "img/icon_shadow.png";
      dIcon.iconSize = new GSize(43, 34);
      dIcon.shadowSize = new GSize(43, 34);
      dIcon.iconAnchor = new GPoint(25, 25);
      dIcon.infoWindowAnchor = new GPoint(25, 15);
    }
     
    function createMarker(point, name, placeId) {
      var marker = new GMarker(point, {icon:dIcon});
      marker.name = name;
      marker.placeId = placeId;
      
      GEvent.addListener(marker, "click", function() {
        html = "<h3>" + name + "</h3>";
        html += "<p><a onclick='getPhotosByPlaceId(" + placeId + ")'>Show photos</a></p>";
        map.openInfoWindowHtml(point, html);
      });
      return marker;
    }
    
    /********************************************
     * Place searching
     *******************************************/
    function hDoSearch(){
      $.getJSON("http://www.restatedesign.com/flickr/json/findplaces.php?q=" + $('#placeName').val() + "&jsoncallback=?",cbDoSearch);
      $('#results').addClass('loading');
      $('#results p').remove();
      $('#results ul').remove();
    }
    
     function hSearchSubmit(){
      hDoSearch();
      return false;
    }
    
     function cbDoSearch(data){
      console.log(data);
      currentPlacesSearch = data;
      $('#results').removeClass('loading');
      if(data.error == 'error connecting to geonames'){ 
        $('#results').append('<p>Error connecting to server, please try again later.</p>');
      } else if(data.error == 'no results found') {
        $('#results').append('<p>No locations with photos nearby found.</p>');
      } else {
        $('#results').append('<p>Found the following locations with photos nearby:</p>');
        $('#results').append('<ul></ul>');
        $.each(data, function(i,aPlace){
                $('#results ul').append('<li id="place' + aPlace.geonameId + '">' + aPlace.name + '<br/></li>');
                $('#results ul li#place' + aPlace.geonameId).append('<a class="showPlace" href="#">show on map</a>');
                $('#results ul li#place' + aPlace.geonameId).append(' - ');
                $('#results ul li#place' + aPlace.geonameId).append('<a class ="showPhotos" href="#">show nearby photos</a>');
                $('#results ul li#place' + aPlace.geonameId + ' .showPlace').click(function(){showPlaceOnMap(aPlace.lat,aPlace.lon); return false});
                $('#results ul li#place' + aPlace.geonameId + ' .showPhotos').click(function(){getPhotosNearPlaceId(aPlace.geonameId); return false});
            });
      }
    }
    
    function showPlaceOnMap(lat,lon){
      map.closeInfoWindow();
      map.setCenter(new GLatLng(lat,lon),10);
    }
    
    /********************************************
     * Thumbnail viewing interface
     *******************************************/
    function setCurrentPhotos(data){
      currentPhotos = data;
      photoPages = new Array();
      photos = new Array;
      $.each(currentPhotos, function(i,aPhoto){
        photos.push(i);
      });
      totalPhotos = photos.length;
      totalPages = Math.ceil(photos.length/12);
      for(var i=0; i<totalPages; i++){
        photoPages.push(new Array());
        for(var j=0; j<12; j++){
          if(photos[(i*12)+j] != undefined){
            photoPages[i].push(photos[(i*12)+j]);
          }
        }
      }
      setPhotoPage(0);
      $('#dateFilter').show();
    }
    
    function setPhotoPage(page){
      $('#thumbs .imageFrame').remove();
      $.each(photoPages[page],function(i){
        photoId = photoPages[page][i];
        $('#thumbs').append("<div class='imageFrame'><a href='http://www.flickr.com/photos/" + currentPhotos[photoId].owner + "/" + photoId + "/' target='_blank'><img src='http://farm" + currentPhotos[photoId].farm + ".static.flickr.com/" + currentPhotos[photoId].server + "/" + photoId + "_" + currentPhotos[photoId].secret + "_t.jpg'/></a></div>");
      });
      currentPage = page;
      if(totalPages == 1){
        $('#prev').addClass('thumbsControlInactive');
        $('#next').addClass('thumbsControlInactive');
        $('#prev').unbind('click',prevPhotoPage);
        $('#next').unbind('click',nextPhotoPage);
        $('#prev a').removeAttr('href');
        $('#next a').removeAttr('href');
      } else if(currentPage == 0 && totalPages > 1){
        $('#prev').addClass('thumbsControlInactive');
        $('#next').removeClass('thumbsControlInactive');
        $('#prev').unbind('click',prevPhotoPage);
        $('#next').click(nextPhotoPage);
        $('#prev a').removeAttr('href');
        $('#next a').attr({href:'#'});
      } else if(currentPage == totalPages-1 && totalPages > 1) {
        $('#prev').removeClass('thumbsControlInactive');
        $('#next').addClass('thumbsControlInactive');
        $('#prev').click(prevPhotoPage);
        $('#next').unbind('click',nextPhotoPage);
        $('#prev a').attr({href:'#'});
        $('#next a').removeAttr('href');
      } else {
        $('#prev').removeClass('thumbsControlInactive');
        $('#next').removeClass('thumbsControlInactive');
        $('#prev').click(prevPhotoPage);
        $('#next').click(nextPhotoPage);
        $('#prev a').attr({href:'#'});
        $('#next a').attr({href:'#'});
      }
     if(currentPage+1 == totalPages){
      var endPhoto = totalPhotos;
      var startPhoto = ((currentPage+1)*12)-11;
     } else {
      var endPhoto = (currentPage+1)*12;
      var startPhoto = endPhoto - 11;
     }
      $('#paging span').remove();
      $('#paging').append('<span>Showing photos ' + startPhoto + ' - ' + endPhoto + ' of ' + totalPhotos + '</span>');
    }
    
    function nextPhotoPage(){
      setPhotoPage(currentPage+1);
      return false;
    }
    
    function prevPhotoPage(){
      setPhotoPage(currentPage-1);
      return false;
    }

    /********************************************
     * Date filtering
     *******************************************/
     function hApplyDateFilter(){
      $('#thumbs p').remove();
      var from = Date.parse($('#dateFrom').val());
      var to = Date.parse($('#dateTo').val());
      // need to get this test working
      if($('#dateFrom').val() == "Date from" || $('#dateTo').val() == "Date to"){
        return;
      } else {
        photoPages = new Array();
        var photos = new Array();
        $.each(currentPhotos, function(i,aPhoto){
          var dateTaken = Date.parse(aPhoto.date_taken.split(" ")[0].replace(/\-/g,'/'));
          if(dateTaken >= from && dateTaken <= to){
            photos.push(i);
          }
        });
        if(photos.length > 0){
          totalPhotos = photos.length;
          totalPages = Math.ceil(photos.length/12);
          for(var i=0; i<totalPages; i++){
            photoPages.push(new Array());
            for(var j=0; j<12; j++){
              if(photos[(i*12)+j] != undefined){
                photoPages[i].push(photos[(i*12)+j]);
              }
            }
          }
          setPhotoPage(0);
        } else {
          $('#thumbs .imageFrame').remove();
          $('#thumbs').append('<p>No photos in this location for the specified dates!</p>');
          $('#prev a').removeAttr('href');
          $('#next a').removeAttr('href');
          $('#prev').addClass('thumbsControlInactive');
          $('#next').addClass('thumbsControlInactive');
        }
        $('#clearDateFilter').removeAttr('disabled');
      }
     }
     
     function hClearDateFilter(){
        $('#thumbs p').remove();
        $('#clearDateFilter').attr({disabled:'disabled'});
        setCurrentPhotos(currentPhotos);
     }
