/**
 * @namespace
 * Class Layer
 * 
 * This class is intended to encapsulate all the methods and attributes of a Layer.
 * <br />
 * <br />
 * Created on 04/03/2009
 * 
 * @class Layer
 *
 * @property {number} id The id of the Layer
 * @property {string} owner The owner of the layer
 * @property {string} url The url of the image of the user
 * @property {string} title The title of the Layer
 * @property {string} description The description of the Layer, once published
 * @property {string} siteURL The URL where the Layer was created over
 * @property {string} visibility The visibility of the Layer. This can be
 * "public", "private" or "shared"
 * @property {string} creationDate The creation date of the Layer
 * @property {number} rate The rate of the Layer
 * @property {boolean} liked Whether the layer has been marked as liked by the current user
 * @property {boolean} reported Whether the layer has been reported by the current user 
 * @property {string} application The application id used to make the Layer. If multiple applications are used, no application will be set.
 * @property {string} ilink Identity which this layer is addressed to.
 * @property {string} llink Layer which this layer is a response to.
 * 
 * @author "Pablo Casado (pablo.casado@layers.com)"
 * @version <1.0>
 *  
 */
function Layer(){
	this._id = "";
	this._owner = "";
	this._ownerImage = "";
	this._ownerName = "";
	this._ownerFamilyName = "";
	this._title = STRING_layer_default_title;
	this._description = "";
	this._visibility = "";
	this._siteURL = os.getURL();
	this._publishDate = new Date();
	this._modDate = new Date();
	this._rate = "";
	this._liked = false;
	this._reported = false;
	this._application = "";
	this._group = "";
	this._corp = "";
	this._timesViewed = 0;
	this._data = {};
	this._comments = new Array();
	this._domain = "";
	this._ilink = "";
	this._llink = "";
	
	
	this._dirtyData = false;
	this._dirtyTitle = false;
	this._dirtyDescription= false;
}


Layer.prototype._id;
Layer.prototype._owner;
Layer.prototype._ownerImage;
Layer.prototype._ownerName;
Layer.prototype._ownerFamilyName;
Layer.prototype._title;
Layer.prototype._description;
Layer.prototype._siteURL;
Layer.prototype._visibility;
Layer.prototype._publishDate;
Layer.prototype._modDate;
Layer.prototype._rate;
Layer.prototype._liked;
Layer.prototype._reported;
Layer.prototype._application;	
Layer.prototype._data;
Layer.prototype._comments;
Layer.prototype._group;
Layer.prototype._corp;
Layer.prototype._timesViewed;
Layer.prototype._dirtyTitle;
Layer.prototype._dirtyData;
Layer.prototype._dirtyDescription;
Layer.prototype._domain;


/**
 * Parses a XML Document that contains a marshalled layer.
 * @memberOf Layer
 * @function
 * 
 * @param mydata An XML Document.
 * 
 * Created on 08/04/2009
 * @author Pablo Casado (pablo.casado@layers.com)
 * @version <1.0>
 * 
 * @return Layer
 * @throws {Exception} If there is an error when creating the Layer from the XML
 */
Layer.prototype.parse = function(mydata){
	if( mydata != undefined ){
		try{			
			this._id = mydata.getElementsByTagName("id")[0].childNodes[0].nodeValue;//.getElementsByTagName("id")[0].childNodes[0].nodeValue;
			this._owner = mydata.getElementsByTagName("owner")[0].childNodes[0].nodeValue;
			//this._ownerImage = mydata.getElementsByTagName("owner_image")[0].childNodes[0].nodeValue;
			
			//this._ownerImage = "http://www.layers.com/images/"+this._owner;
			
			this._siteURL = unescape(mydata.getElementsByTagName("site_URL")[0].childNodes[0].nodeValue);
	
			console.info(mydata.getElementsByTagName("title")[0].childNodes[0].nodeValue);
			this._title = htmlEntitiesDecodema(mydata.getElementsByTagName("title")[0].childNodes[0].nodeValue);
			
			console.info(this._title);
			
			// Layer owner name
			try{
				this._ownerName = mydata.getElementsByTagName("fname")[0].childNodes[0].nodeValue;
			}catch(e){
				this._ownerName = "";
			}
			
			// Layer owner family name
			try{
				this._ownerFamilyName = mydata.getElementsByTagName("sname")[0].childNodes[0].nodeValue;
			}catch(e){
				this._ownerFamilyName = "";
			}
			
			// Layer rate
			try{
				this._rate = mydata.getElementsByTagName("rate")[0].childNodes[0].nodeValue;	
			}catch(e){
				this._rate = 0;
			}
			
			// Layer liked
			try{
				this._liked = mydata.getElementsByTagName("liked")[0].childNodes[0].nodeValue;
				if (this._liked == 'true') this._liked = true;
				else this._liked = false;				
			}catch(e){
				this._liked = false;
			}
			
			// Layer reported
			try{
				this._reported = mydata.getElementsByTagName("reported")[0].childNodes[0].nodeValue;
				if (this._reported == 'true') this._reported = true;
				else this._reported = false;				
			}catch(e){
				this._reported = false;
			}
			
			// Layer applications
			try{
				var apps = mydata.getElementsByTagName("applications");				
				if ( apps.length == 1 ){					
					this._application = apps[0].getElementsByTagName("id")[0].childNodes[0].nodeValue;					
				}
			}catch(e){
				this._application = "";
			}
			
			// Layer group
			try{
				this._group = myData.getElementsByTagName("group")[0].childNodes[0].nodeValue;
			}catch(e){
				this._group = "";
			}
			
			// Layer corporate domain			
			try{
				this._corp = myData.getElementsByTagName("domain")[0].childNodes[0].nodeValue;
			}catch(e){
				this._corp = "";
			}
			
			// Layer visibility			
			try{
				this._visibility = mydata.getElementsByTagName("visibility")[0].childNodes[0].nodeValue;
			}catch(e){				
				this._visibility = "";
			}
			
			// Layer times viewed
			try{
				this._timesviewed = mydata.getElementsByTagName("timesviewed")[0].childNodes[0].nodeValue;
			}catch(e){
				this._timesviewed = "";
			}
			
			// Layer published date
			try{
				this._publishDate.setISO8601( mydata.getElementsByTagName("publishdate")[0].childNodes[0].nodeValue );
			}catch(e){
				this._publishDate = "";
			}			
			
			// Layer modification date
			try{
				this._modDate.setISO8601( mydata.getElementsByTagName("moddate")[0].childNodes[0].nodeValue );
			}catch(e){
				this._modDate = "";
			}
			
			// Layer description
			try{
				this._description = htmlEntitiesDecodema(mydata.getElementsByTagName("description")[0].childNodes[0].nodeValue);
			}catch(e){
				this._description = "";
			}
			
			// Identity this layer is addressed to.
			try{
				this._ilink = mydata.getElementsByTagName("ilink")[0].childNodes[0].nodeValue;
			}catch(e){
				this._ilink = "";
			}			
			
			// Layer this layer is responding to.
			try{
				this._llink = mydata.getElementsByTagName("llink")[0].childNodes[0].nodeValue;
			}catch(e){
				this._llink = "";
			}	
			
			// Layer siteURL domain
			var result = this._siteURL;
			var e=/^((http|ftp):\/)?\/?([^:\/\s]+)((\/\w+)*\/).*$/;

		    if (this._siteURL.match(e)) {
				result = RegExp.$3; // host:RegExp.$3,
		    }
			this._domain = result;
			
			// Layer objects
			try{
				var tmp = mydata.getElementsByTagName("object");
				var i = 0;
				while (i < tmp.length){
					try{
						var tmpObject = new LayersObject();
						tmpObject.parse(tmp[i]);
						
						this._data[tmpObject._application] = tmpObject;
						
						if ( this._application != tmpObject._application && this._application != "" ){
							this._application = "";
						}else{
							this._application = tmpObject._application;
						}
					}catch(e){
						console.error(e);
						//DO nothing
					}
					
					i = i + 1;
				}
				
			}catch(e){
				console.error(e);
				//DO NOTHING!!!
			}
			
			// Layer comments
			try{
				var tmp = mydata.getElementsByTagName("comment");				
				
				var i = 0;
				while (i < tmp.length){
					try{
						this._comments[i] = new Comment().parse(tmp[i]);
					}catch(e){
						console.error(e);
						//DO nothing
					}
					
					i = i + 1;
				}
				
			}catch(e){
				console.error(e);
				//DO NOTHING!!!
			}
						
			this._dirtyData = false;
			this._dirtyDescription = false;
			this._dirtyTitle = false;
			
			//console.info(this);
						
			return this;
			
		}catch(e){
			throw e;
		}
	}else{
		throw new Exception("Error creating Layer from XML");
	}
}


/**
 * getDomainURL
 * 
 * returns the domain where the Layer was created
 * 
 * @memberOf Layer
 * @function
 *
 * Created on 02/06/2009
 * @author "Rodrigo Pérez"
 * @version <1.0>
 * 
 * @return {String} the domain of an URL
 * 
 */
Layer.prototype.getDomain = function(){
	return this._domain;
}

/**
 * getLayerPublishDate
 * 
 * 
 * returns the layer's published date in string format
 * 
 * @memberOf Layer
 * @function
 *
 * Created on 15/07/2009
 * @author "Antonio Perez"
 * @version <2.0>
 * 
 * @return {String} the string representation of the layer's published date
 * 
 */
Layer.prototype.getLayerPublishDate = function(){
	
	var dateString = "";
	
	try {
		dateString = this._publishDate.toDateString();	
	}catch(e){
		return dateString;
	}
	return dateString;
}


/**
 * getApplicationIcon
 * 
 * returns the URL of the icon of the application that was used to create the layer
 * Hard-coded style for this function. Please refactor mercilessly!!!!!!
 * 
 * @memberOf Layer
 * @function
 *
 * @author "Pablo Casado"
 * @version <1.0>
 * 
 * @return {String} An URL
 * 
 */
Layer.prototype.getApplicationIcon = function(){
	
	if(this._application == ""){
		res = "img/ico_multi.gif";
	}else{
		res = "/apps/"+this._application+"/css/images/"+this._application.toLowerCase()+"_ico.gif";
	}
	
	return res;	
}



/**
 * setId
 * 
 * @param {Number} Id The identifier of the Layer
 * 
 * @memberOf Layer
 * @function
 * 
 * Created on 08/04/2009
 * @author Pablo Casado (pablo.casado@layers.com)
 * @version <1.0>
 */
Layer.prototype.setId = function(anId) {
	this._id = anId;
}



/**
 * getId
 * 
 * @returns {Number} The identifier of the Layer
 * 
 * @memberOf Layer
 * @function
 *
 * Created on 08/04/2009
 * @author Pablo Casado (pablo.casado@layers.com)
 * @version <1.0>
 */
Layer.prototype.getId = function() {
	return this._id;
}



/**
 * setTitle
 * 
 * @param {String} Title The new title of the Layer
 * 
 * @memberOf Layer
 * @function
 *
 * Created on 08/04/2009
 * @author Pablo Casado (pablo.casado@layers.com)
 * @version <1.0>
 */
Layer.prototype.setTitle = function(aTitle) {
	this._title = aTitle;
	this._dirtyTitle = true;
}


/**
 * getTitle
 * 
 * @returns {String} The Title of the Layer
 * 
 * @memberOf Layer
 * @function
 *
 * Created on 08/04/2009
 * @author Pablo Casado (pablo.casado@layers.com)
 * @version <1.0>
 */
Layer.prototype.getTitle = function() {
	return this._title;
}


/**
 * setDescription
 * 
 * @param {String} Title The new description of the Layer
 * 
 * @memberOf Layer
 * @function
 *
 * Created on 08/04/2009
 * @author Pablo Casado (pablo.casado@layers.com)
 * @version <1.0>
 */
Layer.prototype.setDescription = function(aDescription) {
	this._description = aDescription;
	this._dirtyDescription = true;
}


/**
 * getDescription
 * 
 * @returns {String} The description of the Layer
 * 
 * @memberOf Layer
 * @function
 */
Layer.prototype.getDescription = function() {
	return this._description;
}



/**
 * setObject
 * 
 * @param {Object} object The object to be appended
 * 
 * @memberOf Layer
 * @function
 * 
 * Created on 14/05/2009
 * @author Pablo Casado (pablo.casado@layers.com)
 * @version <1.0>
 */
 Layer.prototype.setObject = function(appName, data){
	this._data[appName] = data;
	this._dirtyData = true;
 }



 
/**
 * appendObject
 * 
 * @param {Object} object The object to be appended
 * 
 * @memberOf Layer
 * @function
 * 
 * Created on 14/05/2009
 * @author Pablo Casado (pablo.casado@layers.com)
 * @version <1.0>
 */
 Layer.prototype.appendObject = function(data){
	console.info("Layer.prototype.appendObject");
	console.info(data);
	this._data.push(data);
	this._dirtyData = true
	console.info(this._data)
 }
 

/**
 * getObjects
 * 
 * @return {Array} objects The objects contained in the Layer
 * 
 * @memberOf Layer
 * @function
 * 
 * Created on 15/07/2009
 * @author Pablo Casado (pablo.casado@layers.com)
 * @version <1.0>
 */
 Layer.prototype.getObjects = function(object){
	 return this._data;
 }


/**
 * isPublished
 * 
 * @memberOf Layer
 * @function
 * 
 * Created on 26/05/2009
 * @author "Rodrigo Perez (rodrigo@agenciadigital.es)"
 * @version <1.0>
 * 
 * @return {Boolean} return true if visibility is equal to public, false otherwise
 * 
 */
 Layer.prototype.isPublished = function(){
	 return (this._visibility == 'public');
 }
 
 
 /**
  * deleteObject
  * 
  * Removes the object received as an argument from the objects array and
  * compacts the array. 
  * 
  * 
  * Created on 14/05/2009
  *
  * @param {Object} object The object to be removed
  * 
  * @memberOf Layer
  * @function
  * 
  * @author Pablo Casado (pablo.casado@layers.com)
  * @version <1.0>
  * 
  */
  Layer.prototype.deleteObject = function(object){
	  indexOfObject = this._data.indexOf(object);
	  this._data[indexOfObject] = "DELETED";
  }
 


/**
 * toXML
 * 
 * @returns {String} The description of the layer
 * 
 * @memberOf Layer
 * @function
 * 
 * @author Pablo Casado (pablo.casado@layers.com)
 * @version <1.0>
 *
 */
Layer.prototype.toXML = function(){
		
	xmlStr = "";//"<xml version='1.0' encoding='utf-8'>";
	
	if(this._id == undefined || this._id == ""){
		xmlStr = xmlStr + "<layer>";
	}else{
		xmlStr = xmlStr + "<layer lid='"+this._id+"'>";
	}
		
	//if(this._dirtyTitle){
		//Title has been modified
		//xmlStr = xmlStr +"<ltitle>"+htmlEntitiesEncode(this._title)+"</ltitle>";
		xmlStr = xmlStr +"<ltitle>"+this._title+"</ltitle>";
		//console.info("<ltitle>"+this._title+"</ltitle>");
	//}
	
	if(this._id != undefined || this._id == ""){
		//Creation of a layer -> siteURL
		xmlStr = xmlStr +"<url>"+escape(this._siteURL)+"</url>";
	}
	
	if(this._dirtyDescription){
		// Description has been changed
		//xmlStr = xmlStr +"<description>"+htmlEntitiesEncode(this._description)+"</description>";
		xmlStr = xmlStr +"<description>"+this._description+"</description>";
	}
	
	
	if(this._group != undefined && this._group != ""){
		//Creation of a layer -> Layer belongs to a group
		xmlStr = xmlStr +"<group>"+this._group+"</group>";
	}
	
	if(this._ilink != undefined && this._ilink != ""){
		//Creation of a layer -> Layer is addressed to an identity
		xmlStr = xmlStr +"<ilink>"+this._ilink+"</ilink>";
	}
	
	if(this._llink != undefined && this._llink != ""){
		//Creation of a layer -> Layer is a response to another layer
		xmlStr = xmlStr +"<llink>"+this._llink+"</llink>";
	}
	
	
	if(this._dirtyData){
		
		var globalObjXML = "<objects>";
		var i = 0;
		/*
		while(i < this._data.length){
			if(this._data[i] == null || this._data[i] == "DELETED"){
				globalObjXML = globalObjXML + "<object "+this._data[i]._id+" delete='true'>";				
			}else{
				globalObjXML = globalObjXML + this._data[i].toXML();
			}
			i++;
		}*/
		
		for(appName in this._data){
			if(this._data[appName] == null || this._data[appName] == "DELETED"){
				globalObjXML = globalObjXML + "<object "+this._data[appName]._id+" delete='true'>";				
			}else{
				globalObjXML = globalObjXML + this._data[appName].toXML();
			}
		}
		
		xmlStr =  xmlStr + globalObjXML + "</objects>";
	}
	
	xmlStr = xmlStr + "</layer>";
	return xmlStr;
}

Layer.prototype.getObjects = function(){
	return this._data;
}


