GMap = {};

GMap.Map = function(address, id){
    var self = this;
    var options = (function(o){return o})(GMap.Map.options)
    
    this.isReady = false;
    this.observers = [];
    this.map;
    
    new GMap.Address(address).ready(function(){
        options.center = this.result[0].geometry.location;
        GMap.Address.options.bounds = new google.maps.LatLngBounds(options.center);
        window.onload = function(){
            self.map = new GMap.Canvas(id).draw(options);
            self.isReady = true;
            self.notify();
        };
    });
};
GMap.Map.prototype.mark = function(address){
    var self = this;
    this.observers.push(function(){
        new GMap.Address(address).ready(function(){
            address = this;
            new google.maps.Marker({
                map: self.map, 
                position: address.result[0].geometry.location
            });
        });
    });
    self.notify();
    return this;
};
GMap.Map.prototype.notify = function(){
    if(this.isReady)
    	for(var fn; fn = this.observers.shift();)
            fn();
};
GMap.Map.options = {
    zoom: 12,
    mapTypeId: google.maps.MapTypeId.ROADMAP
};


(function(){
    
var geocoder = new google.maps.Geocoder();

GMap.Address = function(address){
    var self = this;
    
    this.isReady = false;
    this.result = null;
    this.observers = [];
    
    GMap.Address.options.address = address;
    
    geocoder.geocode(GMap.Address.options, function(result, status){
        if(status === google.maps.GeocoderStatus.OK){
            self.isReady = true;
            self.result = result;
            self.notify();
        }
    });
};
})();
GMap.Address.prototype.ready = function(fn){
    this.observers.push(fn);
    this.notify();
};
GMap.Address.prototype.notify = function(){
    if(this.isReady)
        for(var fn; fn = this.observers.shift();)
            fn.call(this);
};
GMap.Address.options = {};

GMap.Canvas = function(id){
    this.element = id;
};
GMap.Canvas.prototype.draw = function(options){
    if(typeof this.element === "string")
        this.element = document.getElementById(this.element);
    return new google.maps.Map(this.element, options);
};
