#ifndef __PITERATOR_IMPL_H__
#define __PITERATOR_IMPL_H__

#include "PIterator.h"

///constructeur de PIterator
template <class T>
PIterator<T>::PIterator(){
	p_element = NULL;
}

///constructeur de PIterator
/**	@param element : pointeur vers le PElement qu'il devra gérer
*/
template <class T>
PIterator<T>::PIterator(PElement<T>* element){
	p_element = element;
}

///Constructeur de copie du PIterator
/**	@param it : PIterator que l'on veut copier
*/
template <class T>
PIterator<T>::PIterator(const PIterator<T> & it){
	copyPIterator(it);
}

///destructeur de PIterator
template <class T>
PIterator<T>::~PIterator(){}

///Définition de l'operateur = du PIterator
/**	@param it : PIterator que l'on veut copier
 * 	@return PIterator copié
*/
template <class T>
typename PIterator<T>::PIterator & PIterator<T>::operator = (const PIterator<T> & it){
	copyPIterator(it);
	return *this;
}

///définition de l'opérateur += du PIterator
/**	@param nb : nombre de PElement dont on désir avancer le PIterator
 * 	@return PIterator qui a avancé de nb
*/
template <class T>
typename PIterator<T>::PIterator & PIterator<T>::operator += (int nb){
	next(nb);
	return *this;
}

///définition de l'opérateur -= du PIterator
/**	@param nb : nombre de PElement dont on désir reculer le PIterator
 * 	@return PIterator qui a reculé de nb
*/
template <class T>
typename PIterator<T>::PIterator & PIterator<T>::operator -= (int nb){
	prev(nb);
	return *this;
}

///Définition de l'opérateur ++ du PIterator (++it)
/**	@return PIterator qui a avancé d'un PElement
 * 	C'est l'opérateur ++it et pas it++ (Attention)
*/
template <class T>
typename PIterator<T>::PIterator & PIterator<T>::operator ++ (){
	next();
	return *this;
}

///définition de l'opérateur ++ du PIterator (it++)
/**	@param nb : nombre de PElement dont on désir avancer le PIterator
 * 	@return PIterator qui a avancé de nb
 * 	Celui là c'est l'opérateur it++, et ce qui est n'importe quoi c'est que nb ne sert qu'a différentier le ++it du it++, c'est tout
*/
template <class T>
typename PIterator<T>::PIterator & PIterator<T>::operator ++(int nb){
	next();
	return *this;
}

///définition de l'opérateur -- du PIterator (--it)
/**	@return PIterator qui a reculé d'un PElement
 * 	C'est l'opérateur --it et pas it-- (Attention)
*/
template <class T>
typename PIterator<T>::PIterator & PIterator<T>::operator -- (){
	prev();
	return *this;
}

///définition de l'opérateur -- du PIterator (it--)
/**	@param nb : nombre de PElement dont on désir reculer le PIterator
 * 	@return PIterator qui a reculé de nb
 * 	Celui là c'est l'opérateur it--, et ce qui est n'importe quoi c'est que nb ne sert qu'a différentier le --it du it--, c'est tout
*/
template <class T>
typename PIterator<T>::PIterator & PIterator<T>::operator -- (int nb){
	prev();
	return *this;
}

///définition de l'opérateur ->
/**	@return pointeur vers la donnée du PElement dont le PIterator à le pointeur
*/
template <class T>
T* PIterator<T>::operator -> () const{
	if(p_element == NULL) return NULL;
	return &(p_element->p_data);
}

///Définition de l'opérateur *
/**	@return valeur de la donnée du PElement sur lequel pointe le PIterator
*/
template <class T>
T & PIterator<T>::operator* () const{
	return p_element->p_data;
}

///fonction qui permet de faire avancer d'un PElement le PIterator
template <class T>
void PIterator<T>::next(){
	if(p_element == NULL) return;
	p_element = p_element->p_next;
}

///fonction qui permet de faire avancer le PIterator de nb PElement
/**	@param nb : nombre de PElement dont on veut faire avancer le PIterator
*/
template <class T>
void PIterator<T>::next(int nb){
	for(int i(0); i < nb; i++) next();
}

///fonction qui permet de faire reculer d'un PElement le PIterator
template <class T>
void PIterator<T>::prev(){
	if(p_element == NULL) return;
	p_element = p_element->p_prev;
}

///fonction qui permet de faire reculer le PIterator de nb PElement
/**	@param nb : nombre de PElement dont on veut faire reculer le PIterator
*/
template <class T>
void PIterator<T>::prev(int nb){
	for(int i(0); i < nb; i++) prev();
}

///Fonction de copie du PIterator
/**	@param it : PIterator que l'on veut copier
*/
template <class T>
void PIterator<T>::copyPIterator(const PIterator<T> & it){
	p_element = it.p_element;
}


#endif



