var voyage_maps = {
  map: null,
  maps: [],
  markers: [],
  singleton_marker: null,
  visible_info_window: null,
  circle: null,
  has_circle: false,
  icons: {},
  
  /*open_info_window: function(info_window, marker){
    return function(){
      if(voyage_maps.visible_info_window) {
        voyage_maps.visible_info_window.close();
      }
      info_window.open(voyage_maps.map, marker);
      voyage_maps.visible_info_window = info_window;
    }
  },*/
  add_marker: function(options){
    options.id = typeof(options.id) == 'undefined' ? voyage_maps.markers.length : options.id;
    var marker = new GMarker(options.position, options)
    voyage_maps.markers[options.id] = marker;
    voyage_maps.map.addOverlay(marker);
    return marker;
  },
  add_marker_info_window: function(options, marker){
    /*marker.html_tabs = [];
    for(var i=0; i<options.contents.length; i++) {
      marker.html_tabs.push(new GInfoWindowTab(options.titles[i], options.contents[i]));
    }
    GEvent.addListener(marker, "click", function() {
      marker.openInfoWindowTabsHtml(marker.html_tabs);
    });*/
    marker.info_window_html = options.content;
    GEvent.addListener(marker, "click", function() {
      marker.openInfoWindowHtml(marker.info_window_html);
    });
  },
  remove_marker: function(id){
    if(voyage_maps.markers[id]) {
      voyage_maps.map.removeOverlay(voyage_maps.markers[id]);
      delete voyage_maps.markers[id];
    }
  },
  click_on_marker: function(id){
    if(voyage_maps.markers[id]) {
      GEvent.trigger(voyage_maps.markers[id], 'click');
    }
  },
  
  set_map_type: function(type){
    voyage_maps.map.setMapType(type);
  },
  
  change_map: function(options){
    if(!voyage_maps.maps[options.canvas]) {
      options.zoom = options.zoom || voyage_maps.map.getZoom();
      options.center = options.center || voyage_maps.map.getCenter();
      voyage_maps.maps[options.canvas] = new GMap2(document.getElementById(options.canvas));
      voyage_maps.maps[options.canvas].setCenter(options.center, options.zoom);
      voyage_maps.maps[options.canvas].setUIToDefault();
      voyage_maps.maps[options.canvas].enableGoogleBar();
    }
    //voyage_maps.map.clearOverlays();
    //voyage_maps.map = voyage_maps.maps[options.canvas];
    if(voyage_maps.markers.length > 0) {
      for(var id in voyage_maps.markers) {
        if(id.match(/^\d+$/)) {
          voyage_maps.map.removeOverlay(voyage_maps.markers[id]);
          voyage_maps.maps[options.canvas].addOverlay(voyage_maps.markers[id]);
        }
      }
    }
    voyage_maps.map = voyage_maps.maps[options.canvas];
  },
  
  add_singleton_marker: function(callback){
    if(voyage_maps.singleton_marker == null){
      voyage_maps.singleton_marker = new GMarker(voyage_maps.map.getCenter(), {draggable: true, icon: voyage_maps.icons.singleton});
      GEvent.addListener(voyage_maps.singleton_marker, "dragstart", function() {
        voyage_maps.map.closeInfoWindow();
        if(voyage_maps.circle) {
          voyage_maps.circle.clear();
        }
      });
      GEvent.addListener(voyage_maps.singleton_marker, "dragend", function(e) {
        callback(e);
        if(voyage_maps.circle) {
          voyage_maps.circle.redraw();
        }
      });
      voyage_maps.map.addOverlay(voyage_maps.singleton_marker);
    } else {
      voyage_maps.singleton_marker.setLatLng(voyage_maps.map.getCenter());
      voyage_maps.singleton_marker.show();
    }
    callback(voyage_maps.map.getCenter());
  },
  
  remove_singleton_marker: function(callback){
    if(voyage_maps.singleton_marker != null) {
      voyage_maps.singleton_marker.hide();
    }
    callback();
  },
  
  add_circle: function(radius) {
    voyage_maps.has_circle = true;
    if(voyage_maps.circle == null) {
      voyage_maps.circle = new voyage_maps.circle_overlay({center: voyage_maps.map.getCenter(), radius: radius});
      voyage_maps.map.addOverlay(voyage_maps.circle);
    } else {
      voyage_maps.circle.set_center(voyage_maps.map.getCenter());
      voyage_maps.circle.set_radius(radius);
    }
  },
  remove_circle: function() {
    if(voyage_maps.circle != null) {
      voyage_maps.circle.remove();
      voyage_maps.has_circle = false;
    }
  },
  
  edit_trip: {
    add_country: function(){
      var new_country_id = $('#countries div.country').length;
      var new_country = $('#countries div:first').clone()
        .attr('id', 'country_holder_'+new_country_id)
        .hide();
      new_country.find('select')
        .val('0')
        .attr('id', 'country_'+new_country_id)
        .attr('name', 'countries['+new_country_id+'][id]')
        .change(function(){
          voyage_maps.edit_trip.on_country_change($(this), new_country_id);
        }).next()
          .attr('id', 'country_details_'+new_country_id)
          .click(function(){
            $('#country_cities_holder_'+new_country_id).slideToggle();
            return false;
          });
      new_country.find('div.cities_holder')
        .html('')
        .attr('id', 'country_cities_holder_'+new_country_id);
      
      new_country.insertAfter('#countries div.country:last').show();
      $('#country_destroy').show();
    },
    add_city: function(country_id, country_iso){
      var new_city_id = $('#country_cities_holder_'+country_id+' div.city_holder').length;
      var new_city = $('#country_cities_holder_'+country_id+' div:first').clone()
        .attr('id', 'country_city_holder_'+country_id+'_'+new_city_id)
        .hide();
      new_city.find('input:first')
        .attr('id', 'country_city_'+country_id+'_'+new_city_id+'_lat')
        .attr('name', 'countries['+country_id+'][cities]['+new_city_id+'][lat]')
        .next()
          .attr('id', 'country_city_'+country_id+'_'+new_city_id+'_lng')
          .attr('name', 'countries['+country_id+'][cities]['+new_city_id+'][lng]');
      new_city.find('select')
        .val('0')
        .attr('id', 'city_'+country_id+'_'+new_city_id)
        .attr('name', 'countries['+country_id+'][cities]['+new_city_id+'][id]')
        .change(function(){
          voyage_maps.edit_trip.on_city_change($(this), country_id, new_city_id)
        });
      new_city.find('input[type=text]')
        .attr('id', 'country_city_'+country_id+'_'+new_city_id)
        .attr('name', 'countries['+country_id+'][cities]['+new_city_id+'][name]')
        .next()
          .attr('id', 'country_city_status_'+country_id+'_'+new_city_id)
          .parent()
            .attr('id', 'country_city_input_'+country_id+'_'+new_city_id)
            .hide();
      new_city.children(':last')
        .html('')
        .attr('id', 'country_city_places_holder_'+country_id+'_'+new_city_id);
      
      new_city.insertAfter('#country_cities_holder_'+country_id+' div.city_holder:last').show();
      $('#country_destroy_city_'+country_id).show();
    },
    add_place: function(country_id, city_id){
      var new_place_id = $('#country_city_places_holder_'+country_id+'_'+city_id+' div.place_holder').length;
      var new_place = $('#country_city_places_holder_'+country_id+'_'+city_id+' div:first').clone()
        .attr('id', 'country_city_place_holder_'+country_id+'_'+city_id+'_'+new_place_id)
        .hide();
      new_place.find('input:first')
        .attr('id', 'country_city_place_'+country_id+'_'+city_id+'_'+new_place_id+'_lat')
        .attr('name', 'countries['+country_id+'][cities]['+city_id+'][places]['+new_place_id+'][lat]')
        .next()
        .attr('id', 'country_city_place_'+country_id+'_'+city_id+'_'+new_place_id+'_lng')
        .attr('name', 'countries['+country_id+'][cities]['+city_id+'][places]['+new_place_id+'][lng]');
      new_place.find('input[type=text]')
        .attr('id', 'country_city_place_'+country_id+'_'+city_id+'_'+new_place_id)
        .attr('name', 'countries['+country_id+'][cities]['+city_id+'][places]['+new_place_id+'][name]')
        .val('')
        .next()
          .hide()
          .click(function(){
            voyage_maps.edit_trip.place_marker_place(country_id, city_id, new_place_id);
            return false;
          }).next()
            .hide()
            .click(function(){
              voyage_maps.edtit_trip.remove_marker_place(country_id, city_id, new_place_id);
              return false;
            }).next()
              .hide()
              .click(function(){
                voyage_maps.edit_trip.zoom_to_place(country_id, city_id, new_place_id);
                return false;
              });
      new_place.insertAfter('#country_city_places_holder_' + country_id + '_' + city_id + ' div.place_holder:last').show();
      $('#country_city_destroy_place_'+country_id+'_'+city_id).show();
    },
    
    on_country_change: function(object, id) {
      $('#country_cities_holder_' + id).children().each(function(){
        voyage_maps.edit_trip.remove_city($(this));
      });
      if(object.val() != 0) {
        if(voyage_maps.markers[object.attr('id')]){
          voyage_maps.markers[object.attr('id')].setLatLng(new GLatLng(object.children('[@selected]').attr('lat'), object.children('[@selected]').attr('lng')));
        } else {
          voyage_maps.add_marker({
            position: new GLatLng(object.children('[@selected]').attr('lat'), object.children('[@selected]').attr('lng')),
            icon: voyage_maps.icons.country,
            id: object.attr('id')
          });
        }
        voyage_maps.map.setCenter(new GLatLng(object.children('[@selected]').attr('lat'), object.children('[@selected]').attr('lng')));
        /*if($('#country_cities_holder_' + id).children().length > 0) {
          $('#country_cities_holder_' + id).children().each(function(i){
            voyage_maps.edit_trip.remove_city($(this));
          });
        }*/
        $('#country_cities_holder_' + id + ':hidden').slideDown();
        $('#country_cities_holder_' + id).html('<img src="/images/vajax-loader.gif"/>')
          .load('/trip/cities', {
            'country_id': object.val(),
            'html_id': id,
            'authenticity_token': authenticity_token
          });
      } else {
        $('#country_cities_holder_' + id).html('');
        voyage_maps.remove_marker(object.attr('id'));
      }
    },
    on_city_change: function(object, country_id, city_id){
      $('#country_city_places_holder_' + country_id + '_' + city_id).children().each(function(){
        voyage_maps.edit_trip.remove_place($(this));
      });
      if(object.val() != 0 && object.val() != -1 ) {
        voyage_maps.add_marker({
          position: new GLatLng(object.children('[@selected]').attr('lat'), object.children('[@selected]').attr('lng')),
          icon: voyage_maps.icons.city,
          id: 'country_' + object.attr('id')
        });
        voyage_maps.map.setCenter(new GLatLng(object.children('[@selected]').attr('lat'), object.children('[@selected]').attr('lng')));
        $('#country_city_input_' + country_id + '_' + city_id).hide();
        $('#country_city_places_holder_' + country_id + '_' + city_id).show();
        
        $('#country_city_places_holder_' + country_id + '_' + city_id).html('<img src="/images/vajax-loader.gif"/>')
          .load('/trip/places',{
            city: object.children('[@selected]').text(),
            html_country_id: country_id,
            html_city_id: city_id,
            authenticity_token: authenticity_token
        });
      } else {
        $('#country_city_' + country_id + '_' + city_id).val('');
        voyage_maps.remove_marker('country_city_' + country_id + '_' + city_id);
      }
      if( object.val() == 0 ) {
        $('#country_city_input_' + country_id + '_' + city_id).hide();
        $('#country_city_places_holder_' + country_id + '_' + city_id).hide();
      }
      if( object.val() == -1 ) {
        $('#country_city_input_' + country_id + '_' + city_id).show()
          .children(':first')
          .val('')
          .next()
          .html('');
        $('#country_city_places_holder_' + country_id + '_' + city_id).hide();
      }
    },
    
    remove_country: function(object){
      object.find('div.cities_holder div.city_holder').children().each(function(){
        voyage_maps.edit_trip.remove_city($(this));
      });
      voyage_maps.remove_marker(object.find('select').attr('id'));
      object.remove();
    },
    remove_city: function(object){
      object.children(':last').children().each(function(){
        voyage_maps.edit_trip.remove_place($(this));
      });
      voyage_maps.remove_marker(object.find('input[type=text]').attr('id'));
      object.remove();
    },
    remove_place: function(object){
      voyage_maps.remove_marker(object.find('input[type=text]').attr('id'));
      object.remove();
    },
    
    destroy_country: function() {
      var last_country_id = $('#countries div.country').length - 1;
      $('#country_holder_'+last_country_id).hide(1, function(){
        voyage_maps.edit_trip.remove_country($(this));
      });
      if(last_country_id == 1) {
        $('#country_destroy').hide();
      }
    },
    destroy_city: function(country_id) {
      var last_city_id = $('#country_cities_holder_'+country_id+' div.city_holder').length - 1;
      $('#country_city_holder_'+country_id+'_'+last_city_id).hide(1, function(){
        voyage_maps.edit_trip.remove_city($(this));
      });
      if(last_city_id == 1) {
        $('#country_destroy_city_'+country_id).hide();
      }
    },
    destroy_place: function(country_id, city_id) {
      var last_place_id = $('#country_city_places_holder_'+country_id+'_'+city_id+' div.place_holder').length - 1;
      $('#country_city_place_holder_'+country_id+'_'+city_id+'_'+last_place_id).hide(1, function(){
        voyage_maps.edit_trip.remove_place($(this));
      });
      if(last_place_id == 1) {
        $('#country_city_destroy_place_'+country_id+'_'+city_id).hide();
      }
    }
  },
  
  init_map: function(options){
    options.canvas = options.canvas || "map_canvas";
    options.zoom = options.zoom || 12;
    options.center = options.center || new GLatLng(48.8566667, 2.3509871);
    voyage_maps.map = new GMap2(document.getElementById(options.canvas));
    voyage_maps[options.canvas] = voyage_maps.map;
    voyage_maps.map.setCenter(options.center, options.zoom);
    if(options.controls) {
      for(var i = 0; i < options.controls.length; i++) {
        voyage_maps.map.addControl(options.controls[i]);
      }
    } else {
      voyage_maps.map.setUIToDefault();
    }
  },
  
  init: function(){
    var base_icon_options = new GIcon(G_DEFAULT_ICON);
    base_icon_options.iconSize = new GSize(17, 30);
    base_icon_options.iconAnchor = new GPoint(8, 30);
    base_icon_options.shadow = "";
    
    var singleton_icon_options = new GIcon(G_DEFAULT_ICON);
    singleton_icon_options.iconSize = new GSize(27, 48);
    singleton_icon_options.iconAnchor = new GPoint(14, 48);
    singleton_icon_options.shadow = "";
    
    voyage_maps.icons = {
      country: new GIcon(base_icon_options, '/images/icons/markers/red5.png'),
      city: new GIcon(base_icon_options, '/images/icons/markers/blue5.png'),
      place: new GIcon(base_icon_options, '/images/icons/markers/green5.png'),
      hotel: new GIcon(base_icon_options, '/images/icons/markers/orange5.png'),
      singleton: new GIcon(singleton_icon_options, '/images/icons/markers/singleton.png'),
      indexed_hotel: function(index) {
        return new GIcon(base_icon_options, '/images/icons/markers/hotel'+index+'.png')
      }
    }
    
    if(arguments.length > 0){
      voyage_maps.init_map(arguments[0]);
    }
  }
}

voyage_maps.circle_overlay = function(options) {
  var defaults = {
    radius: options.radius || 2000, //meters
    stroke_color: "#336699",
    stroke_width: 1,
    stroke_opacity: 1,
    fill_color: "#336699",
    fill_opacity: 0.25
  }
  $.extend(options, defaults);
  this.center = options.center;
  this.radius = options.radius;
  this.stroke_color = options.stroke_color;
  this.stroke_width = options.stroke_width;
  this.stroke_opacity = options.stroke_opacity;
  this.fill_color = options.fill_color;
  this.fill_opacity = options.fill_opacity;
}

// Implements GOverlay interface
voyage_maps.circle_overlay.prototype = new GOverlay;

voyage_maps.circle_overlay.prototype.initialize = function() {
  this.map = voyage_maps.map;
}

voyage_maps.circle_overlay.prototype.clear = function() {
  if(this.polygon != null && this.map != null) {
    this.map.removeOverlay(this.polygon);
  }
}

// Calculate all the points and draw them
voyage_maps.circle_overlay.prototype.redraw = function(force) {
  if(voyage_maps.has_circle) {
    var d2r = Math.PI / 180;
    var circle_latlngs = new Array();
    var circle_lat = this.radius * 0.000008999318977;  // Convert statute meters into degrees latitude
    var circle_lng = circle_lat / Math.cos(this.center.lat() * d2r);
    var total_points = 45;
   
    // 2PI = 360 degrees, +1 so that the end points meet
    for (var i = 0; i < total_points + 1; i++) {
      var theta = Math.PI * (i / (total_points / 2));
      var lat = this.center.lat() + (circle_lat * Math.sin(theta));
      var lng = this.center.lng() + (circle_lng * Math.cos(theta));
      var point = new GLatLng(lat, lng);
      circle_latlngs.push(point);
    }
    
    this.clear();
    this.polygon = new GPolygon(circle_latlngs, this.stroke_color, this.stroke_width, this.stroke_opacity, this.fill_color, this.fill_opacity);
    this.map.addOverlay(this.polygon);
  }
}

voyage_maps.circle_overlay.prototype.remove = function() {
  this.clear();
}

voyage_maps.circle_overlay.prototype.containsLatLng = function(latLng) {
  // Polygon Point in poly
  if(this.polygon.containsLatLng) {
    return this.polygon.containsLatLng(latLng);
  }
  return null;
}

voyage_maps.circle_overlay.prototype.set_radius = function(radius) {
  this.radius = radius;
  this.redraw();
}

voyage_maps.circle_overlay.prototype.set_center = function(point) {
  this.center = point;
}
