//Author: Kyle Mulka (http://www.kylemulka.com)
//
//
//A library which allows you to add your own WMS service as a new tab in the Google Maps framework
//inspired by the Katrina map type which shows up if you zoom in on New Orleans
//
//features:
//extra map tab
//zoom in further

//requires:
//WMS version 1.1.1
//srs/projection = EPSG:4326


/* OO Design
WMSService()
defaults:
baseUrl: terraserver WMS
format: image/jpeg
layers: DOQ
bounds: no bounds
size: 256x256

setBaseUrl(string baseUrl);
setFormat(string format);
setLayers(string layers);

MapSpec(WMSService)

setNumZoomLevels() //sets the total number of zoom levels. reasonable range: 1-32
addNumZoomLevels(numLevels) //adds the number of zoom levels specified. Can accept negative numbers, but why?
setName() //string that shows up in map type tab
setBackgroundColor() //sets color which displays before images are loaded
setSpecial() //shows up in red
setCopywrite()
setTextColor()
setLinkColor()
setLinkText() //same as set name
*/

function copy_obj(o) {
	var c = new Object(); for (var e in o) { c[e] = o[e]; } return c;
}

function WMSService(){
	for (var e in map.mapTypes[0]) { this[e] = map.mapTypes[0][e]; }
	this.baseUrl = "http://www.terraserver-usa.com/ogcmap6.ashx?";
	this.format = "image/jpeg";
	this.layers = "DOQ";
	this.styles = "";
	this.srs = "EPSG:4326";
	this.bounds = new GBounds(-180, -90, 180, 90);
	this.setTransparent(true);
}

WMSService.prototype.setBaseUrl = function (baseUrl){
	this.baseUrl = baseUrl;
};

WMSService.prototype.setFormat = function (format){
	this.format = format;
};

WMSService.prototype.setLayers = function (layers){
	this.layers = layers;
};

WMSService.prototype.setBounds = function (bounds){
	this.bounds = bounds;
};

WMSService.prototype.getBounds = function (){
	return this.bounds;
};

WMSService.prototype.setTransparent = function (transparent){
	if(transparent){
		this.transparent = "true";
	}else{
		this.transparent = "false";
	}
};

WMSService.prototype.getUrl = function (x, y, zoom){
	//FIXME: encorporate bounds and other factors here
	var ll = this.getLatLng(x*this.tileSize, (y+1)*this.tileSize, zoom);
	var ur = this.getLatLng((x+1)*this.tileSize, y*this.tileSize, zoom);
	var bbox = ll.x + "," + ll.y + "," + ur.x + "," + ur.y;
	var url = this.baseUrl + "version=1.1.1&request=GetMap&Layers=" + this.layers + "&Styles=" + this.styles + "&SRS="+ this.srs +"&BBOX=" + bbox + "&width=" + this.tileSize +"&height=" + this.tileSize + "&format=" + this.format + "&transparent=" + this.transparent;
	return url;
};

function MapSpec(base, overlay){
	for (var e in map.mapTypes[0]) { this[e] = map.mapTypes[0][e]; }
	this.base = base;
	this.overlay = overlay;
	this.special = false;
	this.Name = this.getLinkText();
	this.zoomLevelOffset = 0;
	//this.numZoomLevels = 18;
	this.bounds = new GBounds(-180, -90, 180, 90);
	this.setAlternativeMapType(map.mapTypes[0]);

	if(!this.base.getUrl){
		this.base.getUrl = this.base.getTileURL;
	}
	
	//if there is an overlay set and it is not a WMSService
	if(this.overlay&&!this.overlay.getUrl){
		if(this.overlay.hasOverlay()){
			this.overlay.getUrl = function (x, y, zoom){return this.getOverlayURL(x, y, zoom);};
		}else{
			this.overlay = null;
		}
	}
	
	this.getTileURL = function (x, y, zoom){
		return this.base.getUrl(x, y, zoom);
	};
	
	this.getOverlayURL = function (x, y, zoom){
		return this.overlay.getUrl(x, y, zoom);
	};
	

}

MapSpec.prototype.hasOverlay = function (){
	if(this.overlay){
		return true;
	}else{
		return false;
	}
};


//sets the total number of zoom levels. reasonable range: 1-32
MapSpec.prototype.setNumZoomLevels = function (levels){
	this.base.numZoomLevels = levels;
	this.base.zoomLevelOffset= 18 - levels;
	this.base.initMercator();
};

//adds the number of zoom levels specified. Can accept negative numbers, but why?
MapSpec.prototype.addNumZoomLevels = function (numLevels){
	this.numZoomLevels += numLevels;
	this.base.numZoomLevels += numLevels;
	this.zoomLevelOffset -= numLevels;
	this.base.zoomLevelOffset -= numLevels;
	//alert(this.base.numZoomLevels);
	this.initMercator();
	this.base.initMercator();
};

//sets the box for which this map type will show up in
MapSpec.prototype.setBounds = function (bounds){
	this.bounds = bounds;
};

MapSpec.prototype.getBounds = function (){
	return this.bounds;
};

//sets the max zoom level that the map type will show up in. Level 0 is always closest zoom level for map type. Could I implement to depend on current map type?
MapSpec.prototype.setMaxZoomLevel = function (level){
	this.maxZoomLevel = level;
};

MapSpec.prototype.getMaxZoomLevel = function (){
	return this.maxZoomLevel;
};

//string that shows up in map type tab
MapSpec.prototype.setName = function (Name){
	//alert("set: " + Name);
	this.Name = Name;
	this.getLinkText = function(){return Name;};
};

//string that shows up in map type tab
MapSpec.prototype.setShortName = function (name){
	this.setShortLinkText(name);
};

//sets color which displays before images are loaded
MapSpec.prototype.setBackgroundColor = function (backgroundColor){
	this.backgroundColor = backgroundColor;
};

//shows up in red
MapSpec.prototype.setSpecial = function (special){
	this.special = special;
};

MapSpec.prototype.isSpecial = function(){
	return this.special;
};


MapSpec.prototype.setCopywrite = function (copywrite){
	this.copywrite = copywrite;
};

MapSpec.prototype.getCopywrite = function (){
	return this.copywrite;
};

MapSpec.prototype.setTextColor = function (){
	this.textColor = textColor
};

MapSpec.prototype.setLinkColor = function (linkColor){
	this.linkColor = linkColor;
	this.getLinkColor = function (){return this.linkColor;};
};

MapSpec.prototype.getLinkColor = function (linkColor){
	return this.linkColor;
};

/*
//same as set name
MapSpec.prototype.setLinkText = function (text){
	this.linkText = text;
};
*/




MapSpec.prototype.setShortLinkText = function (text){
	this.shortLinkText = text;
};

MapSpec.prototype.getShortLinkText = function (){
	return this.shortLinkText;
};

MapSpec.prototype.setAlternativeMapType = function(campus){
	this.alternativeMapType = campus;
};

MapSpec.prototype.getAlternativeMapType = function(){
	return this.alternativeMapType;
};