var GvGMaps2Loader = Class.create();
GvGMaps2Loader.loaded = false;
GvGMaps2Loader.loading = false;
GvGMaps2Loader.timeout = 100;
GvGMaps2Loader.__globalCallBack = function() {
	GvGMaps2Loader.loaded = true;
}
GvGMaps2Loader.prototype = {
  initialize: function(apiKey) {
    this.apiKey = apiKey;
  },
  
	getMap: function(callBack, canvas) {
		this.callBack = callBack;
		this.canvas = canvas;
	
		if (GvGMaps2Loader.loaded) {
			this.__createMap();
		} else {
			if (GvGMaps2Loader.loading) {
				setTimeout(this.__checkStatus.bind(this), GvGMaps2Loader.timeout);
			} else {
				this.__loadGApi();
			}
		}
	},
	
	__createMap: function() {
		var map = new google.maps.Map2($(this.canvas));
		this.callBack(map);
	},
	
	__loadGApi: function() {
		var loader = new GvGApiLoader(this.apiKey);
		loader.load(this.__loadGMapsApi.bind(this));
	},
	
	__loadGMapsApi: function() {
		google.load("maps", "2", {callback: GvGMaps2Loader.__globalCallBack});
		setTimeout(this.__checkStatus.bind(this), GvGMaps2Loader.timeout);
	},
	
	__checkStatus: function() {
		if (GvGMaps2Loader.loaded) {
			this.__createMap();
		} else {
			setTimeout(this.__checkStatus.bind(this), GvGMaps2Loader.timeout);
		}
	}
}

var GvGApiLoader = Class.create();
GvGApiLoader.loaded = false;
GvGApiLoader.loading = false;
GvGApiLoader.timeout = 100;
GvGApiLoader.__globalCallBack = function() {
	GvGApiLoader.loaded = true;
}
GvGApiLoader.prototype = {
  initialize: function(apiKey) {
    this.apiKey = apiKey;
  },
  
	load: function(callBack) {
		if (GvGApiLoader.loaded) {
			callBack();
		} else if (GvGApiLoader.loading) {
			this.callBack = callBack;
			setTimeout(this.__checkStatus.bind(this), GvGApiLoader.timeout);
		} else {
			GvGApiLoader.loading = true;
			this.callBack = callBack;
			
			var script = document.createElement("script");
			script.src = "http://www.google.com/jsapi?key=" + this.apiKey + "&callback=GvGApiLoader.__globalCallBack";
			script.type = "text/javascript";
			document.getElementsByTagName("head")[0].appendChild(script);
			
			setTimeout(this.__checkStatus.bind(this), GvGApiLoader.timeout);
		}
	},
	
	__checkStatus: function() {
		if (GvGApiLoader.loaded) {
			this.callBack();
		} else {
			setTimeout(this.__checkStatus.bind(this), GvGApiLoader.timeout);
		}
	}
}