/**
 * @namespace
 * Class LayerIterator
 * <br />
 * This class is intended to encapsulate all the methods and attributes of a Layer.
 * @class LayerIterator
 * 
 *
 * @property {number} _referal Who is responsible to solve the calls that this
 * object shall make to the server. Must be a LayersOSWSProxy object
 * @property {number} _index The index of the current layer
 * @property {number} _type A number that identifies uniquely the name of the
 * function that was called and returned this iterator. <br /><br />
 * 0 = getLayers<br />
 * 1 = getMyLayers<br />
 * 2 = getLayersOverThisPage<br />
 * 3 = getLayersOverThisPageByMyFriends<br />
 * ...<br />TO DO<br /><br />
 * @property {number} _page The page that has been returned by the server
 * @property {number} _count The number of layers in the Iterator
 * @property {number} _identity The identity whose layers are wanted to be
 * returned.
 * @property {Array} _layersArray The Layers in the Iterator
 * 
 * Created on 04/03/2009
 * @author "Pablo Casado (pablo.casado@layers.com)"
 * @version <1.0>
 *  
 **/
function LayerIterator(referal){
	this._referal = referal;
	this._type = 0;
	this._index = 0;
	this._from = 1;
	this._to = 30;
	this._count = 0;
	this._identity = 0;
	this._layersArray = new Array();
	this._isRetrieving = false;
}


LayerIterator.prototype._referal; // must be a LayersOSWSProxy object
LayerIterator.prototype._type;
LayerIterator.prototype._index;
LayerIterator.prototype._from;
LayerIterator.prototype._to;
LayerIterator.prototype._count;
LayerIterator.prototype._identity;
LayerIterator.prototype._layersArray;
LayerIterator.prototype._isRetrieving;



/**
 * parse
 * 
 * This function returns a user from an XMLDocument returned by the server. It parses the XML received and
 * assign all the fields to the attributes of a user.
 *
 * Created on 04/03/2009
 * @author "Pablo Casado (pablo.casado@layers.com)"
 * @version <version>
 * 
 * @memberOf LayerIterator
 * @function
 * 
 * @param {mydata} XMLDocument An XMLDocument previously constructed by the makeRequest function of the WSProxy class
 *
 * @return {User} A User object
 * 
 * @throws {Exception} If an error occurred when creating the object from XML.
 **/
LayerIterator.prototype.parse = function(mydata){
	try{
		myLayerIterator = mydata.getElementsByTagName("layerIterator")[0];
		
		if(myLayerIterator != undefined){
	
			try{
				this._count = parseInt(myLayerIterator.getElementsByTagName("count")[0].childNodes[0].nodeValue);
			}catch(e){
				//Do nothing
			}			
			
			/*
			try{
				this._page = myLayerIterator.getElementsByTagName("page")[0].childNodes[0].nodeValue;				
			}catch(e){
				this._page = 0;
			}
			*/
			this._page = 0;
			

			try{
				var tmp = myLayerIterator.getElementsByTagName("layer");
				
				var i = 0;
				while (i < tmp.length){
//console.info(tmp[i]);
					try{
						this._layersArray[i] = new Layer().parse(tmp[i]);
					}catch(e){
						console.error(e);
					}
					i = i + 1;
				}
			}catch(e){
				console.error(e);
				throw e;
			}

		}else{
			throw new Exception().parse(mydata);
		}		
				
		return this;
		
	}catch(e){
		throw e;
	}
}



/**
 * hasNextLayer
 * 
 * @memberOf LayerIterator
 * @function
 * 
 * @return {Boolean} A Boolean indicating if there are any more Layers in the
 * iterator
 **/
LayerIterator.prototype.hasNextLayer = function(){
	if(this._index == 0 && this._layersArray.length == 1){
		return true;
	}else {
		if(this._index+1 <= this._count){
			return true;
		}else{
			return false;
		}
	}
	
}



/**
* first
* <br /><br />
* Updates the current position of the iterator to the first position and returns
* the element at this position.
* 
* @memberOf LayerIterator
* @function
* 
**/
LayerIterator.prototype.first = function(){
	 this._index = 0;
	 return this._layersArray[0];
}




/**
 * getElementAt
 * <br /><br />
 * This function has been created in order to access an element in the iterator
 * as it were a direct access data structure. It updates the current position
 * of the iterator to that which was requested, so a call to hasNextLayer is
 * extremely recommended after calling this function.
 * 
 * @memberOf LayerIterator
 * @function
 * 
 * @throws {Exception} If there the requested position of the iterator does not
 * exist.
 * 
 **/
 LayerIterator.prototype.getElementAt = function(position){
	 this._index = position;
	 return this._layersArray[this._index];
 }
 
 
 

/**
 * getList
 * <br /><br />
 * Return the array that contains all the layers of the Layer Iterator, as it
 * is in the current state.
 * 
 * @memberOf LayerIterator
 * @function
 * 
 * @return {Array} An Array containing all the objects of the LayerIterator
 * in its current state.
 **/
LayerIterator.prototype.getList = function(){
	  return this._layersArray;
}
 

 

/**
 * endGetNextPage
 * <br /><br />
 * Callback function for getNextPage call. It updates the state of the iterator
 * with the information retrieved from the server.
 * 
 * @memberOf LayerIterator
 * @function
 * 
 **/
LayerIterator.prototype.endGetNextPage = function(){
	try{
		layers = new LayerIterator(this._referal).parse(data);
		this._layersArray = this._layersArray.concat(layers.getList());
		this._count = layers._count;
		this._page = layers._page;
		this._isRetrieving = false;
	}catch(e){
		console.info(e.msg);
		throw e;
	} 
}
 
 

/**
 * getNextPage
 * <br /><br />
 * Private function that calls the correct method of the server in order to get
 * the next page (X layers) of the iterator.
 * 
 * @memberOf LayerIterator
 * @function
 *
 **/
LayerIterator.prototype.getNextPage = function(){
	
	this._isRetrieving = true;
	var secondPart = "";
	
	switch(this._type){
	 	case 0: // OK
	 		//getLayersOverThisPage
	 		protocol = "POST";
	 		secondPart = "Sites/";
	 		break;
	 	case 1: //OK
	 		//getMyLayersOverThisPage
	 		protocol = "POST";
	 		secondPart = "SitesMyLayers/";
	 		break;
	 	case 2: //OK
	 		//getLayersByMyFriends
	 		protocol = "GET";
	 		secondPart = "FriendsLayers/";
	 		break;
	 	case 3: //OK
	 		//getLayersOverThisPageByMyFriends
	 		protocol = "POST";
	 		secondPart = "SitesFriends/";
	 		break;
		case 4: //OK
	 		//getLayersOverThisPageByMyFriends
	 		protocol = "POST";
	 		secondPart = "SitesNotFriends/";
	 		break;
	 	default:
	 		break;
	 }
	 
	
	if(os._bgUrl_is_layers){
		
		xmlStr = "<xml version='1.0' encoding='utf-8'><layersListRequest>";

		if(this._identity != ""){
			xmlStr = xmlStr+"<user>"+this._id+"</user>";
		}

		xmlStr = xmlStr+"<page>"+this._page+"</page>" +
			"<order>"+this._order+"</order>" +
			"</layersListRequest>";
			
		data = this._referal.makeRequest(protocol, layersOS_spm_site+"services/"+secondPart+os.getBackgroundURL(), "", this.endGetNextPage);
		
		 if (data == undefined){
			 throw new Exception("");
		 }else{
			 return data;
		}
	}else{
		this._to = this._to + 30;
		this._from = this._from + 30;
		
		this._referal.makeAsyncRequest(layersOS_spm_site+"cobrand/"+secondPart+this._from+"/"+this._to, os.getBackgroundURL() );
	}
	
	
}
 
 


/**
 * nextLayer
 * <br /><br />
 * Returns the next Layer in the iterator
 * 
 * @memberOf LayerIterator
 * @function
 * 
 * @return {Layer} The next Layer in the iterator
 * @throws {Exception} If there is not any next layer (last position of the
 * iterator).
 **/
LayerIterator.prototype.nextLayer = function(){	
	var tmpLayer = this._layersArray[this._index];
		
	this._index = this._index + 1;
	if( this.hasNextLayer() && tmpLayer == undefined){		
		this.getNextPage();
	}else{
		return tmpLayer;
	}	
}




/**
 * previousLayer
 * <br /><br />
 * Returns the previous Layer in the iterator
 * 
 * @memberOf LayerIterator
 * @function
 * 
 * @return {Layer} The next Layer in the iterator
 * @throws {Exception} If there is not any previous layer (first position of the
 * iterator).
 **/
LayerIterator.prototype.previousLayer = function(){
	this._index = this._index - 1;
	return this._layersArray[this._index];
}



