/*global $: false, user_lat: false, user_lng: false, google: false */

var GreenBee = (function () {
  var pub_obj,
    geocoder,
    markers,
    info_window,
    codeLatLng,
    addMarker,
    moveMarker,
    codeAddress,
    resetView,
    removeMarkers,
    marker_draggable = false,
    address_timeout,
    what_timeout,
    draggedMarker = null,
    search_string = "",
    stylez = [
      {
        stylers: [
          { saturation: -100 }
        ]
      },{
        featureType: "administrative.country",
        elementType: "labels",
        stylers: [
          { visibility: "off" }
        ]
      },{
        featureType: "water",
        elementType: "labels",
        stylers: [
          { visibility: "off" }
        ]
      },{
        featureType: "road.highway",
        elementType: "labels",
        stylers: [
          { visibility: "off" }
        ]
      },{
        featureType: "poi",
        stylers: [
          { visibility: "off" }
        ]
      },{
        featureType: "road",
        stylers: [
          { lightness: 10 }
        ]
      },{
        featureType: "water",
        stylers: [
          { lightness: -81 }
        ]
      },{
        featureType: "landscape.man_made",
        elementType: "geometry",
        stylers: [
          { lightness: 50 }
        ]
      }
    ];
  
  
  $(document).ready(function () {
    // Animate flash messages
    $('.message').effect('bounce', null, 'fast').delay(5000).hide('drop', { direction: "down" }, 'fast');
    
    // Set up user links
    $('a.user').click(function () {
      var link = $(this),
        container = $('#user-label');
      container.html('')
        .load($(this).attr('href'), function () {
          $(this)
        })
        .show()
        .css('left', link.offset().left - container.width() / 2)
        .css('top', link.offset().top - container.height() / 2);
      
      $('body').click(function () {
        container.hide();
      });
      return false;
    });
    
    $('a').click(function (e) {
      $(this).addClass('clicked');
    });
    
    $('.prefilled').addClass('prefilledin');
    $('.prefilledin').focus(function () {
      $(this).attr('value', '');
      $(this).removeClass('prefilledin');
      $(this).unbind('focus');
    });
    $('.nosubmit').submit(function () {
      return false;
    });
    
    $('.focus').focus();
    $('#focus').focus();
    
    $('.closable').prepend('<a class="close_button">&times;</a>');
    $('.closable .close_button').click(function (e) {
      $(this).parent().hide('drop', { direction: "down" }, 'fast');		
      e.preventDefault();
    });
    
    // Slideshow
    $('.images li:gt(0)').hide();
    $('.images a.prev').fadeTo(0, 0.5);
    $('.images').data('index', 0);
    $('.images a.next').click(function () {
      var index = $('.images').data('index'),
        lis = $(this).parent().parent().find('li'),
        left = lis.size() - index -1;
      if(left >= 1){
        lis.eq(index).fadeOut(500);
        
        index++;
        $('.images').data('index', index);
        lis.eq(index).delay(500).fadeIn(500);	
        
        if(left <= 1){
          $(this).fadeTo(500, 0.5);
        }
        $(this).parent().find('.prev').fadeTo(500, 1);
      }
      return false;
    });
    $('.images a.prev').click(function () {
      var index = $('.images').data('index'),
        lis = $(this).parent().parent().find('li');
      if(index >= 1){
        lis.eq(index).fadeOut(500);
        
        index--;
        $('.images').data('index', index);
        lis.eq(index).delay(500).fadeIn(500);	
        
        if(index <= 1){
          $(this).fadeTo(500, 0.5);
        }
        $(this).parent().find('.next').fadeTo(500, 1);
      }
      return false;
    });
    
    $('.hidden_form').hide();
    $('.show_more').click(function () {
      $(this).hide();
      $('.hidden_form').fadeIn(500);
      return false;
    });
  });
  
  
  /* Public functions */
  
  pub_obj = {
    maxBounds: null,
    map: null,
    smallmap: null,
    mc: null,
    map_min_height: 0,
    def_latlng: null,
    def_zoom: 10,
    current_marker_id: -1,
    initialize: function (autoRefresh) {
      
      if (typeof(autoRefresh) == "undefined") {
        autoRefresh = true;
      }
      var myOptions, usRoadMapType, lat, lng, ll;
      this.def_latlng = new google.maps.LatLng(52.133488, 5.289917);
      myOptions = {
        zoom: this.def_zoom,
        center: this.def_latlng,
        mapTypeControl: false,
        panControl: false,
        rotateControl: true,
        navigationControlOptions : {position: google.maps.ControlPosition.RIGHT_CENTER}
      };
      this.map = new google.maps.Map(document.getElementById("map"), myOptions);
      usRoadMapType = new google.maps.StyledMapType(stylez, {name: 'gb', minZoom: 7});
      this.map.mapTypes.set('gb', usRoadMapType);
      this.map.setMapTypeId('gb');
      google.maps.event.addListener(this.map, 'zoom_changed', function() {
        if (pub_obj.map.getZoom() > 15) {
          pub_obj.map.setMapTypeId(google.maps.MapTypeId.HYBRID);
        } else {
          pub_obj.map.setMapTypeId('gb');
        }
      });
      google.maps.event.addListener(this.map, 'bounds_changed', function () {
        $('.map-label').hide();
      });
      
      if (autoRefresh) {
        google.maps.event.addListener(GreenBee.map, 'idle', function(){
          GreenBee.loadMarkersOnMap();
        });
      }
      
      if($("#smallmap").length > 0){
        myOptions.navigationControl = false;
        myOptions.streetViewControl = false;
        myOptions.draggable = false;
        myOptions.scrollwheel = false;
        myOptions.disableDoubleClickZoom = true;
        this.smallmap = new google.maps.Map(document.getElementById("smallmap"), myOptions);
        this.smallmap.mapTypes.set('gb', usRoadMapType);
        this.smallmap.setMapTypeId('gb');
      }
      
      this.mc = new MarkerClusterer(this.map, null, {styles: [{
        url: '/img/cloud.png',
        height: 17,
        width: 17,
        opt_textColor: '#ffffff',
        opt_textSize: 900
        },{
        url: '/img/cloud.png',
        height: 17,
        width: 17,
        opt_textColor: '#ffffff',
        opt_textSize: 900
        },{
        url: '/img/cloud.png',
        height: 17,
        width: 17,
        opt_textColor: '#ffffff'
        }]});
      this.mc.setGridSize(30);
      
      geocoder = new google.maps.Geocoder();
      
      if ($('#address_lookup').length > 0) {
        $('#address_remove').click(function () {
          $('#lat').attr('value', '');
          $('#lng').attr('value', '');
          $('#address_lookup').attr('value', '');
          $('#address').attr('value', '');
          
          removeMarkerDraggable();
          resetView();
          return false;
        });
        if ($('#lat').attr('value') && $('#lat').attr('value') !== '0') {
          lat = $('#lat').attr('value');
          lng = $('#lng').attr('value');
          ll = new google.maps.LatLng(lat, lng);
          addDragMarker(ll);
          this.map.panTo(ll);
          this.map.setZoom(14);
        }
    
  
        $('#address_copy').click(function () {
          ll = new google.maps.LatLng(user_lat, user_lng);
          moveMarker(ll);
          pub_obj.map.panTo(ll);
          pub_obj.map.setZoom(14);
          
          return false;
        });
        $('#ask_address input').keydown(function (e) {
          if ((e.which && e.which == 13) || (e.keyCode && e.keyCode == 13)) {
            $(this).select();
            return false;
          }
        });
        $('#address_lookup').keyup(function (event) {
          if (typeof(address_timeout) !== 'undefined') {
            clearTimeout(address_timeout);
          }
          if ($('#address_lookup').attr('value') !== '') {
            $('#address_lookup').addClass('loading');
            address_timeout = setTimeout(codeAddress, 1500);
          } else {
            $('#address_lookup').removeClass('loading');
          }
        });
        
      
        if ($('#what_lookup').length > 0 )
        {
          $('#what_lookup').keyup(function (e) {
            if (typeof(what_timeout) !== 'undefined')
            {
              clearTimeout(what_timeout);
            }
            $('#what_lookup').removeClass('loading');
            if($(this).val() != search_string)
            {
              $('#what_lookup').addClass('loading');
              what_timeout = setTimeout(searchWhat, 1500);
            }
          });
        }
      }
      
      // Animate blog hover
      if ($('.col.blog').length > 0)
      {
        var blog_block = $('.col.blog');
        blog_block.css('cursor', 'pointer');
        blog_block.hover(function () {
          var link = $(this).find('a');
          link.stop().css('position', 'relative').animate({opacity: 0.75, left: 10}, 250);
        }, function () {
          var link = $(this).find('a');
          link.stop().css('position', 'relative').animate({opacity: 1, left: 0}, 125);
        });
        blog_block.click(function () {
          var link = $(this).find('a');
          window.location.href = link.attr('href');
        });
      }
      
      // Animate logo hover
      if ($('#logo').length > 0)
      {
        var blog_block = $('#logo');
        blog_block.hover(function () {
          var link = $(this);
          link.stop().animate({opacity: 0.5}, 250);
        }, function () {
          var link = $(this);
          link.stop().animate({opacity: 1}, 250);
        });
        blog_block.click(function () {
          var link = $(this).find('a');
          window.location.href = link.attr('href');
        });
      }
      
      // Auto-resize large map
      if ($('#map.large').length > 0) {
        // Save css value of height for minimum size
        this.map_min_height = $('#map.large').height();
        
        $(window).resize(function () {
          var map = $('#map.large'),
          targetSize = $(window).height() - $('#header').outerHeight(true) - $('#footer').outerHeight(true) - $('.main').outerHeight(true) - 5;
          targetSize = Math.max(pub_obj.map_min_height, targetSize);
          map.height(targetSize);
        });
        
        $(window).resize();
      }
    },
    makeMarkerDraggable: function () {
      marker_draggable = true;
      google.maps.event.addListener(this.map, 'click', function (event) {
        moveMarker(event.latLng);
      });
    },
    addUserMarker: function (ll, role, id, name, type) {
      addMarker(ll, role, id, name, type);
    },
    addCurrentMarker: function (ll, role, id, name, type) {
      var m = createMarker(ll, 3, id, name, type);
      markers.push(m);
      m.setMap(pub_obj.map)
      if (pub_obj.smallmap != null) {
        var m2 = createMarker(ll, 3, id, name, type);
        m2.setMap(pub_obj.smallmap)
      }
    },
    loadMarkersOnMap: function () {
      var url = '/alerts/latlng/',
        bounds = this.map.getBounds(),
        newNE = new google.maps.LatLng(Math.ceil(bounds.getNorthEast().lat()) + 1, Math.ceil(bounds.getNorthEast().lng()) + 1),
        newSW = new google.maps.LatLng(Math.floor(bounds.getSouthWest().lat()) - 1, Math.floor(bounds.getSouthWest().lng()) - 1),
        newbounds = new google.maps.LatLngBounds(newSW, newNE);
      if(this.maxBounds == null || !(this.maxBounds.contains(bounds.getNorthEast()) && this.maxBounds.contains(bounds.getSouthWest()))){
        this.maxBounds = newbounds;
        url = url + newbounds.getNorthEast().lat() + "," + newbounds.getNorthEast().lng();
        url = url + "/";
        
        url = url + newbounds.getSouthWest().lat() + "," + newbounds.getSouthWest().lng();
        var delete_old = false;
        if (search_string != "")
        {
          url = url + "/";        
          url = url + search_string;
          
          delete_old = true;
        }
        this.loadMarkers(url, delete_old);
      }
    },
    loadMarkers: function (url, delete_old) {
      $.getJSON(url, function(json) {
        $('#what_lookup').removeClass('loading');
        if(delete_old) {
          removeMarkers();
        }
        if (json !== null && json.length > 0) { 
          GreenBee.mc.clearMarkers();
          for (i=0; i<json.length; i++) { 
            var location = json[i].Alert;
            if(location.id != GreenBee.current_marker_id){
              var role = 2;
              if(location.personal == 1){
                role = 3
              }
              
              addMarker(new google.maps.LatLng(location.lat, location.lng), role, location.id, location.title, 'alert', location);
            }
          }
        }
        var last_search_string = url.split('/').pop();
        
        var latlng_pattern = /-?\d+,-?\d+/;
        if (latlng_pattern.test(last_search_string))
        {
          last_search_string = "";
        }
        
        var jsonlength = json !== null ? json.length : 0;
        $('body').trigger('update_markers', [last_search_string, jsonlength]);
      });
    },
    showStreetview: function () {
      
      pub_obj.map.setMapTypeId(google.maps.MapTypeId.HYBRID);
      // Check availability
      new google.maps.StreetViewService().getPanoramaByLocation(pub_obj.map.getCenter(), 35, function (data, status) {
        if(status === "OK") {	
          var sv_opts = {
            position: pub_obj.map.getCenter(),
            addressControl: false,
            panControl: false,
            zoomControl: false,
            enableCloseButton: false
          };

          var panorama = new  google.maps.StreetViewPanorama(document.getElementById("map"), sv_opts);
          panorama.setVisible(true);	
          pub_obj.map.setStreetView(panorama);
        }
      });
    },
    getMarkerCount: function () {
      return markers.length;
    }
  };
  
  /* Private functions */
  
  resetView = function () {
    pub_obj.map.setCenter(pub_obj.def_latlng);
    pub_obj.map.setZoom(pub_obj.def_zoom);
  };
  
  removeMarkers = function () {
    
    $('.map-label').hide();
    
    if (typeof(markers) !== 'undefined') {
      while (markers.length > 0) {
        markers.pop().setMap(null);
      }
      pub_obj.mc.clearMarkers();
    }
  };
  
  addDragMarker = function (ll) {
    var icon_path;
    
    if (typeof(markers) === 'undefined') {
      markers = [];
    }
    icon_path = '/img/marker.png';
    
    draggedMarker = new google.maps.Marker({
      position: ll,
      icon: icon_path,
      draggable: true
    });
    google.maps.event.addListener(draggedMarker, 'dragend', function (event) {
      moveMarker(event.latLng);
    });
    
    $('#lat').attr('value', ll.lat());
    $('#lng').attr('value', ll.lng());
    
    draggedMarker.setMap(pub_obj.map);
    
    codeLatLng(ll);
  }
  
  createMarker = function (ll, role, id, name, type, data) {
    var icon_path, m;
    
    name = typeof(name) !== 'undefined' ? name : '';
    if (typeof(markers) === 'undefined') {
      markers = [];
    }
    if (typeof(role) === 'undefined' || role === 0) {
      icon_path = '/img/marker_a.png';
    } else {
      if (role === 3) {
        icon_path = '/img/marker.png';
      } else {
        icon_path = '/img/marker_a.png';
      }
    }
    
    m = new google.maps.Marker({
      position: ll,
      icon: icon_path,
      title: name
    });
    if (typeof(id) !== 'undefined') {
      if (typeof(type) === 'undefined') {
        type = 'alert';
      }
      google.maps.event.addListener(m, 'click', function () {
        var scale = Math.pow(2, pub_obj.map.getZoom());
        var nw = new google.maps.LatLng(
            pub_obj.map.getBounds().getNorthEast().lat(),
            pub_obj.map.getBounds().getSouthWest().lng()
        );
        var worldCoordinateNW = pub_obj.map.getProjection().fromLatLngToPoint(nw);
        var worldCoordinate = pub_obj.map.getProjection().fromLatLngToPoint(ll);
        var pixelOffset = new google.maps.Point(
            Math.floor((worldCoordinate.x - worldCoordinateNW.x) * scale),
            Math.floor((worldCoordinate.y - worldCoordinateNW.y) * scale)
        );        
        var icon_height = 20;
        
        var label = $('.map-label');
        label.hide().find('h2').text(name);
        label.find('p').text(data.body.substr(0, 70) + '...');
        label.find('a').attr('href', '/' + type + 's/view/' + id);
        label.css('left', pixelOffset.x - label.width() / 2);
        label.css('top', pixelOffset.y + $('#map').offset().top - icon_height);
        label.hide().fadeIn();
        // document.location.href = '/' + type + 's/view/' + id;
      });
    }
    return m;
  }
  
  addMarker = function (ll, role, id, name, type, data) {
    data = data || {};
    var m = createMarker(ll, role, id, name, type, data);
    markers.push(m);
    pub_obj.mc.addMarker(m, 0);
  };
    
  codeLatLng = function (latlng) {
    if ($('.address').length > 0) {
      geocoder.geocode({'latLng': latlng, 'region': 'nl', 'language': 'nl'}, function (results, status) {
        if (status === google.maps.GeocoderStatus.OK) {
          if (results[0]) {
            $('.address').attr('value', results[0].formatted_address);
            
            $('#lat').attr('value', latlng.lat());
            $('#lng').attr('value', latlng.lng());
          }
        } else {
          $('#address').attr('value', "");
        }
      });
    }
  };
  
  moveMarker = function (latLng) {
    if(draggedMarker == null){
      pub_obj.map.panTo(latLng);
      pub_obj.map.setZoom(14);
    }
    removeMarkerDraggable();
    addDragMarker(latLng);
  };
  
  removeMarkerDraggable = function () {
    if(draggedMarker != null){
      draggedMarker.setMap(null);
    }
  };
  
  codeAddress = function () {
    var address = document.getElementById("address_lookup").value;
    geocoder.geocode({'address': address,  'region': 'nl', 'language': 'nl'}, function (results, status) {
      $('#address_lookup').removeClass('loading');
      if (status === google.maps.GeocoderStatus.OK) {
        pub_obj.map.panTo(results[0].geometry.location);
        pub_obj.map.setZoom(11);
        
        if (marker_draggable) {				
          removeMarkerDraggable();
          addDragMarker(results[0].geometry.location);
        }
        $('.address').attr('value', results[0].formatted_address);
      } else {
        $('.address').attr('value', "");
      }
    });
  };
  
  searchWhat = function () {
    search_string = $('#what_lookup').val();
    pub_obj.maxBounds = null;
    pub_obj.loadMarkersOnMap();
  };
    
  return pub_obj;
}());
