
//  set global variables
function initMap(map_id) {
  map = new google.maps.Map2($(map_id));
  resultMarkers = [];
  locationMarkers = [];
  mapLastMarker = null;
}

function createBaseIcon() {
  var baseIcon = new google.maps.Icon(G_DEFAULT_ICON);
  baseIcon.shadow = "http://www.google.com/mapfiles/shadow50.png";
  baseIcon.iconSize = new google.maps.Size(20, 34);
  baseIcon.shadowSize = new google.maps.Size(37, 34);
  baseIcon.iconAnchor = new google.maps.Point(9, 34);
  baseIcon.infoWindowAnchor = new google.maps.Point(9, 2);
  return baseIcon;
}

function getSearchIconSettings() {
  return {iconSize: new google.maps.Size(24, 38)}
}

function getIconSettings(category_keyword) {
  switch (category_keyword) {
  case 'airport': return {iconSize: new google.maps.Size(60.0, 43.0),
                     shadowSize: new google.maps.Size(82.0, 43.0),
                     imageMap: [29,41,24,27,3,33,1,26,6,20,0,14,7,11,19,14,23,9,31,9,32,6,27,3,37,0,56,2,53,8,49,8,39,19,59,24,54,32,32,29],
                     iconAnchor: new google.maps.Point(30.0, 21.0),
                     infoWindowAnchor: new google.maps.Point(30.0, 21.0)};
  case 'attraction': return {iconSize: new google.maps.Size(49.0, 52.0),
                        shadowSize: new google.maps.Size(76.0, 52.0),
                        imageMap: [26,51,21,38,8,39,3,36,0,24,4,15,4,6,17,0,33,3,48,12,48,36,37,41,31,38],
                        iconAnchor: new google.maps.Point(24.0, 26.0),
                        infoWindowAnchor: new google.maps.Point(24.0, 26.0)};
  case 'ceremony': return {iconSize: new google.maps.Size(43.0, 55.0),
                      shadowSize: new google.maps.Size(71.0, 55.0),
                      imageMap: [21,56,17,43,1,42,0,22,1,3,21,1,42,3,42,23,42,42,26,43],
                      iconAnchor: new google.maps.Point(21.0, 27.0),
                      infoWindowAnchor: new google.maps.Point(21.0, 27.0)};
  case 'entertainment': return {iconSize: new google.maps.Size(32.0, 62.0),
                           shadowSize: new google.maps.Size(64.0, 62.0),
                           imageMap: [17,62,12,50,0,44,4,39,4,29,0,22,0,4,6,0,17,1,23,1,33,6,33,27,28,30,29,40,33,46,29,51,20,51],
                           iconAnchor: new google.maps.Point(16.0, 31.0),
                           infoWindowAnchor: new google.maps.Point(16.0, 31.0)};
  case 'hotel': return {iconSize: new google.maps.Size(47.0, 66.0),
                   shadowSize: new google.maps.Size(81.0, 68.0),
                   imageMap: [24,66,20,53,0,51,0,33,0,16,18,0,46,15,46,32,46,51,28,53],
                   iconAnchor: new google.maps.Point(23.0, 33.0),
                   infoWindowAnchor: new google.maps.Point(23.0, 33.0)};
  case 'reception': return {iconSize: new google.maps.Size(44.0, 58.0),
                       shadowSize: new google.maps.Size(74.0, 58.0),
                       imageMap: [22,57,18,44,6,43,0,36,2,31,2,23,6,21,7,13,8,2,21,0,33,4,33,11,36,13,36,19,39,23,40,31,42,36,39,42,27,44],
                       iconAnchor: new google.maps.Point(22.0, 29.0),
                       infoWindowAnchor: new google.maps.Point(22.0, 29.0)};
  case 'residence': return {iconSize: new google.maps.Size(66.0, 61.0),
                   shadowSize: new google.maps.Size(97.0, 61.0),
                   imageMap: [33,60,28,47,3,43,2,23,1,23,1,16,11,0,16,0,43,8,49,6,54,6,54,12,65,18,64,25,62,25,61,41,38,47],
                   iconAnchor: new google.maps.Point(33.0, 33.0),
                   infoWindowAnchor: new google.maps.Point(33.0, 33.0)};
  case 'restaurant': return {iconSize: new google.maps.Size(53.0, 51.0),
                        shadowSize: new google.maps.Size(79.0, 51.0),
                        imageMap: [26,49,9,34,0,27,6,19,12,7,21,3,26,0,31,3,40,7,47,19,52,26,40,35,30,36],
                        iconAnchor: new google.maps.Point(26.0, 25.0),
                        infoWindowAnchor: new google.maps.Point(26.0, 25.0)};
  }
}

// result_idx is only needed if creating an icon for a search result
function createCustomIcon(category_keyword, result_idx) {
  var customIcon = createBaseIcon();

  var imageBaseUrl = '/images/wedding_website/map_icons/';
  if (category_keyword == 'search') {
    customIcon.image = imageBaseUrl+'/icon_yellow'+(result_idx+1)+'.png';
    var iconSettings = getSearchIconSettings();
    customIcon.iconSize = iconSettings['iconSize'];
  } else {
    customIcon.image = imageBaseUrl+category_keyword+'-icon.png';
    customIcon.shadow = imageBaseUrl+category_keyword+'-shadow.png';
    customIcon.printImage = imageBaseUrl+category_keyword+'-icon-print.gif';
    customIcon.mozPrintimage = imageBaseUrl+category_keyword+'-icon-mozprint.gif';
    customIcon.printShadow = imageBaseUrl+category_keyword+'-print-shadow.gif';
    customIcon.transparent = imageBaseUrl+category_keyword+'-transparent.png';

    var iconSettings = getIconSettings(category_keyword);
    customIcon.iconSize = iconSettings['iconSize'];
    customIcon.shadowSize = iconSettings['shadowSize'];
    customIcon.iconAnchor = iconSettings['iconAnchor'];
    customIcon.infoWindowAnchor = iconSettings['infoWindowAnchor'];
    customIcon.imageMap = iconSettings['imageMap'];
  }

  return customIcon;
}

function tooltipMouseover(sidebar_elem) {
  if (!(this.isInfoWindowOpen) && !(this.isHidden())) {
    this.tooltip.show();
  }
}

function tooltipMouseout(sidebar_elem) {
  this.tooltip.hide();
}

function infoWindowOpen(sidebar_elem) {
  this.isInfoWindowOpen = true;
  desc_mce = $('ws_loc_description_edit_'+this.id);
  if (desc_mce != null && desc_mce != undefined) {
    tinyMCE.execCommand('mceAddControl', false, 'ws_loc_description_edit_'+this.id);
  } else {
    edesc_mce = $('ws_loc_event_description_edit_'+this.id);
    if (edesc_mce != null && edesc_mce != undefined) {
      tinyMCE.execCommand('mceAddControl', false, 'ws_loc_event_description_edit_'+this.id);
    }
  }
}

function infoWindowBeforeClose(sidebar_elem) {
  desc_mce = $('ws_loc_description_edit_'+this.id);
  if (desc_mce != null && desc_mce != undefined) {
    tinyMCE.execCommand('mceRemoveControl', false, 'ws_loc_description_edit_'+this.id);
  } else {
    edesc_mce = $('ws_loc_event_description_edit_'+this.id);
    if (edesc_mce != null && edesc_mce != undefined) {
      tinyMCE.execCommand('mceRemoveControl', false, 'ws_loc_event_description_edit_'+this.id);
    }
  }
}

function infoWindowClose(sidebar_elem) {
  this.isInfoWindowOpen = false;
}

function markerClick() {
  showMarker(this, this.infoHtml);
}

function showLastToDir() {
  showMarker(mapLastMarker, mapLastMarker.toDirHtml);
}

function showLastFromDir() {
  showMarker(mapLastMarker, mapLastMarker.fromDirHtml);
}

function showLastInfo() {
  showMarker(mapLastMarker, mapLastMarker.infoHtml);
}


/**
 * options:
 * id
 * latitude
 * longitude
 * title
 * categoryKeyword
 * infoHtml
 */
function createMarker(options) {
  var point = new google.maps.LatLng(options.latitude, options.longitude);
  var marker = new google.maps.Marker(point, {icon: createCustomIcon(options.categoryKeyword, options.resultIdx)});
  marker.id = options.id; // id to find markers in locationMarkers
  marker.tooltip = new Tooltip(marker, options.title, 4);
  marker.infoHtml = options.infoHtml;

  map.addOverlay(marker);
  map.addOverlay(marker.tooltip);

  if (typeof(options.resultIdx) !== 'undefined') {
    resultMarkers.push(marker);
    setupListeners(options.id, marker, marker.tooltip);
  } else {
    locationMarkers.push(marker);
    setupListeners(options.id, marker, marker.tooltip);
  }

  return marker;
}

function setupListeners(id, marker, tooltip) {
  var map_leftbar_location = $('map_leftbar_location_content_'+id)
  var mclick = google.maps.Event.callbackArgs(marker, markerClick);
  var ttmover = google.maps.Event.callbackArgs(marker, tooltipMouseover, map_leftbar_location);
  var ttmout = google.maps.Event.callbackArgs(marker, tooltipMouseout, map_leftbar_location);

  google.maps.Event.addListener(marker, 'click', mclick);
  google.maps.Event.addListener(marker, 'mouseover', ttmover);
  google.maps.Event.addListener(marker, 'mouseout', ttmout);
  google.maps.Event.addListener(marker, 'infowindowopen', google.maps.Event.callbackArgs(marker, infoWindowOpen, map_leftbar_location));
  google.maps.Event.addListener(marker, 'infowindowbeforeclose', google.maps.Event.callbackArgs(marker, infoWindowBeforeClose, map_leftbar_location));
  google.maps.Event.addListener(marker, 'infowindowclose', google.maps.Event.callbackArgs(marker, infoWindowClose, map_leftbar_location));

  if (map_leftbar_location != null) {
    google.maps.Event.addDomListener(map_leftbar_location, 'click', mclick);
    google.maps.Event.addDomListener(map_leftbar_location, 'mouseover', ttmover);
    google.maps.Event.addDomListener(map_leftbar_location, 'mouseout', ttmout);
  }
}

function latBuffer() { return 0.11; } // in degrees
function lngBuffer() { return 0.065; } // in degrees

// make sure bubble does not interfere with map title
function beyondLatBuffer(mapBounds, markerLatLng) {
  return (mapBounds.getNorthEast().lat() - latBuffer()) > markerLatLng.lat();
}

// make sure bubble does not interfere with map title
function beyondLngBuffer(mapBounds, markerLatLng) {
  return (mapBounds.getSouthWest().lng() + lngBuffer()) < markerLatLng.lng();
}

// some prep work before showing any info on a marker
function showInit(marker) {
  mapLastMarker = marker;
  marker.tooltip.hide();
}

function showMarker(marker, html) {
  showInit(marker);

  var mapBounds = map.getBounds();
  var markerLatLng = marker.getLatLng();

  if (mapBounds.containsLatLng(markerLatLng) && beyondLatBuffer(mapBounds, markerLatLng) && beyondLngBuffer(mapBounds, markerLatLng)) {
    marker.openInfoWindowHtml(html);
  } else {
    marker.openInfoWindowHtml(html);
    map.setCenter(markerLatLng);
  }
}

function showMarkerMsg(marker_id, msg) {
  var marker = findMarker(marker_id);
  showInit(marker);
  marker.openInfoWindowHtml(msg);  
}

function showMarkerTabs(marker_id, tabs_html) {
  var marker = findMarker(marker_id);
  showInit(marker);
  var mapBounds = map.getBounds();
  var markerLatLng = marker.getLatLng();

  if (mapBounds.containsLatLng(markerLatLng) && beyondLatBuffer(mapBounds, markerLatLng) && beyondLngBuffer(mapBounds, markerLatLng)) {
    marker.openInfoWindowTabsHtml(tabs_html);
  } else {
    marker.openInfoWindowTabsHtml(tabs_html);
    map.setCenter(markerLatLng);
  }
}

function findMarker(id) {
  for (var i = 0; i < locationMarkers.length; i++) {
    if (locationMarkers[i].id == id) {
      return locationMarkers[i];
    }
  }
  return null;
}

function removeMarker(id) {
  var marker = findMarker(id);
  if (marker != null) {
    map.removeOverlay(marker);
  }
}

function clearResults() {
  $('map_search_results').innerHTML = '';
  clearResultMarkers();
}

function clearResultMarkers() {
  for (var i = 0; i < resultMarkers.length; i++) {
    map.removeOverlay(resultMarkers[i]);
  }
  resultMarkers = [];
}

function showFirstResult() {
  if (resultMarkers.length > 0) {
    google.maps.Event.trigger(resultMarkers[0], 'click');
  }
}

function hideResults() {
  $('map_search_results_container').style.display = 'none';
  clearResultMarkers();
}

function open_gmap(location_id) {
  var location = $('location_'+location_id);
  var dir_points = location.select('.dir_point');

  var addresses = [];
  for (var i = 0; i < dir_points.length; i++) {
    addresses.push(get_address(dir_points[i], location_id));
  }

  if (addresses[0] && addresses[1]) {
    var gmap_url = 'http://maps.google.com/maps?pw=2&hl=en&saddr='+addresses[0]+'&daddr='+addresses[1];
    window.open(gmap_url, "google_map");
  }
}

function get_address(direction_point, location_id) {
  if (direction_point.hasClassName('dir_location')) {
    return get_address_from_location(direction_point, location_id);
  } else if (direction_point.hasClassName('dir_unknown')) {
    return get_address_from_unknown(direction_point, location_id);
  }
}

function get_address_from_location(direction_point, location_id) {
  var hidden_addresses = direction_point.select('.dir_location_address');
  return hidden_addresses[0].innerHTML;
}

function get_address_from_unknown(direction_point, location_id) {
  var address;

  if (direction_point.select('#dir_unknown_type_'+location_id+'_location')[0].checked) {
    var unknown_selects = direction_point.select('#dir_unknown_select_'+location_id);
    var options = unknown_selects[0].select('option');
    for (var i = 0; i < options.length; i++) {
      if (options[i].selected) {
        address = options[i].value;
      }
    }
    if (address == null || address == '') {
      alert("Please select a location from the list.");
    }
  } else if (direction_point.select('#dir_unknown_type_'+location_id+'_text')[0].checked) {
    address = direction_point.select('#dir_unknown_text_'+location_id)[0].value
    if (address == null || address == '') {
      alert("Please enter an address.");
    }
  }
  
  return address;
}

function refreshCodeTextField() {
  var base_url = $('map_embed_base_url').value;
  var map_url = $('map_embed_map_url').value;
  var url = $('map_embed_url').value;
  var zoom = $('map_embed_zoom').value;
  var iframe_attrs = getIframeAttributes({base_url: base_url, map_url: map_url, url: url, width: 550, height: 400, zoom: zoom});
  $('map_share_embed').value = getEmbedCode(iframe_attrs, getMapUrl(base_url, map_url));
}

function refreshCodeAndPreview() {
  var base_url = $('map_embed_base_url').value;
  var map_url = $('map_embed_map_url').value;
  var url = $('map_embed_url').value;

  // get size
  var width = 550;
  var height = 400;  
  if ($('map_size_small').checked) {
    width = 300;
    height = 300;
    toggleCustomFields('disable');
  } else if ($('map_size_medium').checked) {
    width = 550;
    height = 400;
    toggleCustomFields('disable');
  } else if ($('map_size_large').checked) {
    width = 800;
    height = 600;
    toggleCustomFields('disable');
  } else if ($('map_size_custom').checked) {
    var customWidthField = $('map_size_custom_width');
    if (customWidthField.value != '' && customWidthField.value != null) {
      width = customWidthField.value;
    }

    var customHeightField = $('map_size_custom_height');
    if (customHeightField.value != '' && customHeightField.value != null) {
      height = customHeightField.value;
    }

    toggleCustomFields('enable');
  }

  // get zoom
  var zoomField = $('map_zoom_level');
  var zoom = zoomField.options[zoomField.selectedIndex].value;

  var iframe_attrs = getIframeAttributes({base_url: base_url, map_url: map_url, url: url, width: width, height: height, zoom: zoom});
  var embed_code = getEmbedCode(iframe_attrs, getMapUrl(base_url, map_url));
  $('map_embed_preview_code').value = embed_code
  $('map_embed_preview').innerHTML = embed_code;
}

function toggleCustomFields(action) {
  var widthField = $('map_size_custom_width');
  var heightField = $('map_size_custom_height');
  if (action == 'enable') {
    widthField.readOnly = false;
    heightField.readOnly = false;
  } else if (action == 'disable') {
    widthField.readOnly = true;
    heightField.readOnly = true;
  }
}

function getIframeAttributes(options) {
  return {src: getEmbedUrl(options.base_url, options.url, options.zoom),
          name: getEmbedName(options.map_url),
          width: options.width,
          height: options.height,
          scrolling: 'no',
          frameborder: '0',
          marginwidth: '0',
          marginheight: '0'};
}

function getEmbedUrl(base_url, url, zoom) {
  return base_url + 'map/embed/' + url + '?z='+zoom;
}

function getMapUrl(base_url, map_url) {
  return base_url + 'map/' + map_url;
}

function getEmbedName(map_url) {
  return 'pw_map_'+map_url;
}

function getEmbedCode(attrs, link_url) {
  var embed_code = '<iframe';
  for (var attr in attrs) {
    embed_code += ' ' + attr + '="' + attrs[attr] + '"';
  }
  embed_code += '></iframe>';
  embed_code += '<br/><a href="'+link_url+'" target="_blank" style="text-align:left;text-decoration:underline;font-size:11px;line-height:18px;">View wedding map in full screen</a>';
  
  return embed_code;
}

function resizeMap(preview) {
  var offset = preview ? 26 : 0;
  var height = document.viewport.getHeight() - offset;
  $('map_leftbar').style.height = height+'px';
  $('map_main').style.height = height+'px';
}

function updateLocation(location_id, entry_id) {
  var params = {'id': location_id,
                'wed_site_location[name]': $('ws_loc_name_edit_'+location_id).value,
                'wed_site_location[wed_site_location_category_id]': $('ws_loc_wed_site_location_category_id_'+location_id).value,
                'wed_site_location[website]': $('ws_loc_website_edit_'+location_id).value,
                'wed_site_location[address_line_1]': $('ws_loc_address_line_1_edit_'+location_id).value,
                'wed_site_location[address_line_2]': $('ws_loc_address_line_2_edit_'+location_id).value,
                'wed_site_location[city]': $('ws_loc_city_edit_'+location_id).value,
                'wed_site_location[state]': $('ws_loc_state_edit_'+location_id).value,
                'wed_site_location[postcode]': $('ws_loc_postcode_edit_'+location_id).value,
                'wed_site_location[country]': $('ws_loc_country_edit_'+location_id).value,
                'wed_site_location[phone]': $('ws_loc_phone_edit_'+location_id).value,
                'wed_site_entry[photo_id]': $('wse_photo_id_edit_'+entry_id).value}
  var desc_mce = $('ws_loc_description_edit_'+location_id);
  if (desc_mce != null && desc_mce != undefined) {
    params['wed_site_location[description]'] = desc_mce.value;
  } else {
    var edesc_mce = $('ws_loc_event_description_edit_'+location_id);
    if (edesc_mce != null && edesc_mce != undefined) {
      params['wed_site_location[event_description]'] = edesc_mce.value;
    }
  }

  new Ajax.Request('/map/update_location', {parameters: params});
  showMarkerMsg(location_id, 'Saving to map and website...');
}
