//
// Objeto de configuración
//
function wmsConfig() {
	this.groups = new Object();
	this.clone = function() {
		var cfg = new wmsConfig();
		for (var g in this.groups) {
			cfg.groups[g] = this.groups[g].clone();
		}
		return cfg;
	}
}

//
// Objeto grupo
//
function wmsGroup() {
	this.name = 'name';
	this.desc = 'desc';
	this.defaultGroup = false;
	this.services = new Object;
	this.clone = function() {
		var group = new wmsGroup();
		group.name = this.name;
		group.desc = this.name;
		group.defaultGroup = this.defaultGroup;
		for (var s in this.services) {
			group.addService(this.services[s].clone());
		}
		return group;
	}
}
wmsGroup.prototype.setDefault = function(flag) {
	this.defaultGroup = flag;
}
wmsGroup.prototype.addService = function(svc) {
	if (this.services[svc.name]) wmsConfig.throwError('duplicated', 'El servicio "' + svc.desc + '" ya existe', 'Error agregando servicio');
	this.services[svc.name] = svc;
}
wmsGroup.prototype.removeService = function(name) {
	if (!this.serviceExists(name)) wmsConfig.throwError('notFound', 'El servicio ' + name + ' no existe', 'Error eliminando servicio');
	return delete(this.services[name]);
}
wmsGroup.prototype.serviceExists = function(name) {
	for (var s in this.services) {
		if (this.services[s].name==name) return true;
	}
	return false;
}

//
// Objeto servicio
//
function wmsService() {
	this.sorted_layers = new Array();
	//
	this.name = 'name';
	this.shortName = this.name;
	this.desc = 'desc';
	this.defaultService = false;
	this.forBrowse = true;
	this.forError = false;
	this.customizable = false;
	this.onlyOneFixedLayer = false; // si verdadero, sólo puede haber una capa fixed activa
	this.highlight = false;
	this.href = {title:'',url:''};
	//
	this.legend = '';
	this.visibility = {minResolution:7, maxResolution:19};
	this.copyrightCollection = '';
	this.baseUrl3D = '';
	this.query = {
		queryUrl: '',
		queryUrl3D: '',
		queryLayers: '',
		format: '',
		imageFormat: ''
	};
	this.layers = new Object;
	this.clone = function() {
		var svc = new wmsService();
		with (svc) {
			name = this.name;
			shortName = this.shortName;
			desc = this.desc;
			defaultService = this.defaultService;
			forBrowse = this.forBrowse;
			forError = this.forError;
			customizable = this.customizable;
			onlyOneFixedLayer = this.onlyOneFixedLayer;
			highlight = this.highlight;
			href = {title:this.href.title,url:this.href.url};
			legend = this.legend;
			visibility = {minResolution:this.visibility.minResolution, maxResolution:this.visibility.maxResolution};
			copyrightCollection = this.copyrightCollection;
			baseUrl3D = this.baseUrl3D;
			query = {
				queryUrl: this.query.queryUrl,
				queryUrl3D: this.query.queryUrl3D,
				queryLayers: this.query.queryLayers,
				format: this.query.format,
				imageFormat: this.query.imageFormat
			};
			// capas
			for (var l in this.layers) {
				svc.addLayer(this.layers[l].clone());
			}
		}
		return svc;
	};
}
wmsService.prototype.getConfig = function() {
	var xml = '<service name="'+this.name
	                +'" shortName="'+this.shortName
					+'" desc="'+this.desc
					+'" default="'+this.defaultService
					+'" forBrowse="'+this.forBrowse
					+'" forError="'+this.forError
					+'" customizable="'+this.customizable
					+'" onlyOneFixedLayer="'+(this.layers.onlyOneFixedLayer?'true':'false')
					+'" highlight="'+(this.highlight?'true':'false')+'">'
	// href
	if (this.href.url!='') xml += '<href title="'+this.href.title+'">'+this.href.url+'</href>'
	// legend
	xml += '<legend>'+this.legend+'</legend>'
	// visibility
	xml += '<visibility min="'+this.visibility.minResolution+'" max="'+this.visibility.maxResolution+'"/>'
	// copyrightCollection
	xml += '<copyrightCollection>'+this.copyrightCollection+'</copyrightCollection>'
	// query
	xml += '<query>'
	xml += '<queryUrl><![CDATA['+this.query.queryUrl+']]></queryUrl>'
	xml += '<queryLayers>'+this.query.queryLayers+'</queryLayers>'
	xml += '<format'+(this.query.infoFormat?' image="'+this.query.infoFormat+'"':'')+'>'+this.query.format+'</format>'
	xml += '</query>'
	// layers
	xml += '<layers>'
	for (var s=0;s<this.sorted_layers.length;s++) {
		var l = this.layers[this.sorted_layers[s]];
		if (l.name!='ghost') {
			xml += '<layer name="'+l.name
			           +'" desc="'+l.desc
					   +'" visible="'+l.visible
					   +'" fixed="'+l.fixedLayer
					   +'" folder="'+((l.folder)?l.folder:'')
					   +'" queryable="'+l.queryable
					   +'" hidden="'+(l.hidden?l.hidden:'false')+'">'
			xml += '<type>'+l.type+'</type>'
			xml += '<format>'+l.format+'</format>'
			xml += '<baseUrl><![CDATA['+l.baseUrl+']]></baseUrl>'
			if (l.baseUrlToPrint)
				xml += '<baseUrlToPrint><![CDATA['+l.baseUrlToPrint+']]></baseUrlToPrint>'
			//xml += '<tileUrl><![CDATA['+l.tileFunction+']]></tileUrl>'
			xml += '<tileUrl/>' // se establece a la hora de recrear el servicio
			xml += '<layers>'+l.layers+'</layers>'
			xml += '<opacity>'+l.opacity+'</opacity>'
			if (l.singleTile)
				xml += '<singleTile><![CDATA['+l.singleTile+']]></singleTile>';
			xml += '</layer>'
		}
	}
	xml += '</layers>'
	xml += '</service>'
	return xml
}
wmsService.prototype.setDefault = function(flag) {
	this.defaultService = flag;
}
wmsService.prototype.removeLayer = function(name) {
	if (!this.layerExists(name)) wmsConfig.throwError('notFound', 'La capa ' + name + ' no existe', 'Error eliminando capa');
	return delete(this.layers[name]);
}
wmsService.prototype.removeLayers = function() {
	var flag = true;
	var noDel=0;
	for (var s in this.layers) {
		// eliminamos todas las capas excepto la fantasma
		if (this.layers[s].name!='ghost')
			if (!delete(this.layers[s])) wmsConfig.throwError('unknowError', 'Error al eliminar la capa ' + s, 'Error de borrado');
		else
			noDel++;
	}
	this.sorted_layers = new Array();
	if (noDel==0) {
		this.layers = {};
		this.sorted_layers.push('ghost');
	}	
	return flag;
}
wmsService.prototype.addLayer = function(lyr) {
	if (this.layerExists(lyr.name)) wmsConfig.throwError('duplicated', 'La capa ' + lyr.name + ' ya existe', 'Capa duplicada');
	this.layers[lyr.name] = lyr;
	this.sorted_layers.push(lyr.name);
}
wmsService.prototype.layerExists = function(name) {
	if (this.layers) {
		for (var s in this.layers) {
			if (this.layers[s].name==name)
				return true;
		}
	}
	return false;
}
wmsService.prototype.getLayerByDesc = function(desc) {
	if (this.layers) {
		for (var s in this.layers) {
			if (this.layers[s].desc==desc)
				return this.layers[s];
		}
	}
	return null;
}
//
// Objeto layer
//
function wmsLayer() {
	this.name = 'newLayer';
	this.desc = 'newLayerDesc';
	this.visible = false;
	this.fixedLayer = false;
	this.visibility = {minResolution:7,maxResolution:19};
	this.type = '';
	this.format = '';
	this.baseUrl = '';
	this.baseUrlToPrint = '';
	this.tileFunction = null;
	this.layers = '';
	this.opacity = 1;
	this.singleTile = null;
	this.folder = null;
	this.queryable = false;	
	this.hidden = false;
	this.clone = function() {
		var layer = new wmsLayer();
		layer.name = this.name;
		layer.desc = this.desc;
		layer.visible = this.visible;
		layer.fixedlayer = this.fixedLayer;
		layer.visibility = {minResolution:this.visibility.minResolution,maxResolution:this.visibility.maxResolution};
		layer.type = this.type;
		layer.format = this.format;
		layer.baseUrl = this.baseUrl;
		layer.baseUrlToPrint = this.baseUrlToPrint;
		layer.tileFunction = this.tileFunction;
		layer.layers = this.layers;
		layer.opacity = this.opacity;
		layer.singleTile = this.singleTile;
		layer.folder = this.folder;
		layer.queryable = this.queryable;
		layer.hidden = this.hidden;
		return layer;
	}
	return this;
}
//
// Rutinas de creación de objetos
//
wmsConfig.prototype.createGroup = function(name, desc) {
 	var grp = new wmsGroup();
	grp.name = name;
	grp.desc = desc;
	this.groups[name] = grp;
	return grp;
}
wmsConfig.prototype.createService = function(attrs, query, elems) {
 	var svc = new wmsService();
	svc.name = attrs['name'];
	if (attrs['shortName']!='')
		svc.shortName = attrs['shortName'];
	else
		svc.shortName = svc.name;
	svc.desc = attrs['desc'];
	svc.defaultService = attrs['defaultService'];
	svc.forBrowse = attrs['forBrowse'];
	svc.forError = attrs['forError'];
	if (attrs['customizable'])
		svc.customizable = eval(attrs['customizable']);
	if (svc.customizable /*&& svc.name=='customService'*/) {
		//svc.name = 'custom' + (this.countOfCustomizableServices()+1);
		svc.name = 'custom' + (++this.customCount);
	}
	for (var s in query) {
		svc.query[s] = query[s];
	}
	if (elems) {
		if (elems['legend']) svc.legend = elems['legend'];
		if (elems['minResolution'] && elems['maxResolution']) {
			svc.visibility.minResolution = elems['minResolution'];
			svc.visibility.maxResolution = elems['maxResolution'];
		}
		if (elems['copyrightCollection']) svc.copyrightCollection = elems['copyrightCollection'];
		if (elems['baseUrl3D']) svc.baseUrl = elems['baseUrl3D'];
	}
	if (attrs['onlyOneFixedLayer']) svc.onlyOneFixedLayer = attrs['onlyOneFixedLayer'];
	if (attrs['highlight']) svc.highlight = attrs['highlight'];
	if (attrs['href']) {
		svc.href.title = attrs['href'].title;
		svc.href.url = attrs['href'].url;
	}
	// Si es un servicio personalizado creamos su capa fantasma de fondo
	if (svc.customizable) {
		svc.addLayer(this.createGhostLayer());
	}
	//
	return svc;
}
wmsConfig.prototype.createServiceFromXML = function(xml) {
	// xml contiene un nodo <service>
 	var svc = new wmsService();
	svc.name = attrs['name'];
	if (attrs['shortName']!='')
		svc.shortName = attrs['shortName'];
	else
		svc.shortName = svc.name;
	svc.desc = attrs['desc'];
	svc.defaultService = attrs['defaultService'];
	svc.forBrowse = attrs['forBrowse'];
	svc.forError = attrs['forError'];
	if (attrs['customizable'])
		svc.customizable = eval(attrs['customizable']);
	if (svc.customizable /*&& svc.name=='customService'*/) {
		//svc.name = 'custom' + (this.countOfCustomizableServices()+1);
		svc.name = 'custom' + (++this.customCount);
	}
	for (var s in query) {
		svc.query[s] = query[s];
	}
	if (elems) {
		if (elems['legend']) svc.legend = elems['legend'];
		if (elems['minResolution'] && elems['maxResolution']) {
			svc.visibility.minResolution = elems['minResolution'];
			svc.visibility.maxResolution = elems['maxResolution'];
		}
		if (elems['copyrightCollection']) svc.copyrightCollection = elems['copyrightCollection'];
		if (elems['baseUrl3D']) svc.baseUrl = elems['baseUrl3D'];
	}
	if (attrs['onlyOneFixedLayer']) svc.onlyOneFixedLayer = attrs['onlyOneFixedLayer'];
	return svc;
}
wmsConfig.prototype.createLayer = function(name, desc, params) {
	var layer = new wmsLayer();
	layer.name = name;
	layer.desc = desc;
	try {layer.visible = params['visible'];} catch(e){};
	try {layer.fixedLayer = params['fixedLayer'];} catch(e){};
	//layer.visibility = {minResolution:7,maxResolution:19};
	try {layer.visibility.minResolution = params['visibility'].minResolution;} catch(e){};
	try {layer.visibility.maxResolution = params['visibility'].maxResolution;} catch(e){};
	try {layer.type = params['type'];} catch(e){};
	try {layer.format = params['format'];} catch(e){};
	try {layer.baseUrl = params['baseUrl'];} catch(e){};
	try {layer.baseUrlToPrint = params['baseUrlToPrint'];} catch(e){layer.baseUrlToPrint=null;};
	try {layer.tileFunction = eval(params['tileFunction']);} catch(e){};
	try {layer.layers = params['layers'];} catch(e){};
	try {layer.opacity = params['opacity'];} catch(e){};
	try {layer.singleTile = params['singleTile'];} catch(e){layer.singleTile = null;};
	try {layer.folder = params['folder'];} catch(e){layer.folder = null;};
	try {layer.queryable = params['queryable'];} catch(e){};
	try {layer.hidden = params['hidden'];} catch(e){layer.hidden = false;};
	return layer;
}
wmsConfig.prototype.createGhostLayer = function() {
	var layer = new wmsLayer();
	layer.name = 'ghost';
	layer.desc = 'ghost layer';
	layer.visible = true;
	layer.fixedLayer = true;
	layer.tileFunction = getTileUrl_blank;
	layer.hidden = true;
	return layer;
}

//
// utilidades
//
wmsConfig.throwError = function(name, description, constructorDescription) {
	var err = new Error(constructorDescription);
	err.description = description;
	err.name = name;
	throw(err);
}
wmsConfig.prototype.getService = function(serviceName, groupName) {
	if (groupName) {
		if (this.groups[groupName] && this.groups[groupName].services[serviceName])
			return this.groups[groupName].services[serviceName];
	} else {
		for (var s in this.groups) {
			for (var t in this.groups[s].services) {
				if (this.groups[s].services[t].name==serviceName)
					return this.groups[s].services[t];
			}
		}
	}
	if (groupName)
		wmsConfig.throwError('notFound', 'El grupo ' + groupName + ' no existe', 'Grupo inexistente');
	else
		wmsConfig.throwError('notFound', 'El servicio ' + serviceName + ' no existe', 'Servicio inexistente');
}
wmsConfig.prototype.getDefaultService = function() {
	for (var s in this.groups) {
		for (var t in this.groups[s].services) {
			if (this.groups[s].services[t].defaultService) {
				return this.groups[s].services[t];
			}
		}
	}
}
wmsConfig.prototype.groupExists = function(name) {
	for (var s in this.groups) {
		if (this.groups[s].name==name) return true;
	}
	return false;
}
wmsConfig.prototype.getCustomizableServices = function() {
	var svc = {};
	for (var s in this.groups) {
		for (var t in this.groups[s].services) {
			if (this.groups[s].services[t].customizable)
				svc[t] = this.groups[s].services[t].desc;
		}
	}
	return svc;
}
wmsConfig.prototype.countOfCustomizableServices = function() {
	var count = 0;
	for (var s in this.groups) {
		for (var t in this.groups[s].services) {
			if (this.groups[s].services[t].customizable)
				++count;
		}
	}
	return count;
}
wmsConfig.prototype.customCount = 0;