/* $Id: function.map.js,v 1.18 2007/12/17 17:12:41 oliver Exp $ */

/**
 * Map related functions
 */

// variables
var map;
var centerMarker;
var propertyPin;
var businessPin;

/**
 * Sets current map's center and zoomlevel to fit bounding box
 *
 * sw, ne: GLatLng
 */
function centerAndZoomBB(sw,ne) {
  var bounds = new GLatLngBounds(sw,ne);
  var zoomLevel = map.getBoundsZoomLevel(bounds);
  console.info('centerAndZoomBB',sw,ne,bounds,zoomLevel);
  map.setCenter(bounds.getCenter(),zoomLevel);
}

/**
 * Parses a string '(float,float)' (as returned by Postgres POINTs) and
 * returns it as {x: float, y: float}
 */
function parsePoint(point) {
  var result = {};
  console.info('parsePoint',point);
  if(typeof point != 'undefined' && point.match(/^\((-*\d+\.*\d*), *(-*\d+\.*\d*)\)$/)) {
    var coords = point.match(/^\((-*\d+\.*\d*), *(-*\d+\.*\d*)\)$/);
    result.x = parseFloat(coords[1]);
    result.y = parseFloat(coords[2]);
    console.info('parsePoint whohoo',result);
  } else {
    console.error('parsePoint did not match',point);
  }
  return result;
}

/**
 * 
 */
function loadCountry(countryCode, url, regionsOnly) {
  console.info('loadCountry',countryCode);
  map.clearOverlays();
  if($('regions')) $('regions').options.length=0;
  if(typeof url == 'undefined') url = 'index.php?mode=ajax&sub=search&action=country&country_code=';
  var jSonRequest = new JSON.Request(url+countryCode, null, {
    onCompleteCallback: function(obj) {
      console.info('onCompleteCallback JSON',obj);
      if(!regionsOnly) {
        var sw = new GLatLng(parsePoint(obj.bb_sw).x,parsePoint(obj.bb_sw).y);
        var ne = new GLatLng(parsePoint(obj.bb_ne).x,parsePoint(obj.bb_ne).y);
        console.info('onCompleteCallback coords ',sw,ne);
        centerAndZoomBB(sw,ne);
      }

      if($('regions')) $('regions').options[$('regions').options.length] = new Option((typeof regionDefaultOption == 'undefined' ? 'All regions' : regionDefaultOption),'');
      $H(obj.regions).values().each(function(region) {
        console.info(region);
        if($('regions')) $('regions').options[$('regions').options.length] = new Option(region.title,region.region_id);
      });
      if(!regionsOnly) $('status_message').textContent = 'Search for properties in '+obj.name;
    }
  });
  console.info('jSonRequest',jSonRequest);
}

/**
 *
 */
JSON = {
  Request: function(url, params, options) {
    console.info('JASON.Request',url,params,options);
    this.request = new Ajax.Request(url, {
      method: 'get',
      parameters: params,
      onComplete: function(response) {
        console.info('JSON.Request -> Ajax.Request.complete',this,response);
        console.info('JSON.Request -> Ajax.Request.completeFn',this.onCompleteCallback);
        var data = response.responseText.evalJSON();
        console.info('JSON.Request -> Ajax.Request.JSON',data);
        this.onCompleteCallback(data);
      }.bind(options)
    });
  }
};

var Search = Class.create();
Search.prototype = {
  initialize: function(url, frm) {
    console.info('Search object created');
    this.url  = url;
    this.frm  = frm;
  },

  find: function() {
    map.clearOverlays();
    $('status_message').textContent = 'Searching...';
    var jSonRequest = new JSON.Request(this.url+'bb', this.frm.serialize(true), {
      onCompleteCallback: function(obj) {
        console.info('onCompleteCallback JSON',obj);
        if(obj.success == 'true') {
          var ne = parsePoint(obj.bbox.bb_ne);
          var sw = parsePoint(obj.bbox.bb_sw);
          if($('country_code')) {
            if($('country_code').value != obj.bbox.country_code) {
              $('country_code').value = obj.bbox.country_code;
              loadCountry(obj.bbox.country_code, undefined, true);
            }
          }
          centerAndZoomBB(new GLatLng(sw.x,sw.y), new GLatLng(ne.x,ne.y));
          mMap({'ne': ne, 'sw': sw});
        } else {
          $('status_message').textContent = 'Nothing found';
        }
      }
    });
  }
};

function resetSearchForm() {
  $('search').reset();
  loadCountry($('country_code').value);
}

function createMarker(point, id, isBusiness) {
  var marker = new GMarker(point,(isBusiness == true ? businessPin : propertyPin));
  var url;
  if(isBusiness == true) url = 'index.php?mode=ajax&sub=search&action=business&business_id=';
  else                   url = propertySearch.url+'property&property_id=';
    
  GEvent.addListener(marker, "click", function() {
    marker.openInfoWindowHtml('<div id="propPrev'+id+'">Loading '+(isBusiness == true ? 'business' : 'property')+'<br><img src="templates/site/img/big_loading.gif"></div>');
    new Ajax.Request(url+id, {
      method: 'get',
      onComplete: function(result) {        
        //console.info($('propPrev'+id).innerHTML);
        //map.updateInfoWindow($('propPrev'+id).innerHTML);
        //this.closeInfoWindow();
        this.openInfoWindowHtml(result.responseText);
      }.bind(marker)
    });
    //console.info($('propPrev'+id));
  });
  return marker;
}

function putProperty(coords,property_id) {
  var point = new GLatLng(coords.x,coords.y);
  map.addOverlay(createMarker(point, property_id));
}

function putBusiness(coords,business_id) {
  var point = new GLatLng(coords.x,coords.y);
  map.addOverlay(createMarker(point, business_id, true));
}

function mMap(params) {
  var requestParams = propertySearch.frm.serialize(true);
  requestParams.x1 = params.ne.x;
  requestParams.y1 = params.ne.y;
  requestParams.x2 = params.sw.x;
  requestParams.y2 = params.sw.y;
  console.info('Property coord request',requestParams);
  var jSonRequest = new JSON.Request(propertySearch.url+'properties', requestParams, {
    onCompleteCallback: function(obj) {
      console.info('onCompleteCallback JSON',obj);
      console.info('properties',$H(obj.properties));
      $H(obj.properties).values().each(function(property) {
        console.info(property);
        putProperty(parsePoint(property.coords),property.property_id);
      });
      $('status_message').textContent = $H(obj.properties).values().length+' properties found';
    }
  });
}

/**
 * load map in specified div
 */
function loadMap(mapDiv){
  map = new GMap2($(mapDiv));
  map.addControl(new GLargeMapControl());
  map.addControl(new GMapTypeControl());
  map.addControl(new GScaleControl());
  
  propertyPin = new GIcon();
  propertyPin.image = img_dir+'pin.png';
  propertyPin.iconSize = new GSize(20, 33);
  propertyPin.iconAnchor = new GPoint(2, 32);
  propertyPin.infoWindowAnchor = new GPoint(5, 1);

  businessPin = new GIcon();
  businessPin.image = img_dir+'business_pin.png';
  businessPin.iconSize = new GSize(20, 33);
  businessPin.iconAnchor = new GPoint(2, 32);
  businessPin.infoWindowAnchor = new GPoint(5, 1);
  
  window.unload = function(){
    if(GUnload)GUnload();
  }
}

/**
 * place a marker at the specified coords and the center the map on it
 */
 
function placeCenterMarker(coords, zoom) {
  if (centerMarker != null) centerMarker.remove();
  if (zoom == null) zoom = 15;
  map.setCenter(coords, zoom);
  centerMarker = new GMarker(coords,propertyPin);
  map.addOverlay(centerMarker);
}
