#ifndef _XMLLIGHT_VECTOR_
#define _XMLLIGHT_VECTOR_

#include "Behavioural/include/XMLLightFunctors.h"
#include <vector>
#include <algorithm>
#include <iostream>

using std::basic_ostream;
using std::basic_ios;
using std::endl;

namespace morpheo {
	namespace XMLUtils {
	
	//********************************************Class Declaration***************************************//
	
		// an helper class to handle XMLLight * vector 
		template < typename XMLLightImpl>
		class XMLLightVector : public std::vector<XMLLightImpl *> {
		public : 
			inline explicit XMLLightVector(void); 
			inline ~XMLLightVector(void); 
			
			XMLLightVector(const XMLLightVector & xmlLightVectorCopied); 
			XMLLightVector & operator= ( const XMLLightVector & copy ); 

			// must be defined inside template class declaration 
			template < typename charT, typename traits> friend 
			basic_ostream<charT, traits> & operator<< 
			( basic_ostream<charT, traits> & os , const XMLLightVector<XMLLightImpl> & vect) {
				if ( vect.size() == 0 ) {
					os << "There's no Child Nodes " << endl ; 
				} else {
					for (  unsigned int i = 0 ; i < vect.size() ; ++i ) {
						os <<"Nodes "<< i << ": \n\t" <<  vect[i] ->getInternalString()  << endl; 
					}
				}
				return os;   
			}
			
		};
		
	//******************************************Inline implementation************************************//

		template< typename T > class XMLLightDeleter;

		template < typename XMLLightImpl > 
		XMLLightVector<XMLLightImpl>::XMLLightVector() {
		}				
	
		template < typename  XMLLightImpl >
		XMLLightVector< XMLLightImpl>::~XMLLightVector(void) {
			transform ( this -> begin(), this -> end(), this -> begin(), XMLLightDeleter<XMLLightImpl>() );
		}

	//**************************************** template implementation*******************************//

		template < typename XMLLightImpl >
		XMLLightVector<XMLLightImpl>::XMLLightVector(const XMLLightVector<XMLLightImpl> & copy ) {
			for ( unsigned int i = 0 ; i < copy.size() ; ++i ) {
				this -> push_back(copy[i]);
				copy[i] -> attach(); 
			}
		}	

		template < typename XMLLightImpl >
		XMLLightVector<XMLLightImpl> & XMLLightVector<XMLLightImpl>::operator= ( const XMLLightVector<XMLLightImpl> & vector ) {
			if ( &vector != this ) {
				unsigned int this_size = this -> size();
				unsigned int copy_max_size = vector.size();
				unsigned int max_size = copy_max_size < this_size ? this_size : copy_max_size;
				for ( unsigned int i = 0 ; i < max_size ; ++i ) {
					if (  this_size ) {
						(*this)[i] -> detach();
					}
					if ( i < copy_max_size ) {
					 	if ( this_size == 0 ) {
							this -> push_back(vector[i]);
						} else {
							(*this)[i] = vector[i]; 
						}
						(*this)[i] -> attach();
					} else {
						(*this)[i] = NULL; 
					}
				}
			}	
			return *this;
		}

	}// end of XMLUtils namespace 
} // end of morpheo namespace 

#endif // _XMLLIGHT_VECTOR_
