GPolyline.prototype.equals = function ( gpolyline ) {
	if ( !(gpolyline instanceof GPolyline) ) return false;
	return ( ( this.getBounds() == gpolyline.getBounds() )
			&& ( this.getLength() == gpolyline.getLength() )
			&& ( this.getVertexCount() == gpolyline.getVertexCount() ) );
}

GMarker.prototype.equals = function ( gmarker ) {
	if ( !(gmarker instanceof GMarker) ) return false;
	return this.fk == gmarker.fk;
}

var LayerGroup = ( function ( ) {
	var obj = function ( ) {
		this._layers = [];
		this.addLayer.apply ( this, arguments );
	}
	obj.prototype.addLayer = function ( layer ) {
		this.removeLayer.apply ( this, arguments );
		for ( var i = 0; i < arguments.length; i ++ ) {
			this._layers.push ( arguments[i].id || arguments[i].toString() );
		}
	}
	obj.prototype.removeLayer = function ( layer ) {
		var layers = [];
		for ( var i = 0; i < arguments.length; i ++ ) {
			layers.push ( arguments[i].id || arguments[i].toString() );
		}
		layers = layers.join("~=~");
		for ( var i = this._layers.length - 1; i >= 0; i -- ) {
			if ( layers.match ( new RegExp ( "(^|~=~)" + this._layers[i] + "(~=~|$)", "i" ) ) ) {
				this._layers.splice(i,1);
			}
		}
	}
	return obj;
} )();

var LayerManager = ( function ( ) {
	var register = {};
	var fireEvent = function ( evt, args ) {
		if ( !(args instanceof Array) ) args = [ args ];
		if ( register[evt] instanceof Array ) {
			for ( var i = 0, r; r = register[evt][i]; i ++ ) {
				r.fn.apply ( r.obj, args );
			}
		}
	}
	var addEventListener = function ( evt, fn, obj ) {
		if ( register[evt] === undefined ) {
			register[evt] = [];
		}
		register[evt].push ( { fn : fn, obj : obj } );
	}
	var removeEventListener = function ( evt, fn, obj ) {
		if ( register[evt] === undefined ) return;
		for ( var i = register[evt].length - 1; i > 0; i -- ) {
			if ( register[evt].fn == fn && register[evt].obj == obj ) {
				register[evt].splice(i,0);
			}
		}
	}
	var obj = function ( map ) {
		this._map = map;
		this._layers = {};
		this._currentLayer = null;
		this._defaultLayer = "default";
	}
	obj.prototype.showLayer = function ( layer ) {
		var layers = [];
		for ( var i = 0; i < arguments.length; i ++ ) {
			if ( arguments[i] instanceof LayerGroup ) {
				for ( var j = 0; j < arguments[i]._layers.length; j ++ ) {
					if ( this._layers[arguments[i]._layers[j]] ) layers.push ( arguments[i]._layers[j] );
				}
			} else {
				var lid = ( arguments[i].id || arguments[i].toString() );
				if ( this._layers[lid] ) layers.push ( lid );
			}
		}
		if ( !layers.length ) return;
	
		var layerId = layers.join("~=~");
		this._currentLayer = layerId;
		
		for ( layer in this._layers ) {
			var l = this._layers[layer];
			var visible = !!layerId.match ( new RegExp ( "(^|~=~)" + l.id + "(~=~|$)", "i" ) );
			if ( l._visible != visible ) {
				var obj = ( visible ? "add" : "remove" ) + "Overlay";
				for ( var i = 0; i < l._overlays.length; i ++ ) {
					this._map[obj](l._overlays[i]);
				}
				this._layers[layer]._visible = visible;
				if ( visible ) {
					if ( l.center ) MAP.panTo ( l.center );
					if ( l.zoom && l.zoom != MAP.getZoom() ) MAP.setZoom ( l.zoom );
					if ( l.type && l.type != MAP.getMapType ) MAP.setMapType ( l.type );
					fireEvent ( "showlayer", this._layers[layer] );
				}
			}
		}
	}
	obj.prototype.setLayer = function ( layer, options ) {
		if ( this._layers[layer] == null ) {
			this._layers[layer] = { _overlays : [] };
		}
		options = options || {};
		options.id = layer;
		for ( o in options ) {
			if ( o.charAt(0) != "_" )
				this._layers[layer][o] = options[o];
		}
		fireEvent ( "setlayer", this._layers[layer] );
	}
	obj.prototype.getCurrentLayer = function ( ) {
		if ( this._currentLayer == null ) {
			this._currentLayer = this._defaultLayer;
		}
		return this._currentLayer;
	}
	obj.prototype.addOverlay = function ( overlay, layer ) {
		if ( layer == null ) layer = this.getCurrentLayer();
		if ( this._layers[layer] == null ) {
			this.setLayer ( layer );
		}
		this._layers[layer]._overlays.push ( overlay );
		if ( this._layers[layer]._visible ) {
			this._map.addOverlay ( overlay );
		}
	}
	obj.prototype.removeOverlay = function ( overlay, layer ) {
		if ( !overlay ) return;
		if ( layer == null ) layer = this.getCurrentLayer();
		var f = function ( i ) {
			this._layers[layer]._overlays.splice ( i, 1 );
			if ( this._layers[layer]._visible ) {
				this._map.removeOverlay ( overlay );
			}
		}

		if ( this._layers[layer] != null ) {
			for ( var i = 0, o; o = this._layers[layer]._overlays[i]; i ++ ) {
				if ( overlay.equals && overlay.equals ( o ) ) {
					f.call ( this, i );
					break;
				}
			}
		}
	}
	obj.prototype.addEventListener = addEventListener;
	obj.prototype.removeEventListener = removeEventListener;
	return obj;
} )();

var AMarker = ( function ( ) {
	var bindPage = function ( obj, page ) {
		var fn = ( typeof page == "string" ) ? "bindInfoWindowHtml" : "bindInfoWindow";
		obj[fn](page);
	}
	var obj = function ( latlng, options ) {
		var pages = options.text;
		delete options.text;

		var tmp = new GMarker ( latlng, options );
		for ( p in tmp ) {
			if ( (typeof tmp[p] != "function") || (typeof this[p] == "undefined") ) {
				this[p] = tmp[p];
			}
		}
		if ( pages && !(pages instanceof Array ) ) {
			pages = [ pages ];
		}
		var self = this;
		//this.setLatLng ( latlng );
		var container = null;
		if ( pages && pages.length ) {
			if ( pages.length > 1 ) {
				container = document.createElement('div');
				container.className = "bubblePaginator";
				container.showPage = function ( page ) {
					var extras = 0;
					var pages = paginator.getElementsByTagName('li');
					page = Math.min ( Math.max ( 0, parseInt ( page ) ), pages.length - 1 - extras );
					for ( var i = 0; i < pages.length - extras; i ++ ) {
						pages[i+extras/2].className = ( page == i ) ? "active" : "";
						pages[i+extras/2].page.className = "page" + ( ( page == i ) ? " active" : "" );
					}
					self.openInfoWindow(this);
					container._pageNumber = page;
				}
				container._pageNumber = 0;
				
				var pageContainer = document.createElement('div');
				pageContainer.className = "pages";
				container.appendChild ( pageContainer );
				var paginator = document.createElement('ul')
				var paginatorParent = document.createElement('div');
				paginatorParent.className = "paginator";
				paginatorParent.innerHTML = "<span>Page</span>";
				paginatorParent.appendChild ( paginator );
				container.appendChild ( paginatorParent );
				
				var prev = document.createElement('li');
				prev.className = "prev";
				prev.innerHTML = "&laquo;";
				prev.onclick = function ( ) {
					container.showPage ( container._pageNumber - 1 );
				}
				//paginator.appendChild ( prev );
				
				for ( var i = 0; i < pages.length; i ++ ) {
					var pageHandle = document.createElement('li');
					pageHandle.className = ( i ? "" : "active" );
					pageHandle.pageNumber = i;
					pageHandle.onclick = function ( ) { container.showPage ( this.pageNumber ); }
					pageHandle.innerHTML = i+1;
					paginator.appendChild ( pageHandle );
					
					var page = document.createElement('div');
					page.className = "page" + ( i ? "" : " active" );
					pageContainer.appendChild ( page );
					pageHandle.page = page;

					if ( typeof pages[i] == "string" ) {
						page.innerHTML = pages[i];
					} else {
						page.appendChild ( pages[i] );
					}
				}

				var next = document.createElement('li');
				next.className = "next";
				next.innerHTML = "&raquo;";
				next.onclick = function ( ) {
					container.showPage ( container._pageNumber + 1 );
				}
				//paginator.appendChild ( next );
				
				bindPage ( this, container );
			} else {
				bindPage ( this, pages[0] );
			}
		} else {
			pages = null;
		}
		this.showInfoWindow = function ( ) {
			this.show();
			if ( !pages ) {
				GEvent.trigger ( this, "infowindowopen" );
			} else {
				if ( container ) {
					container.showPage ( 0 );
				} else {
					GEvent.trigger ( this, "click" );
				}
			}
		}
	}

	obj.prototype = GMarker.prototype; 
	return obj;
} )();
