///////////////////////////////////////
/* sokurenko map control, slightly modified */

var POINT_ZOOM_LEVEL = 8
var GROUP_ZOOM_LEVEL = 6
var DEFAULT_ZOOM_LEVEL = 7
var SEARCH_MAX_ZOOM_LEVEL = 14
var DEFAULT_CENTER_LAT = 53.45
var DEFAULT_CENTER_LNG = -8
function Map(container, options) {
  var map, markerManager, pointMarkers, groupMarkers
  initialize()
  return map
  
  function initialize() {
    options = options || {}
    container = $(container)

    map = new GMap2(container)
    map.setCenter(new GLatLng(DEFAULT_CENTER_LAT, DEFAULT_CENTER_LNG), DEFAULT_ZOOM_LEVEL)
    map.enableScrollWheelZoom()
    map.disableDoubleClickZoom()
    map.addControl(new GSmallMapControl())
   
    markerManager = new MarkerManager(map)
        
    if (options.points)
    {
    	loadGroups()
    	loadPoints()
    }
    
    markerManager.refresh()
    
    GEvent.addListener(map, 'click', onMapClick)
    Event.observe(window, 'unload', GUnload)
  }
  
  function loadPoints() {
    createPointMarkers()
    markerManager.addMarkers(pointMarkers, map.groups ? POINT_ZOOM_LEVEL : GROUP_ZOOM_LEVEL)
  }
  
  function loadGroups() {
    createGroupMarkers()
    markerManager.addMarkers(groupMarkers, GROUP_ZOOM_LEVEL)
  }
  
  function createPointMarkers() {
    pointMarkers = options.points.map(PointMarker.create)
  }
    
  function createGroupMarkers() {
  	map.groups=new Array()
  	var groups=new Array()
  	var group_names=new Array() // this was required cause I couldn't use the js associative arrays properly.  How do you iterate through one?! 
  	options.points.each( function(point){
    	var key = point[options.group_on]
  		if(groups[key] == null) {
  			group_names[group_names.length]=key
  			groups[key] = {top:null,right:null,bottom:null,left:null,latitude:null,longitude:null,amount:0,desc:null,name:key}
    	}
    	groups[key].amount++;
    	
    	// top
    	if(groups[key].top == null || point.latitude > groups[key].top)
    		groups[key].top = point.latitude
    	// right
    	if( groups[key].right == null || point.longitude > groups[key].right )
    		groups[key].right = point.longitude
    	// bottom
    	if( groups[key].bottom == null || point.latitude < groups[key].bottom)
    		groups[key].bottom = point.latitude
    	// left
    	if( groups[key].left == null || point.longitude < groups[key].left)
    		groups[key].left = point.longitude
    })
    var cnt=0
    group_names.each(function(group_name){
    	groups[group_name].latitude = ((groups[group_name].top - groups[group_name].bottom)/2)+groups[group_name].bottom
    	groups[group_name].longitude = ((groups[group_name].left - groups[group_name].right)/2)+groups[group_name].right
    	groups[group_name].desc = groups[group_name].name+": "+groups[group_name].amount
    	map.groups[cnt++] = groups[group_name]
    })
    
    groupMarkers = map.groups.map(GroupMarker.create.curry(map))
    map.reset = function() {
    	this.setCenter(new GLatLng(DEFAULT_CENTER_LAT, DEFAULT_CENTER_LNG), DEFAULT_ZOOM_LEVEL)
    }
  }
  
  function onMapClick(overlay, point) {
  	if (overlay instanceof GMarker)
      overlay.onClick()
    else if( point != null && console != null)
    	console.log("latitude: "+point.y+", longitude: "+point.x)
  }
}

///////////////////////////////////////

function PointMarker(point) {
  GMarker.call(this,
    new GLatLng(point.latitude, point.longitude),
    {title: point.name+", "+point.county, icon: PointMarker.getIcon(point.icon)}
  )
  this.mark = point
}

PointMarker.prototype = Object.extend(new GMarker(new GLatLng(0, 0)), {
  showTooltip: function() {
	  var tooltip = new Element('div', {style: "width: 180px"}).
			insert(new Element('h5', {style: "font-weight: bold"}).update(this.mark.name)).
			insert(new Element('span', {style: "font-style: italic"}).insert(this.mark.type)).
			insert(new Element('p').insert(this.mark.desc))
		this.openInfoWindow(tooltip)
  },
  onClick: function() {
    this.showTooltip()
  }
})

Object.extend(PointMarker, {
  create: function(point) {
    return new PointMarker(point)
  },
  getIcon: function(icon_type) {
  	// if (this.icon) return this.icon
    // this.icon = new GIcon(G_DEFAULT_ICON)
		this.icon = IconLib[icon_type]
    /*if(type == "Topaz") {
  	  this.icon.image = "/images/gmap-topaz-icon.png"
  	  this.icon.shadow = "/images/gmap-topaz-shadow.png"
  	  this.icon.iconSize = new GSize(29, 30)
  	  this.icon.shadowSize = new GSize(32, 20)
    } else {
	    this.icon.image = "/images/gmap-point-icon.png"
	    this.icon = IconLib["Default"]
    }*/
	  return this.icon
  }  
})


function GroupMarker(map, group) {
  GMarker.call(this,
    new GLatLng(group.latitude, group.longitude),
    {title: group.desc, icon: GroupMarker.getIcon()}
  )
  GEvent.bind(this, 'dblclick', this, this.zoom)
  this.group = group
  this.map = map
}

GroupMarker.prototype = Object.extend(new GMarker(new GLatLng(0, 0)), {
  showTooltip: function() {
    var tooltip = new Element('div', {style: "width: 180px; height: 20px"}).
      insert(new Element('h5', {style: "font-weight: bold"}).
        insert("#{name}: (#{count})".interpolate(this.group))
      )    
    
    this.openInfoWindow(tooltip)
  },
  zoom: function() {
  	if(this.map.getZoom() != DEFAULT_ZOOM_LEVEL) {
			this.map.setCenter(new GLatLng(DEFAULT_CENTER_LAT, DEFAULT_CENTER_LNG), DEFAULT_ZOOM_LEVEL)
			return
		}
  	var newBounds = new GLatLngBounds( new GLatLng(this.group.bottom, this.group.left), new GLatLng(this.group.top, this.group.right))
		var newZoomLevel = this.map.getBoundsZoomLevel(newBounds)
		newZoomLevel = Math.min(newZoomLevel, SEARCH_MAX_ZOOM_LEVEL)
		this.map.setCenter(newBounds.getCenter(), newZoomLevel)
    /*
  	var newZoomLevel = this.map.getZoom() < POINT_ZOOM_LEVEL ? POINT_ZOOM_LEVEL : DEFAULT_ZOOM_LEVEL
    this.map.setCenter(this.getLatLng(), newZoomLevel)
    */
  },
  onClick: function() { }
})

Object.extend(GroupMarker, {
  create: function(map, group) {
    return new GroupMarker(map, group)
  },
  getIcon: function() {
    if (this.icon) return this.icon
    this.icon = new GIcon(G_DEFAULT_ICON)
    this.icon.image = "/images/gmap-group-icon.png"
    return this.icon
  }  
})

function CustomIcon(image, shadow, imageSize, shadowSize)
{
	var icon = new GIcon(G_DEFAULT_ICON);
	if( image != null ) icon.image = image;
	if( shadow != null ) icon.shadow = shadow;
	if( imageSize != null ) icon.iconSize = imageSize;
	if( shadowSize != null ) icon.shadowSize = shadowSize;
	return icon;
}

var IconLib = {
// 	"Group": CustomIcon("/images/gmap-group-icon.png"),
	"Default": CustomIcon("/images/gmap-point-icon.png"),
	"Topaz": CustomIcon("/images/gmap-topaz-icon.png", "/images/gmap-topaz-shadow.png", new GSize(29, 30), new GSize(32, 20)),
	"Coffee": CustomIcon("/images/gmap-coffee-icon.png", "/images/gmap-topaz-shadow.png", new GSize(30, 30), new GSize(32, 30)),
	"Truck": CustomIcon("/images/gmap-truck-icon.png", "/images/gmap-topaz-shadow.png", new GSize(47, 21), new GSize(32, 30))
};

///////////////////////////////////////
