/**
 * Define a SLD Object
 *
 * First Param : SLD url if none, the default SLD
 */
function SLD(){
	/**
	 * Define the layer type 'Point', 'Line' or 'Polygon' 
	 */
	this.layerType = "";

	/**
	 * Layer Object associated
	 */
	this.layerObj;
	
	/**
	 * Is a new SLD or an edition ?
	 */
	this.isNew = false;
	
	/**
	 * URL of the initial SLD
	 */
	if(arguments.length == 0) {
		this.url = 'vide.sld';
		this.isNew = true;
	}
	else
		this.url = arguments[0];

	this.initSldId = function() {
		var newSldId = null;
		var sldUrl = this.url
		//si different de vide
		if (sldUrl.indexOf('vide') == -1) {
			//si c'est un interne
			if (sldUrl.indexOf('sldControler') > -1) {
				sldUrl = unescape(sldUrl);
				var slashId = sldUrl.lastIndexOf('/');
				var optId = sldUrl.lastIndexOf('sld=');
				//cas du non connecte
				if (optId > slashId) {
					slashId = optId + 4;
				}
				newSldId = sldUrl.substring(slashId+1);
				newSldId = newSldId.replace(/\.sld/g,"");
			}
		}
		return newSldId;
	}

	/**
	 * Current SLDID, return by the server who save the SLD to update this SLD
	 */
	this.sldId = this.initSldId();
	
	/**
	 * is this sld file parsed
	 */
	this.parsed = false;

	/**
	 * Define the selectedRule
	 */
	this.selectedRule;

	/**
	 * Return the xml form of the SLD
	 */
	this.toString = function(){
		var data;
		if(typeof ActiveXObject != "undefined") {
			data = this.SLDDoc.xml;
		} else {
			var serializer = new XMLSerializer();
			data = serializer.serializeToString(this.SLDDoc);
		}
		return data;
	};
    
	/**
	 * return the XMLHttpRequest Object
	 */
	this.getHTTPObject = function() {
		return dojo._xhrObj();
	};
    
	/**
	 * Return the xml content of an url
	 */
	this.getXMLAsText = function(XMLurl){
		var http = this.getHTTPObject();
		var message = "Erreur lors du chargement du fichier SLD";

		http.open("GET", XMLurl, false);
		http.send(null);
		if (http.status == 200)
			message = http.responseText;

		return message;
	}
    
	/**
	 * Return the xml DOM of an xml content
	 */
	function XML2DOM(textXML){
		var result;
		if (typeof DOMParser != "undefined") { 
			// Mozilla, Firefox, and related browsers
			result = (new DOMParser()).parseFromString(textXML, "application/xml"); 
		} else if (typeof ActiveXObject != "undefined") { 
			var xml = new ActiveXObject("Microsoft.XMLDOM");
			xml.async = false;
			xml.loadXML(textXML);
			result = xml;
		} else { 
			// As a last resort, try loading the document from a data: URL 
			// This is supposed to work in Safari. Thanks to Manos Batsis and 
			// his Sarissa library (sarissa.sourceforge.net) for this technique. 
			var url = "data:text/xml;charset=utf-8," + encodeURIComponent(textXML); 
			var request = new XMLHttpRequest(); 
			request.open("GET", url, false); 
			request.send(null); 
			result = request.responseXML; 
		}
		return result;
	}

	/**
	 * XML content of the initial URL
	 */
	this.SLDXML = this.getXMLAsText(this.url);
    
    /**
     * Last modification SLDXML
     */
    this.lastSLDXML = this.SLDXML;
    
    /**
     * first modification SLDXML
     */
    this.firstSLDXML = this.SLDXML;

	/**
	 * XML DOM of the initial URL
	 */
	this.SLDDoc = XML2DOM(this.SLDXML);
    
    /**
     * Restore the last version
     */
    this.restore = function(toFirst) {
    	if (toFirst) {
    		this.SLDDoc = XML2DOM(this.firstSLDXML);
    		this.SLDXML = this.firstSLDXML;
    	} else {
	    	this.SLDDoc = XML2DOM(this.lastSLDXML);
    		this.SLDXML = this.lastSLDXML;
	    }
    }
    
    /**
     * Make a save version
     */
    this.restorePoint = function() {
    	this.lastSLDXML = this.toString();
    }
    
	/**
	 * Return the value of the first tag 'Name' in the given node
	 * if no tag 'Name' make one with a default value
	 */
	this.getNameValueForNode = function(nodeName,idx){
		if (!idx) idx = 0;
		var element = this.SLDDoc.getElementsByTagName(nodeName);

		// test du renseignement du nom du layer.
		if (element.length>0 && element[idx].getElementsByTagName('Name').length>0){
			nameValue = (element[idx].getElementsByTagName('Name').item(0).firstChild.nodeValue);
		} else {
			// creation
			// TODO : recuperer le vrai nom du layer soit a partir de l'appel de fonction, soit autrement
			switch(nodeName){
				case "NamedLayer":
					nameValue='test';
					break;
				case "UserStyle":
					nameValue='Nouvelle th�matisation';
					break;
				case 'PropertyName':
					nameValue="";
					break;
				default:
					nameValue='new'+nodeName;
			}
			var obj = this.SLDDoc.createTextNode(nameValue);
			element[idx].getElementsByTagName('Name').item(0).appendChild(obj);
		}
		return nameValue; 
	};
    
	/**
	 * Define the layer Object and set the layer name in the sld
	 */
	this.setLayer = function( newLayerObj) {
		this.layerObj = newLayerObj;
		var layerName = this.layerObj.selectSingleNode("wmc:Name").firstChild.nodeValue;
		this.setLayerName(layerName);
	}
    
	/**
	 * Define the name of the Layer
	 */
	this.setLayerName = function(newName){
		var element = this.SLDDoc.getElementsByTagName('NamedLayer');
		element[0].getElementsByTagName('Name').item(0).firstChild.nodeValue = newName;
	};
    
	/**
	 * Define the name of the 'UserStyle' tag
	 */
	this.setThemeName = function(newName){
		var element = this.SLDDoc.getElementsByTagName('UserStyle');
		element[0].getElementsByTagName('Name').item(0).firstChild.nodeValue = newName;
	};
    
	/**
	 * Return he first 'PropertyName' tag's value
	 */
	this.getFirstPropertyName = function(){
		var element;
		if (this.SLDDoc.getElementsByTagName('PropertyName').length >0)
			element = this.SLDDoc.getElementsByTagName('PropertyName').item(0).firstChild.nodeValue;
		else
			element = "";
		return element;
	};
   
	/**
	 * Return the list of name and index of the 'Rule' tags
	 */
	this.getRulesNamesWithIndex = function() {
		var rules = this.SLDDoc.getElementsByTagName('Rule');
		var names = new Array();
		for (i=0;i<rules.length;i++) {
			var RuleName = (rules[i].getElementsByTagName('Name').item(0).firstChild.nodeValue);
			names.push([i+1,RuleName]);
		}
		return names;
	};
   
	/**
	 * Return the name of a rule with the given index
	 */
	this.getRuleName = function (RuleIdx) {
		var rule = this.SLDDoc.getElementsByTagName('Rule').item(RuleIdx);
		if (rule.getElementsByTagName('Name').length>0)
			var ruleName = rule.getElementsByTagName('Name').item(0).firstChild.nodeValue;
		else
			ruleName = "";
		return ruleName;
	};
   
	/**
	 * Define the name of a rule with the given index
	 */
	this.setRuleName = function (RuleIdx, RuleName) {
		var rule = this.SLDDoc.getElementsByTagName('Rule').item(RuleIdx);
		rule.getElementsByTagName('Name').item(0).firstChild.nodeValue = RuleName;
	};
   
	/**
	 * Return the first 'PropertyName' of the given rule index for the given filter index
	 */
	this.getPropertyName = function(RuleIdx, FilterIdx){
		if (!RuleIdx) RuleIdx = 0;
		if (!FilterIdx) FilterIdx = 0;
		if (this.SLDDoc.getElementsByTagName('Rule').length > 0){
			var rule = this.SLDDoc.getElementsByTagName('Rule').item(RuleIdx);
			var filter = rule.getElementsByTagName('Filter');
			if (filter.length == 0) {
				return "";
			}
			var propertyName = filter.item(0).getElementsByTagName('PropertyName').item(0).firstChild.nodeValue;
		} else
			propertyName = "";
		return propertyName;
   };
   
	/**
	 * Return the operator tag Name of the given rule index for the given filter index
	 */
	this.getOperator = function(RuleIdx, FilterIdx) {
		if (!RuleIdx) RuleIdx = 0;
		if (!FilterIdx) FilterIdx = 0;
		var opName = "";
		if (this.SLDDoc.getElementsByTagName('Rule').length > 0) {
			var rule = this.SLDDoc.getElementsByTagName('Rule').item(RuleIdx);
			if (rule.getElementsByTagName('PropertyName').length > 0)
				var opName = rule.getElementsByTagName('PropertyName').item(FilterIdx).parentNode.nodeName;
        } else
			opName = "";
		return opName;
	};

	/**
	 * Define the operator tag Name of the given rule index for the given filter index
	 * If FilterOp = 'PropertyIsBetween' the function take an other param, the UpperBoundary value (the lower is the value on the current literal
	 */
	this.setOperator = function(RuleIdx, FilterIdx, FilterOp) {
		if (!RuleIdx) RuleIdx = 0;
		if (!FilterIdx) FilterIdx = 0;
		var rule = this.SLDDoc.getElementsByTagName('Rule').item(RuleIdx);
		var OpNode = rule.getElementsByTagName('PropertyName').item(FilterIdx).parentNode;
		var FilterNode = OpNode.parentNode;
		FilterNode.removeChild(OpNode);
		var newNode = this.SLDDoc.createElement(FilterOp);
		if (FilterOp != 'PropertyIsBetween') {
			var children = OpNode.childNodes;
			for (var i=0;i<children.length;i++) {
				newNode.appendChild(children[i].cloneNode(true));
			}
		} else {
			var literal2 = arguments[3];
			var literal1 = OpNode.getElementsByTagName('Literal')[0];
			var propName = OpNode.getElementsByTagName('PropertyName')[0].firstChild.nodeValue;
			
			var newPropName = this.SLDDoc.createElement('PropertyName');
			var newValue = this.SLDDoc.createTextNode(propName);
			newPropName.appendChild(newValue);
			
			var lower = this.SLDDoc.createElement('LowerBoundary');
			lower.appendChild(literal1.cloneNode(true));
			
			var upper = this.SLDDoc.createElement('UpperBoundary');
			var upperLit = this.SLDDoc.createElement('Literal');
			var upperLitValue = this.SLDDoc.createTextNode(literal2);
			upperLit.appendChild(upperLitValue);
			upper.appendChild(upperLit);
			
			newNode.appendChild(newPropName);
			newNode.appendChild(lower);
			newNode.appendChild(upper);
			
		}
		FilterNode.appendChild(newNode);
	}

	/**
	 * Return the filter of the given rule index for the given filter index
	 */
	this.getFilterValue = function(RuleIdx, FilterIdx) {
		if (!RuleIdx) RuleIdx = 0;
		if (!FilterIdx) FilterIdx = 0;
		var expValue = "";

		if (this.SLDDoc.getElementsByTagName('Rule').length > 0) {
			var rule = this.SLDDoc.getElementsByTagName('Rule').item(RuleIdx);
			if  (rule.getElementsByTagName('PropertyName').length > 0) {
				var OpNode = rule.getElementsByTagName('PropertyName').item(FilterIdx).parentNode;
				for (i=0;i<OpNode.childNodes.length;i++) {
					if (OpNode.childNodes[i].nodeType == 1) {
						var theNode = OpNode.childNodes[i];
						if (theNode.nodeName == 'Literal' && theNode.firstChild)
							expValue = theNode.firstChild.nodeValue;
					}
				}
			}
		}
		return expValue;
	};

	/**
	 * Define the filter of the given rule index for the given filter index
	 */
	this.setFilterValue = function(RuleIdx, FilterIdx, FilterValue) {
		if (!RuleIdx) RuleIdx = 0;
		if (!FilterIdx) FilterIdx = 0;
		var rule = this.SLDDoc.getElementsByTagName('Rule').item(RuleIdx);
		var OpNode = rule.getElementsByTagName('PropertyName').item(FilterIdx).parentNode;
		expValue = "";
		for (i=0;i<OpNode.childNodes.length;i++) {
			if (OpNode.childNodes[i].nodeType == 1) {
				theNode = OpNode.childNodes[i];
				if (theNode.nodeName == 'Literal')
					theNode.firstChild.nodeValue = FilterValue;
			}
		}
	};

	/**
	 * Delete all the rules of the sld
	 */
	this.deleteRules = function() {
		var rules = this.SLDDoc.getElementsByTagName('Rule');

		for (i=rules.length-1;i>=0;i--) {
			this.SLDDoc.getElementsByTagName('FeatureTypeStyle').item(0).removeChild(rules[i]);  
		}
	};
   
	/**
	 * Delete the rule of the given index
	 */
	this.deleteRule = function(RuleIdx) {
		var rule = this.SLDDoc.getElementsByTagName('Rule').item(RuleIdx);
		this.SLDDoc.getElementsByTagName('FeatureTypeStyle').item(0).removeChild(rule);  
	};
   
	/**
	 * Add a new Rule
	 */
	this.buildDefaultRules = function(fieldname) {
		// implementation simple pour l'instant : on ne cree qu'un rule par defaut.
		var newRuleIdx = this.addRule('Defaut',fieldname);
		this.buildDefaultLayout(newRuleIdx);
   };
   
	/**
	 * Duplicate the rule with the given index
	 */
	this.duplicateRule = function(RuleIdx){
		var rule = this.SLDDoc.getElementsByTagName('Rule').item(RuleIdx).cloneNode(true);
		this.SLDDoc.getElementsByTagName('FeatureTypeStyle').item(0).appendChild(rule);
		this.setRuleName(this.SLDDoc.getElementsByTagName('Rule').length-1,'Copie de ' + this.getRuleName(RuleIdx));
		return this.SLDDoc.getElementsByTagName('Rule').length-1;
	};
   
	/**
	 * Make a new Layout in the given index Rule
	 */
	this.buildDefaultLayout = function(RuleIdx){
		if (arguments.length == 0) RuleIdx = 0;
        
		var theRule = this.SLDDoc.getElementsByTagName('Rule').item(RuleIdx);
		switch (this.layerType){
			case 'Point':
				SymbolizerType = 'PointSymbolizer';
				break;
			case 'Line':
				SymbolizerType = 'LineSymbolizer';
				break;
			case 'Polygon':
				SymbolizerType = 'PolygonSymbolizer';
				break;
			default:
				SymbolizerType = 'PointSymbolizer';
		}
		
		var Symbolizer = this.SLDDoc.createElement(SymbolizerType);
		theRule.appendChild(Symbolizer);
		if (SymbolizerType == 'PolygonSymbolizer') {
			var FillNode = this.SLDDoc.createElement('Fill');
			Symbolizer.appendChild(FillNode);
			
			FillNode.appendChild(this.buildCSSNode('fill','#999999'));
			
			var StrokeNode = this.SLDDoc.createElement('Stroke');
			Symbolizer.appendChild(StrokeNode);
			StrokeNode.appendChild(this.buildCSSNode('stroke','#000000'));
			StrokeNode.appendChild(this.buildCSSNode('stroke-width','1'));
		
		} else if(SymbolizerType == 'PointSymbolizer') {
			var graphicNode = this.SLDDoc.createElement('Graphic');
			Symbolizer.appendChild(graphicNode);
            
			var markNode = this.SLDDoc.createElement('Mark');
			graphicNode.appendChild(markNode);
            
			var Symbol = this.SLDDoc.createElement('WellKnownName');
			var SymbolName  = this.SLDDoc.createTextNode('Circle');
            
			Symbol.appendChild(SymbolName);
			markNode.appendChild(Symbol);
            
			var fillNode = this.SLDDoc.createElement('Fill');
			markNode.appendChild(fillNode);
			fillNode.appendChild(this.buildCSSNode('fill','#0000FF'));
			var sizeNode = this.SLDDoc.createElement('Size');
			SizeValue = this.SLDDoc.createTextNode('10');
			sizeNode.appendChild(SizeValue);
			markNode.appendChild(sizeNode);
            
			var StrokeNode = this.SLDDoc.createElement('Stroke');
			markNode.appendChild(StrokeNode);
			StrokeNode.appendChild(this.buildCSSNode('stroke','#000000'));
			StrokeNode.appendChild(this.buildCSSNode('stroke-width','1'));
		
		} else if (SymbolizerType == 'LineSymbolizer') {
			var StrokeNode = this.SLDDoc.createElement('Stroke');
			Symbolizer.appendChild(StrokeNode);
			StrokeNode.appendChild(this.buildCSSNode('stroke','#000000'));
			StrokeNode.appendChild(this.buildCSSNode('stroke-width','1'));
		}
	};
   
	/**
	 * Make an node 'CssParameter' with the given name and value
	 */
	this.buildCSSNode = function(name, value){
		var Css = this.SLDDoc.createElement('CssParameter');
		var fillAtt = this.SLDDoc.createAttribute('name');
		fillAtt.nodeValue=name;
		Css.setAttributeNode(fillAtt);
		var fillValue = this.SLDDoc.createTextNode(value);
		Css.appendChild(fillValue);
		return Css;
	};
   
	/**
	 * Return a new Rule with the given RuleName and a default 'PropertyIsEqualTo' with the given PropertyName aqual to ''
	 */
	this.addRule = function (RuleName, PropertyName){
		// implementation simple pour l'instant : on ne cree qu'un rule par defaut.
		var newRule = this.SLDDoc.createElement('Rule');
		this.SLDDoc.getElementsByTagName('FeatureTypeStyle').item(0).appendChild(newRule);
		
		var ruleName = this.SLDDoc.createElement('Name');
		newRule.appendChild(ruleName);
		
		var textNode = this.SLDDoc.createTextNode(RuleName);
		ruleName.appendChild(textNode);
		
		var FilterNode = this.SLDDoc.createElement('Filter');
		newRule.appendChild(FilterNode);
		
		var OpNode = this.SLDDoc.createElement('PropertyIsEqualTo');
		FilterNode.appendChild(OpNode);
		
		var PropertyNameNode = this.SLDDoc.createElement('PropertyName');
		OpNode.appendChild(PropertyNameNode);
		
		var PropertyText = this.SLDDoc.createTextNode(PropertyName);
		PropertyNameNode.appendChild(PropertyText);
		
		var LiteralNode = this.SLDDoc.createElement('Literal');
		OpNode.appendChild(LiteralNode);
		
		var LiteralText = this.SLDDoc.createTextNode('');
		LiteralNode.appendChild(LiteralText);
		
		return this.getRulesNamesWithIndex().length - 1;
   };

	/**
	 * Return a new Rule with a default layout (use the addRule function)
	 */
	this.buildNewRule = function(RuleName, PropertyName) {
		var newRuleIdx = this.addRule(RuleName,PropertyName);
		this.buildDefaultLayout(newRuleIdx);
		return newRuleIdx; 
	}

	/**
	 * Update a cssProperty 
	 * RuleIdx : Index of the Rule which contains the cssProperty
	 * SymbolizerSection : symbolzer name which contains the cssProperty
	 * CssPropertyName : the name the the CssParameter to update
	 * CssPropertyValue : the new value
	 */
	this.updateSymbolizer = function(RuleIdx, SymbolizerSection, CssPropertyName, CssPropertyValue) {
		var RuleToUpdate = this.SLDDoc.getElementsByTagName('Rule').item(RuleIdx);
		var symbolizerName = "";
        
		if (this.layerType == 'Point')
			symbolizerName = 'PointSymbolizer';
		else if(this.layerType == 'Line')
			symbolizerName = 'LineSymbolizer';
		else if (this.layerType == 'Polygon')
			symbolizerName = 'PolygonSymbolizer';
        
		var Symbolizer = RuleToUpdate.getElementsByTagName(symbolizerName).item(0);
		// parcours des differents noeuds nommes fill ou stroke, qu'on peut retrouver plusieurs fois 
        
		var elements = Symbolizer.getElementsByTagName(SymbolizerSection);
		var theProperty;
		for (i=0;i<elements.length;i++) {
			if ((elements[i].parentNode.tagName == symbolizerName)|| (elements[i].parentNode.tagName == 'Mark'))
			theProperty = elements[i];
        }
        if (theProperty == null) return;
        
		var CssNode = theProperty.getElementsByTagName('CssParameter');
		for (i=0;i<CssNode.length;i++) {
			var CssAttr = CssNode.item(i).getAttribute('name');
			if (CssAttr == CssPropertyName) {
				CssNode.item(i).firstChild.nodeValue = CssPropertyValue;
			}
		}
	}
   
	/**
	 * Return a cssProperty
	 * RuleIdx : Index of the Rule which contains the cssProperty
	 * SymbolizerSection : symbolzer name which contains the cssProperty
	 * CssPropertyName : the name the the CssParameter to return
	 */
	this.getSymbolizer = function(RuleIdx, SymbolizerSection, CssPropertyName) {
		var ccsval = '';
		var RuleToUpdate = this.SLDDoc.getElementsByTagName('Rule').item(RuleIdx);
		var symbolizerName = "";
        
        if (this.layerType == 'Point')
			symbolizerName = 'PointSymbolizer';
		else if(this.layerType == 'Line')
			symbolizerName = 'LineSymbolizer';
		else if (this.layerType == 'Polygon')
			symbolizerName = 'PolygonSymbolizer';
        
		var Symbolizer = RuleToUpdate.getElementsByTagName(symbolizerName).item(0);
		
		// parcours des differents noeuds nommes fill ou stroke, qu'on peut retrouver plusieurs fois 
		var elements = Symbolizer.getElementsByTagName(SymbolizerSection);
		var theProperty;
		for (i=0;i<elements.length;i++) {
			if ((elements[i].parentNode.tagName == symbolizerName) || (elements[i].parentNode.tagName == 'Mark'))
				theProperty = elements[i];
		}
		
		if (theProperty == null) return 0;
		var CssNode = theProperty.getElementsByTagName('CssParameter');
		for (i=0;i<CssNode.length;i++) {
			var CssAttr = CssNode.item(i).getAttribute('name');
			if (CssAttr == CssPropertyName) {
				ccsval = CssNode.item(i).firstChild.nodeValue;
			}
		}
		return ccsval;
	};
   
	/**
	 * Update the point Graphic by a PNG image url (default size is 30)
	 */
	this.setImageGraphic = function(RuleIdx, imageUrl) {
		var RuleToUpdate = this.SLDDoc.getElementsByTagName('Rule').item(RuleIdx);
		if (RuleToUpdate.getElementsByTagName('Graphic').length > 0) {
			GraphicNode = RuleToUpdate.getElementsByTagName('Graphic').item(0);
			if (RuleToUpdate.getElementsByTagName('Mark').length > 0) {
				GraphicNode.removeChild(RuleToUpdate.getElementsByTagName('Mark').item(0));  
			}
		}
		var extGraphNode = this.SLDDoc.createElement('ExternalGraphic');
		GraphicNode.appendChild(extGraphNode);
		
		var OnlineResNode = this.SLDDoc.createElement('OnlineResource');
		extGraphNode.appendChild(OnlineResNode);
        
		var hrefAtt = this.SLDDoc.createAttribute('href');
		hrefAtt.nodeValue='images/'+imageUrl;
		OnlineResNode.setAttributeNode(hrefAtt);
        
		var imageTypeNode = this.SLDDoc.createElement('Format');
		var typeValue = this.SLDDoc.createTextNode('image/png');
		imageTypeNode.appendChild(typeValue);
		GraphicNode.appendChild(imageTypeNode);
        
		var sizeNode = GraphicNode.getElementsByTagName('Size').item(0);
		sizeNode.nodeValue = '30';
	}
   
	/**
	 * Update the point Graphic by a wellknowname tag
	 */
	this.changePointGraphic = function(RuleIdx,newGraphicName){
		var RuleToUpdate = this.SLDDoc.getElementsByTagName('Rule').item(RuleIdx);
		if (RuleToUpdate.getElementsByTagName('WellKnownName').length > 0) {
			var WKN = RuleToUpdate.getElementsByTagName('WellKnownName').item(0);
			WKN.firstChild.nodeValue = newGraphicName;
		} else {
			// suppression du bloc definissant eventuellement une image
			if (RuleToUpdate.getElementsByTagName('Graphic').length > 0) {
				var graphicNode = RuleToUpdate.getElementsByTagName('Graphic').item(0);
				if (RuleToUpdate.getElementsByTagName('ExternalGraphic').length > 0) {
					graphicNode.removeChild(RuleToUpdate.getElementsByTagName('ExternalGraphic').item(0));  
				}

				// ajout du bloc pour le graphique
				var markNode = this.SLDDoc.createElement('Mark');
				graphicNode.appendChild(markNode);
				
				var Symbol = this.SLDDoc.createElement('WellKnownName');
				var SymbolName  = this.SLDDoc.createTextNode(newGraphicName);
				Symbol.appendChild(SymbolName);
				markNode.appendChild(Symbol);
	
				var fillNode = this.SLDDoc.createElement('Fill');
				markNode.appendChild(fillNode);
				fillNode.appendChild(this.buildCSSNode('fill','#0000FF'));
				var sizeNode = this.SLDDoc.createElement('Size');
				SizeValue = this.SLDDoc.createTextNode('10');
				sizeNode.appendChild(SizeValue);
				markNode.appendChild(sizeNode);
	
				var StrokeNode = this.SLDDoc.createElement('Stroke');
				markNode.appendChild(StrokeNode);
				StrokeNode.appendChild(this.buildCSSNode('stroke','#000000'));
				StrokeNode.appendChild(this.buildCSSNode('stroke-width','1'));
			}
		}
	};
   
	/**
	 * Return the point graphic of the given index Rule
	 */
	this.getPointGraphic = function(RuleIdx) {
		var RuleToUpdate = this.SLDDoc.getElementsByTagName('Rule').item(RuleIdx);
		if (RuleToUpdate.getElementsByTagName('WellKnownName').length > 0) {
			var WKN = RuleToUpdate.getElementsByTagName('WellKnownName').item(0);
			return WKN.firstChild.nodeValue;
		} else
			return "";
	}
	
	this.getPointGraphicType = function(RuleIdx) {
		var rule = this.SLDDoc.getElementsByTagName('Rule').item(RuleIdx);
		if (rule.getElementsByTagName('WellKnownName').length > 0) {
			return "WellKnownName";
		} else if (rule.getElementsByTagName('Graphic').length > 0){
			return "Graphic";
		} else {
			return "";
		}
	}

	/**
	 * Update the point graphic size of the given index Rule
	 */
	this.updateGraphicSize = function(RuleIdx, newSize) {
		var RuleToUpdate = this.SLDDoc.getElementsByTagName('Rule').item(RuleIdx);
		var SizeNode = RuleToUpdate.getElementsByTagName('Size').item(0);
		SizeNode.firstChild.nodeValue = newSize;
	};
   
	/**
	 * Return the point graphic size of the given index Rule
	 */
	this.getGraphicSize = function(RuleIdx) {
		var RuleToUpdate = this.SLDDoc.getElementsByTagName('Rule').item(RuleIdx);
		var SizeNode = RuleToUpdate.getElementsByTagName('Size').item(0);
		if (!SizeNode) {
			SizeNode = this.SLDDoc.createElement('Size');
			SizeNode.nodeValue = "10";
			RuleToUpdate.appendChild(SizeNode);
		}
		return SizeNode.firstChild.nodeValue;
	};
   
	/**
	 * Save the sld
	 */
	this.save = function(){
		var body = {
				method: "save",
				SLDBody: this.toString(),
				layerUUID: this.layerObj.selectSingleNode("wmc:Extension/wmc:Infoterre/wmc:UUID").firstChild.nodeValue,
				sldTitle: this.getNameValueForNode('UserStyle')
			}
		
		if (this.sldId != null && this.sldId != '') {
			body.sldUUID = this.sldId;
		}
	
		dojo.xhrPost({
			url: "sldControler",
			handleAs: "json",
			content: body,
			sync: true,
			load: function(response, ioArgs) { 
				SldDoc.sldId = response.sldId;
				this.url = response.fileName;
			},
			error: function(response, ioArgs) {
				console.error("HTTP status code: ", ioArgs.xhr.status);
			}
		});
	};
}
/**
 * Objet contenant le SLD en cours d'edition
 */
var SldDoc;
   
