var map, ionfoDot, updMarker, geoc = new GClientGeocoder();
var mProj = new GMercatorProjection(20);

CONFIRM_LEVEL = 18;
ZOOM_INCREMENT = 4;

var ADD = "add.png";
var ADD_TOOLTIP = " add yourself ";
var MAGNIFIER = "magnifier.png";
var MARKER = "default.png";
var SHADOW = "shadow.png"
var STEP1 = '<p><strong>Step 2 (of 3):</strong> Put the marker at your house, <br/>'
          +'or a local square if you want more privacy. <br/>'
          +'You might need to close the bubble first.<br/>'
          +'<input type="button"'
                       +'class="button"'
                       +'value="zoom in for step 3"'
                       +'onclick="map.setZoom(map.getZoom()+ZOOM_INCREMENT)">'
          +'</p>';
var STEP1B = '<p><strong>Step 2 (of 3):</strong> '
          +'Put the marker at your house, <br/>'
          +'or a local square if you want more privacy. <br/>'
          +'You might need to close the bubble first.<br/><br/>'
          +'Please, move your big marker away <br/>'
          +'from the small marker of someone else.'
          +'</p>';

function getInfoBlock (dot) {

   var params;
   if (dot.latlong) {
       params = 'id=' + dot.e
              + '&n=' + escape(dot.name)
              + '&l=' + dot.latlong[0] 
              + ',' + dot.latlong[1]
              ;
   }

   return '<div class="bubble">'
        + ( dot.name
          ? '<strong>' + dot.name.replace( /</g, "&lt;" ) + '</strong><br/>'
          : ''
          )
        + ( dot.e
          ? ( dot.latlong
            ? '<script type="text/javascript" src="getaddress.cgi?' + params + '"></script>'
              + '<a href="getaddr.cgi?' + params + '" onmouseover="if (newref==null || newref==\'\') { target=\'_blank\' } else { this.href=newref}">'
            : '<a href="mailto:'+ (dot.e.toString().replace( /,,/g, "@" ).replace( /,/g, "." )) +'">' // while adding a new entry
            )
            + "<img width='18' height='12' src='e.gif' style='border:0' alt='e-mail'></a> "
          : ''
          )
        + ( dot.site
          ? " <a href='" + dot.site
            + "'><img width='18' height='12' src='site.gif' style='border:0' alt='e-mail'></a> "
          : ''
          )
        + ( dot.location
          ? dot.location.replace( /</g, "&lt;" )
          : ''
          )
        + ( dot.comment
          ? " <br/>" + dot.comment.replace( /</g, "&lt;" )
          : ''
          )
        + '</div>'
        ;
}

function getConfirmBlock (dot) {
   return '<form action="add.cgi" method="post" class="bubbleForm">'
               + '<strong>Step 3:</strong> preview above ok?&nbsp;'
               + '<input type="hidden" name="latlong" value="'   + updMarker.getLatLng() + '"/>'
               + '<input type="hidden" name="comment" value="'   + dot.comment   + '"/>'
               + '<input type="hidden" name="e" value="'         + dot.e         + '"/>'
               + '<input type="hidden" name="location" value="'  + dot.location  + '"/>'
               + '<input type="hidden" name="name" value="'      + dot.name      + '"/>'
               + '<input type="hidden" name="site" value="'      + dot.site      + '"/>'
               + '<input type="submit" value="submit" class="button"/>'
        + '</form>'
        ;
}

function getReportBlock (dot) {
   
   return ''
      +'<a href="mai'+'lto:'+e(['yhgr','jfp','','xs4all','nl'])
      + '?subject=lacemakers%20map%20delete&body='
      + escape ( 'Dear Map assistant of the LaceFairy,\n\n'
               + 'Please delete my entry from the lacemakers map because ....'
               + '\n\n\n__________________\n\n'
               +                   'name: '         + dot.name              + '\n'
               +                   'location: '     + dot.location          + '\n'
               +                   '          '     + updMarker.getLatLng() + '\n'
               + ( dot.comment   ? 'comment: '      + dot.comment           + '\n' : '' )
               + ( dot.site      ? 'site: '         + dot.site              + '\n' : '' )
               ) + '" style="font-size:0.8em">delete</a>'
      + ' - '
      + '<a href="mai'+'lto:'+e(['Lori','','lacefairy','com'])
      + '?subject=lacemakers%20map%20abuse&body='
      + escape ( 'Dear Lori / LaceFairy.\n\n'
               + 'Would you please consider to delete the entry listed below because'
               + '\n\n...\n\n\n__________________\n\n'
               +                   'name: '         + dot.name              + '\n'
               +                   'location: '     + dot.location          + '\n'
               +                   '          '     + updMarker.getLatLng() + '\n'
               + ( dot.comment   ? 'comment: '      + dot.comment           + '\n' : '' )
               + ( dot.site      ? 'site: '         + dot.site              + '\n' : '' )
               ) + '" style="font-size:0.8em">report abuse</a>'
      ;
}

function preview( newDot, destination ) {

   if (  newDot.name     == null || newDot.name     == 0
      || newDot.location == null || newDot.location == 0) {
            alert('please fill in name and location');
            return;
   }
   
   if ( newDot.site     != null &&   newDot.site.match(       /^http:\/\/$/ ) ) newDot.site     = '';
   if ( newDot.site     != ''   && ! newDot.site.match(       /^http:\/\//  ) ) newDot.site     = 'http://'+newDot.site;
   if ( newDot.name     != null && newDot.name.length     != 0) newDot.name     = newDot.name.replace(    new RegExp('"',"g"),"''");
   if ( newDot.location != null && newDot.comment.length  != 0) newDot.location = newDot.location.replace(new RegExp('"',"g"),"''");
   if ( newDot.comment  != null && newDot.comment.length  != 0) newDot.comment  = newDot.comment.replace( new RegExp('"',"g"),"''");

   if ( newDot.site     != null && newDot.site.length     != 0) newDot.site     = newDot.site.replace(    new RegExp('"',"g"),"''");
   if ( newDot.e        != null && newDot.e.length        != 0) newDot.e        = newDot.e.replace(       new RegExp('"',"g"),"''")
                                                                                   .replace('@','..').split('.');
   infoDot = newDot;
   geoc.getLocations( newDot.location, function(result) {
       if (result.Status.code == G_GEO_SUCCESS) {
           var s = '<div class="bigbubble">'+STEP1;
           if ( result.Placemark.length > 1 ) {
               s += "If you didn't mean: <em>" + result.Placemark[0].address + "</em>, maybe try: "; 
               for (var i=1; i<result.Placemark.length; i++) {
                   var c = result.Placemark[i].Point.coordinates;
                   s += (i) + '. '
                     + '<a href="#" onClick="setUpdMarker'
                     + '(' + c[1] + ',' +c[0] +',' + result.Placemark[i].AddressDetails.Accuracy
                     + ');">'
                     + result.Placemark[i].address
                     + '</a> '
                     ;
               }
           }
           s += '</div>';
           var c = result.Placemark[0].Point.coordinates;
           setUpdMarker( c[1], c[0], result.Placemark[0].AddressDetails.Accuracy );
           updMarker.bindInfoWindowHtml( s );
           updMarker.openInfoWindowHtml( s );
       } else {
          alert ("Sorry, couldn't find " + newDot.location + ".");
       }
   });
   return false;
}

function e (s) {
   return s.join(".").replace("..","@");
}

function loadList(listContainerID,filterID) {

   var c = document.getElementById(filterID);
   var filter = (c ? c.value : '');
   var s = '';
   for ( var i=dots.length-1 ; i >= 0 ; i-- ) {
       var dot = dots[i];
       var name = dot.name;
       if ( filter.length > 0 ) {
          if ( null == name.match(new RegExp(filter,"i")) ) continue;
          name = name.replace ( new RegExp(filter,"ig"), '<span class="filter">'+filter+'</span>');
       }
       s += '<p>'
         +"<a href='javascript:showDot(dots["+i+"])'>"+name+'</a> '
         + ( dot.location ? dot.location : '' ) 
         + ( dot.site     ? " <a href='javascript:showDot(dots["+i+"])'><img width='18' height='12' src='site.gif' style='border:0' alt='web site'></a> " : '' )
         + ( dot.e        ? " <a href='javascript:showDot(dots["+i+"])'><img width='18' height='12' src='e.gif' style='border:0' alt='e-mail'></a> " : '' )
         + ( dot.comment  ? " <a href='javascript:showDot(dots["+i+"])'><img width='18' height='12' src='comment.gif' style='border:0' alt='comment'></a> " : '' )
         + '<br/>'
         ;
   }
   document.getElementById(listContainerID).innerHTML = s;
}

function getRadioValue (list) {
    
    for ( var i=0 ; i < list.length ; i++ ) {
       if ( list[i].checked ) {
          return list[i].value;
       }
    }
    return null;
}    

function tinyMarker( markerIcon ) {
    
   var icon = new GIcon( G_DEFAULT_ICON );
   icon.image = markerIcon;
   icon.shadow = SHADOW;
   icon.iconSize = new GSize(12,20);
   icon.shadowSize = new GSize(22,20);
   icon.iconAnchor = new GPoint(6,20);
   icon.infoWindowAnchor = new GPoint(5, 1);
   return icon;
}

/* --------------- */

function setUpdMarker(lat,lng,accuracy) {
    updMarker.setLatLng(  new GLatLng(lat, lng ));
    map.setCenter( updMarker.getLatLng() );
    switch (accuracy) {
        case 0 :                  break; // Unknown location. (Since 2.59)
        case 1 : map.setZoom( 5); break; // Country level accuracy. (Since 2.59)
        case 2 : map.setZoom( 5); break; // Region (state, province, prefecture, etc.) level accuracy. (Since 2.59)
        case 3 : map.setZoom( 8); break; // Sub-region (county, municipality, etc.) level accuracy. (Since 2.59)
        case 4 : map.setZoom( 8); break; // Town (city, village) level accuracy. (Since 2.59)
        case 5 : map.setZoom(12); break; // Post code (zip code) level accuracy. (Since 2.59)
        case 6 : map.setZoom(12); break; // Street level accuracy. (Since 2.59)
        case 7 : map.setZoom(14); break; // Intersection level accuracy. (Since 2.59)
        case 8 : map.setZoom(14); break; // Address level accuracy. (Since 2.59)
    }
}

function clearForm() {
   updMarker.setLatLng(new GLatLng(260,0));
   map.closeInfoWindow();
}

function createUpdMarker() {
    var icon = new GIcon(G_DEFAULT_ICON);
    icon.image = ADD;
    updMarker = new GMarker( new GLatLng(260,0), { icon: icon, title:ADD_TOOLTIP, draggable: true } );
    updMarker.bindInfoWindowHtml( STEP1 );
    GEvent.addListener(updMarker, "dragend", function() {
       if ( (map.getZoom() + ZOOM_INCREMENT) < CONFIRM_LEVEL ) {
          map.setZoom( map.getZoom() + ZOOM_INCREMENT );
       }
       updInfoWindow();
    });
    return updMarker;
}

function showDot(dot) {
   infoDot = null;
   map.openInfoWindowHtml( dot.m.getLatLng(), dot.s );
   if ( map.getZoom() < dot.minZoom ) {
      map.setZoom( dot.minZoom );
   }
}
var mProj = new GMercatorProjection(20);

function dotDistance() {
    var value = 50;
    var gpi = mProj.fromLatLngToPixel(updMarker.getLatLng(),CONFIRM_LEVEL);
    for ( var i=0 ; i < dots.length ; i++ ) {
       ll = new GLatLng( dots[i].latlong[0], dots[i].latlong[1] );
       var gpj = mProj.fromLatLngToPixel(ll,CONFIRM_LEVEL);
       var dx = Math.abs(gpi.x - gpj.x);
       var dy = Math.abs(gpi.y - gpj.y);
       var dxy = Math.max(dx,dy);
       if ( dxy >= 0 && dxy < value ) value = dxy;
    }
	return value;
}

function updInfoWindow() {
    
   if ( infoDot != null ) {
      if ( (map.getZoom() + ZOOM_INCREMENT) < CONFIRM_LEVEL ) {
         updMarker.openInfoWindowHtml( STEP1 );
      } else if ( dotDistance() < 5 ) {
         updMarker.openInfoWindowHtml( STEP1B );
      } else {
         updMarker.openInfoWindowHtml( getInfoBlock( infoDot ) + getConfirmBlock( infoDot ) );
      }
   }
}

function setTransRequest(x) {
  x.href += "yhgr"+"."+"jfp"
  +"@"
  +"xs4all"+"."+"nl"
  +"?subject=%5Blacemakers%20map%5D&body="
  +escape ("for the language __\n")
  +escape ("the translaction of 'lacemakers of the world' is \n__\n")
  +escape ("and the translaction of 'Have a look at the details or add yourself' is \n__\n")
}

// areas hidding a cluster of markers

var zoomAreas = [];

function zoomingArea( dot ) {

   // oops cx is vert, cy hor
   var cx = dot.latlong[0];
   var cy = dot.latlong[1];
   var level = dot.maxZoom;
   var x = 20 * Math.cos( (cx*Math.PI)/180);
   var y = 40;
   for ( var i=level-2 ; i>0 ; i--) {
      x = x/2;
      y = y/2;
   }
   var points = [ new GLatLng (-x+cx,-y+cy), new GLatLng (-x+cx,y+cy), new GLatLng (x+cx,y+cy), new GLatLng (x+cx,-y+cy), new GLatLng (-x+cx,-y+cy) ];
   var area = new GPolygon( points, "#777", 1, 0.8, "#777", 0.1 ); 
   zoomAreas.push( { bounds : area.getBounds(), level : level } );
   return area;
}

function minZoom( latLng ) {

   var zoom = 0;
   for ( i=0 ; i < zoomAreas.length ; i++ ) {
       var z = zoomAreas[i].level;
       if ( zoom <= z && zoomAreas[i].bounds.containsLatLng(latLng) ) {
           zoom = z+1;
       }
   }
   return zoom;
}

function zoomIn (zoomingMarker) {
     if ( map.getZoom() < zoomingMarker.value ) {
          map.setZoom( zoomingMarker.value );
     }
     map.setCenter(zoomingMarker.getLatLng());
}

function loadMap( mapContainerID, countContainerID ) {
   
   if ( ! GBrowserIsCompatible() ) return; 
   var c = document.getElementById(countContainerID); 
   if ( c ) c.innerHTML = dots.length;
   c = document.getElementById(mapContainerID); 
   if ( ! c ) {
      alert('The page doesn\'t have a HTML block element with id '+mapContainerID+' to contain the map');
      return;
   }
   c.innerHtml = 'loading';
   
   map = new GMap2(c);
   map.addControl(new GLargeMapControl());
   map.addControl(new GMapTypeControl());
   map.addControl(new GScaleControl());
   map.setCenter(new GLatLng(30,0), 1);
   map.enableScrollWheelZoom();
   
   mgr = new GMarkerManager( map );
   map.addOverlay( createUpdMarker() );
   GEvent.addListener( map, "zoomend", function() {
       if ( updMarker.getLatLng().lat() < 90 )
         updInfoWindow();
   });

   var icon = tinyMarker( MAGNIFIER );
   var marker;
   for ( var i=0 ; i < clusters.length ; i++ ) {
       var ll = new GLatLng( clusters[i].latlong[0], clusters[i].latlong[1] );
       marker = new GMarker( ll, { icon:icon, title:clusters[i].location });
       marker.value = clusters[i].maxZoom + 1;  // level for zoomIn()
       GEvent.addListener( marker, "click", function() {
           zoomIn (this);
       });
       mgr.addMarker( marker, clusters[i].minZoom, clusters[i].maxZoom );
       map.addOverlay( zoomingArea( clusters[i] ) );
   }
   icon = tinyMarker( MARKER );
   for ( var i=0 ; i<dots.length ; i++ ) {
       var s = getInfoBlock( dots[i] ) + getReportBlock( dots[i] );
       var ll = new GLatLng( dots[i].latlong[0], dots[i].latlong[1] );
       marker = new GMarker( ll, { icon:icon, title:dots[i].name });
       marker.bindInfoWindowHtml( s );
       marker.value = 0;
       mgr.addMarker( marker, dots[i].minZoom = minZoom( ll ) );
       dots[i].m = marker;
       dots[i].s = s;
   }
}

