/***

MochiKit.Maps__Cgoogle 0.2

(c) 2007 Schmap ltd.  All rights Reserved.

***/
var isIE6 = b_version.search(/MSIE 6/i) != -1;

if (typeof(dojo) != 'undefined') {
    dojo.provide('MochiKit.Maps__Cgoogle');
}

if (typeof(MochiKit) == 'undefined') {
    MochiKit = {};
}

if (typeof(MochiKit.Maps__Cgoogle) == 'undefined') {
    MochiKit.Maps__Cgoogle = {};
}

if (typeof(MochiKit.Maps) == 'undefined') {
    // provide default implementation
    MochiKit.Maps = MochiKit.Maps__Cgoogle;
}

MochiKit.Maps__Cgoogle.NAME = "MochiKit.Maps__Cgoogle";
MochiKit.Maps__Cgoogle.VERSION = "0.2";
MochiKit.Maps__Cgoogle.__repr__ = function () {
    return "[" + this.NAME + " " + this.VERSION + "]";
};
MochiKit.Maps__Cgoogle.toString = function () {
    return this.__repr__();
};

MochiKit.Maps__Cgoogle.Map = function(element, options) {
    this.parentElement = $(element);
    this.element = DIV({id: 'MochiKit.Maps__Cgoogle.Map.' +
                            MochiKit.Maps__Cgoogle.Map._id_pool + '.container',
                        style: 'position: absolute; height: 100%; width:100%; top: 0px; bottom: 0px; right: 0px; left: 0px;' +
                               'overflow: hidden; margin: 0px; padding: 0px; ' +
                               'background: white;'});
    this.imgElement = IMG({id: 'MochiKit.Maps__Cgoogle.Map.' +
                               MochiKit.Maps__Cgoogle.Map._id_pool + '.img',
                           style: 'z-index: 1; position: absolute; ' +
                                  'top: 0px; left: 0px;'});
    this.markersElement = DIV({id: 'MochiKit.Maps__Cgoogle.Map.' +
                                   (MochiKit.Maps__Cgoogle.Map._id_pool++) +
                                   '.markers',
                               style: 'z-index: 2; height: 100%; ' +
                                      'margin: 0px; padding: 0px;' +
                                      'position: relative'});
    this.parentElement.appendChild(this.element);
    appendChildNodes(this.element, this.markersElement, this.imgElement);
    this.provider = 'c';
    this.bounds = this.imgBounds = null;
    this.images = [];
    this._items = [];
	this.google_api_key = google_api_key;

};

 

MochiKit.Maps__Cgoogle.Map.prototype.__repr__ = function () {
    return "[Map at " + this.element.id + "]";
};

MochiKit.Maps__Cgoogle.Map._id_pool = 0;
MochiKit.Maps__Cgoogle.Map.datafiles = {};
MochiKit.Maps__Cgoogle.Map.newDataArrived = true;
MochiKit.Maps__Cgoogle.Map.prototype.setBackground = function(style) {
    setStyle(this.element, {background: style});
};
 
 
MochiKit.Maps__Cgoogle.Map.prototype.fixSize = function(noupdate) {

};

MochiKit.Maps__Cgoogle.Map.prototype.actualBoundsFromIdealBounds = function (bounds)
{
    return (this.imgBounds);
}

MochiKit.Maps__Cgoogle.Map.prototype.setDisplay = function(point, zoom) {
	var d = getElementDimensions(this.element);
	x = point.latitude;
	y = point.longitude;
	this.imgElement.src = "http://maps.google.com/staticmap?center="+x+","+y+"&zoom="+zoom+"&size="+d.w+"x"+d.h+"&key="+this.google_api_key;
    this.__display__();
    signal(this, 'moveend');
};
 

MochiKit.Maps__Cgoogle.Map.prototype.zoomToBounds = function(bounds) {	
	var d = getElementDimensions(this.element);
	var centergeo = bounds.getCenter();
	x = centergeo.latitude;
	y = centergeo.longitude;
	var ppl = d.w/(bounds.east-bounds.west);
	//var zoom = Math.round(Math.log(ppl/(256/360)) / Math.log(2));
	this.GMercatorProjection = new MochiKit.Maps__Cgoogle.GMercatorProjection(17);
	this.imgElementSize = new MochiKit.Maps__Cgoogle.ElementSize(d.w,d.h);
	var zoom = this.GMercatorProjection.getBoundsZoomLevel(bounds,this.imgElementSize);
	this.imgElement.src = "http://maps.google.com/staticmap?center="+x+","+y+"&zoom="+zoom+"&size="+d.w+"x"+d.h+"&key="+this.google_api_key;
	var mapobj = this; 
	


	this.zoomFactors = {x: this.GMercatorProjection.pixelsPerLonDegree[zoom],
				         y: this.GMercatorProjection.pixelsPerLonRadian[zoom]};
		var halfLng = d.w/this.zoomFactors.x/2;
	var halfLat = d.h/this.zoomFactors.y/2*180/Math.PI;
	
	this.zoom = zoom;
	this.imgBounds =bounds; 
	this.imgBounds.west = centergeo.longitude - halfLng;
	this.imgBounds.east = centergeo.longitude + halfLng;
	this.imgBounds.north = centergeo.latitude + halfLat;
	this.imgBounds.south = centergeo.latitude - halfLat;
	this.imgElmentOpoint = this.GMercatorProjection.fromLatLngToPixel(centergeo,zoom);	
	this.imgElement.onload = function(){
			mapobj.hideAll(false);
		};
		// if(this.imgElement.complete){

		// this.imgElement.onload = null;this.hideAll(false);
		// }
};

MochiKit.Maps__Cgoogle.Map.prototype.getBounds = function() {
    return clone(this.imgBounds);
};

MochiKit.Maps__Cgoogle.Map.prototype.setMapType = function(maptype) {
};

MochiKit.Maps__Cgoogle.Map.prototype.convert = function(item, _with_data) {
		var c = MochiKit.Style.getElementPosition(this.imgElement);
		var ec = MochiKit.Style.getElementPosition(this.element);
		var i = _with_data || this;
		if(item instanceof MochiKit.Maps__Cgoogle.Point) { 
			c.x += Math.round((item.longitude - this.imgBounds.west) * this.zoomFactors.x);
			g = this.GMercatorProjection.fromLatLngToPixel(item,this.zoom);
			c.y += (g.y-this.imgElmentOpoint.y+this.imgElementSize.height/2);
		return c;
		} else {
			logWarning('Map.convert: unknown argument');
		return undefined;
		}
};

MochiKit.Maps__Cgoogle.Map.prototype.addItem = function(item) {
    if(item.__added__ !== undefined)
        item.__added__(this);
    else
        item.map = this;
    if(item.__display__ !== undefined)
        this._items.push(item);
};

MochiKit.Maps__Cgoogle.Map.prototype.hideMarkers = function() {
    this.markersElement.style.zIndex = 0;	
	this.markersElement.style.visibility = "hidden";
};

MochiKit.Maps__Cgoogle.Map.prototype.__display__ = function() {
    if(this.markersHidden) return;
    map(function(item) {item.__display__();}, this._items);
    this.markersElement.style.zIndex = 2;
	this.markersElement.style.visibility = "visible";
};

MochiKit.Maps__Cgoogle.Map.prototype.hideAll = function(hide) {
    if(hide) {
        this.markersHidden = true;
        this.hideMarkers();
    } else {
        this.markersHidden = false;
        this.__display__();
    }
};
 
MochiKit.Maps__Cgoogle.Point = function(lat, lon) {
    this.latitude = Number(lat);
    this.longitude = Number(lon);
};

MochiKit.Maps__Cgoogle.Point.prototype.lat=function(){
   return this.latitude
};

MochiKit.Maps__Cgoogle.Point.prototype.lng=function(){
   return this.longitude
};

MochiKit.Maps__Cgoogle.Point.prototype.__repr__ = function () {
    return "[Map Point at " + this.latitude + ',' + this.longitude + "]";
};

MochiKit.Maps__Cgoogle.Bounds = function(south, west, north, east) {
    if(south > north) {
        var tmp = south;
        south = north;
        north = tmp;
    }
    if(west > east) {
        var tmp = west;
        west = east;
        east = tmp;
    }
    this.west = west;
    this.south = south;
    this.east = east;
    this.north = north;
	this.southWest = new MochiKit.Maps__Cgoogle.GLatLng(south,west);
	this.northEast = new MochiKit.Maps__Cgoogle.GLatLng(north,east);
	this.northWest = new MochiKit.Maps__Cgoogle.GLatLng(north,west);
};

MochiKit.Maps__Cgoogle.Bounds.fromGeoRSS = function(georss) {
    // extract from xml node
    if(georss.textContent && georss.nodeName &&
       georss.nodeName.match(/box$/))
        georss = georss.textContent;
    else if(georss.object)
        georss = georss.object;
    var box = map(Number, georss.split(/ /));
    
    return new MochiKit.Maps__Cgoogle.Bounds(box[0], box[1], box[2], box[3]);
};

MochiKit.Maps__Cgoogle.Bounds.prototype.__repr__ = function () {
    return "[Map bounds: (" + this.south + ", " + this.east +
                   ") to (" + this.north + ", " + this.west + ")]";
};

MochiKit.Maps__Cgoogle.Bounds.prototype.getCenter = function() {
    return new MochiKit.Maps__Cgoogle.Point((this.north + this.south) / 2,
                                   (this.west + this.east) / 2);
};

MochiKit.Maps__Cgoogle.Bounds.prototype.contains = function(pb) {
    if(pb instanceof MochiKit.Maps__Cgoogle.Bounds) {
        return (pb.west >= this.west) && (pb.east <= this.east) &&
               (pb.south >= this.south) && (pb.north <= this.north);
    } else if(pb instanceof MochiKit.Maps__Cgoogle.Point) {
        return (pb.longitude >= this.west) && (pb.longitude <= this.east) &&
               (pb.latitude >= this.south) && (pb.latitude <= this.north);
    }
};

MochiKit.Maps__Cgoogle.Bounds.prototype.equals = function(b) {
    return (b.west == this.west) && (b.east == this.east) &&
           (b.south == this.south) && (b.north == this.north);
};

MochiKit.Maps__Cgoogle.Bounds.prototype.getWidth = function() {
    return Math.abs(this.east - this.west);
};

MochiKit.Maps__Cgoogle.Bounds.prototype.getHeight = function() {
    return Math.abs(this.north - this.south);
};

MochiKit.Maps__Cgoogle.Bounds.prototype.northwest = function() {
    return new MochiKit.Maps__Cgoogle.GLatLng(this.north,this.west);;
};
MochiKit.Maps__Cgoogle.Icon = function(url, dimensions, anchor) {
    this.image = url;
    this.dimensions = dimensions;
    this.anchor = anchor;
};

MochiKit.Maps__Cgoogle.Icon.prototype.create = function() {
    e = IMG({src:this.image, suppress:"TRUE"});
    //e.src = this.image;
    //e.width = this.dimensions.w; 
    //e.height = this.dimensions.h;
    e.style.position = 'absolute';
    e.style.zIndex = '23';
    return e;
};

MochiKit.Maps__Cgoogle.Icon.prototype.IEcreate = function() {
    e = MochiKit.DOM.DIV(null);
    MochiKit.Style.setElementDimensions(e, this.dimensions);
    MochiKit.Style.setStyle(e, {
            display: 'block',
            position: 'absolute',
            filter: "progid:DXImageTransform.Microsoft.AlphaImageLoader(" +
                "src='" + this.image + "',sizingMethod='scale')",
            'z-index': '23'});
    return e;
};

// yes, browser detection is evil, but this is the only browser stupid enough
// to be unable to display alpha PNGs, and I don't want to single out IE7
var _MSIE = navigator.userAgent.indexOf("MSIE");
if((_MSIE != -1) && (parseFloat(navigator.userAgent.substring(_MSIE+5))) < 7) {
    MochiKit.Maps__Cgoogle.Icon.prototype.create =
        MochiKit.Maps__Cgoogle.Icon.prototype.IEcreate;    
} else {
    delete MochiKit.Maps__Cgoogle.Icon.prototype.IEcreate;
}
delete _MSIE;

MochiKit.Maps__Cgoogle.Marker = function(point, icon) {
    this.point = point;
    this.icon = icon;
    this.map = null;
    this.element = this.icon.create();
    this.hidden = false;
};

MochiKit.Maps__Cgoogle.Marker._nextId = 1;

MochiKit.Maps__Cgoogle.Marker.prototype.__repr__ = function () {
    return "[Marker at " + repr(this.point) + "]";
};

MochiKit.Maps__Cgoogle.Marker.prototype.__added__ = function (map) {
    this.map = map;
    this.map.markersElement.appendChild(this.element); 
    this.__display__();
};

MochiKit.Maps__Cgoogle.Marker.prototype.__display__ = function () {
    if(!this.map) return;
    if(!this.hidden)
        this.element.style.display = 'block'; 
    p = getElementPosition(this.map.convert(this.point), this.map.markersElement);
    p.x -= this.icon.anchor.x; p.y -= this.icon.anchor.y;
    setElementPosition(this.element, p);
};

MochiKit.Maps__Cgoogle.Marker.prototype.reposition = function(point) {
    this.point = point;
    this.__display__();
};

MochiKit.Maps__Cgoogle.Marker.prototype.setImage = function(url) {
    this.element.src = url;
    this.__display__();
};

MochiKit.Maps__Cgoogle.Marker.prototype.show = function() {
    this.element.style.display = 'block';
    this.hidden = false;
};

MochiKit.Maps__Cgoogle.Marker.prototype.hide = function() {
    this.element.style.display = 'none';
    this.hidden = true;
};

MochiKit.Maps__Cgoogle.Marker.prototype.__connect__ =
    function(ident, signal, objOrFunc, funcOrStr) {
    if(funcOrStr === undefined) {
        funcOrStr = objOrFunc;
        objOrFunc = this;
    }
    if(signal == 'click') {
        // 'onclick' doesn't work for some reason
        signal = 'mousedown';
    }
    disconnect(ident);
    id2 = connect(this.element, 'on'+signal, objOrFunc, funcOrStr);
    if(ident.connected !== undefined) {
        // newer MochiKit.Signal.Ident
        update(ident, id2);
    } else for(var i = 0; i < id2.length; i++) {
        // older MochiKit.Signal
        ident[i] = id2[i];
    }
}

MochiKit.Maps__Cgoogle.Marker.prototype.listen = function(events) {
    logWarning('Marker.listen is deprecated');
};

MochiKit.Maps__Cgoogle.Marker.prototype.unlisten = function() {
    logWarning('Marker.unlisten is deprecated');
};
MochiKit.Maps__Cgoogle.Marker.prototype.getElement = function() {
        return this.element;
};

MochiKit.Maps__Cgoogle.GMercatorProjection= function(a)
  {
   var b=this;
   b.pixelsPerLonDegree=[];
   b.pixelsPerLonRadian=[];
   b.bitmapOrigo=[];
   b.numTiles=[];
   var c=256;
   for(var d=0;d<a;d++)
   {
    var e=c/2;
    b.pixelsPerLonDegree.push(c/360);
    b.pixelsPerLonRadian.push(c/(2*Math.PI));
    b.bitmapOrigo.push(new MochiKit.Maps__Cgoogle.GPoint(e,e));
    b.numTiles.push(c);
    c*=2
   }
  };
  
MochiKit.Maps__Cgoogle.GMercatorProjection.prototype.fromLatLngToPixel=function(point,zoom){
   var a = point;
   var b = zoom;
   var c = this;
   var d = c.bitmapOrigo[b];
   var e = Math.round(d.x+a.lng()*c.pixelsPerLonDegree[b]);
   var f = GetNumberInRange(Math.sin(this.getRadianByDegree(a.lat())),-0.9999,0.9999);
   var g = Math.round(d.y+0.5*Math.log((1+f)/(1-f))*-c.pixelsPerLonRadian[b]);
   return new MochiKit.Maps__Cgoogle.GPoint(e,g)
  };
MochiKit.Maps__Cgoogle.GMercatorProjection.prototype.getWrapWidth=function(a)
  {
   return this.numTiles[a]
  };  
MochiKit.Maps__Cgoogle.GMercatorProjection.prototype.getBoundsZoomLevel=function (bounds,b)
  {
   var c=this;
   var d=16;
   var e=0;
   var f=bounds.southWest;
   var g=bounds.northEast;
   for(var h=d;h>=e;--h)
   {
    var i=c.fromLatLngToPixel(f,h);
    var l=c.fromLatLngToPixel(g,h);
    if(i.x>l.x)
    {
     i.x-=c.getWrapWidth(h)
    }
    if(Math.abs(l.x-i.x)<=b.width&&Math.abs(l.y-i.y)<=b.height)
    {
     return h
    }
   }
   return 0
  };  
 
MochiKit.Maps__Cgoogle.GMercatorProjection.prototype.getRadianByDegree = function (d){
	return d*Math.PI/180
};

MochiKit.Maps__Cgoogle.GLatLng = function (a,b,c){
	if(!c){
		a=GetNumberInRange(a,-90,90);
		b=this.getLoopNumber(b,-180,180)
	}
	this.latitude=a;
	this.longitude=b;
	this.x=b;
	this.y=a
} 

MochiKit.Maps__Cgoogle.GLatLng.prototype.lat=function(){
	return this.latitude
};
MochiKit.Maps__Cgoogle.GLatLng.prototype.lng=function(){
	return this.longitude
};
MochiKit.Maps__Cgoogle.GLatLng.prototype.getLoopNumber = function(a,b,c){ 
   while(a>c){
    a-=c-b
   }
   while(a<b){
    a+=c-b
   }
   return a
};

MochiKit.Maps__Cgoogle.GPoint=function (a,b){
	this.x=a;
	this.y=b
};

MochiKit.Maps__Cgoogle.ElementSize=function (a,b){
	this.width=a;
	this.height=b
};

GetNumberInRange = function(a,b,c){
	  if(a>b&&a<c){
	  return a;
	  }
	  if(a<b) return b;
	  if(a>c) return c;
};

MochiKit.Signal.signal(window, "MochiMaps-load", MochiKit.Maps__Cgoogle);

