#include "nVec.h"

nVec :: ~nVec()
{
#ifdef __SSE
	if(iType == nVT_copy && ppdDim) _aligned_free ( ppdDim );
#else
	if(iType == nVT_copy) delete [] ppdDim ;		// &&ppdDim checking isnt needed, since delete handles that
#endif
	lCDim = 0;
	ppdDim = 0;
}

nVec nVec :: operator +(const nVec &NParam){
	try{
		if(lCDim != NParam.lCDim){
			throw IncompatibleVectors();
		}
			nVec TmpVec(lCDim);
			TmpVec = *this;
			TmpVec+=NParam;
			return TmpVec;
	}
	catch(IncompatibleVectors IV){
		cerr << " 'IncompatibleVectors' thrown by + " << lCDim << " + " << NParam.lCDim <<" : "<< &NParam <<endl;
		throw(IV);
	}
	return 0;			// error if this is executed
}

nVec nVec :: operator -(const nVec &NParam){
	try{
		if(lCDim != NParam.lCDim){
			throw IncompatibleVectors();
		}
		nVec TmpVec(lCDim);
		TmpVec = *this;
		TmpVec-=NParam;
		return TmpVec;
	}
	catch(IncompatibleVectors IV){
		cerr << " 'IncompatibleVectors' thrown by - " << lCDim << " + " << NParam.lCDim << " : "<< &NParam <<endl;
		throw(IV);
	}
	return 0;			// error if this is executed
}

nVec nVec :: operator *(const nVec_var dParam){
	nVec TmpVec(lCDim);
	TmpVec = *this;
	TmpVec*=dParam;
	return TmpVec;
}

nVec nVec :: operator /(const nVec_var dParam){
	nVec TmpVec(lCDim);
	TmpVec = *this;
	TmpVec/=dParam;
	return TmpVec;
}

nVec_var nVec :: CBLength(void){
	nVec_var dtemp=0;
	long lschl;
	for(lschl=0;lschl < lCDim;lschl++){
		dtemp += ppdDim[lschl];
	}
	return dtemp;
}

int nVec :: Save(FILE *fhd){
	return fwrite(ppdDim,sizeof(nVec_var),lCDim,fhd);
}

int nVec :: Load(FILE *fhd){
	if(ppdDim) return fread(ppdDim,sizeof(nVec_var),lCDim,fhd);
	return false;
}

void nVec::testout(void){
	long lschl;
	for(lschl=0;lschl < lCDim;lschl++){
		cout <<ppdDim[lschl]<<" ";
	}
	cout << endl;
}

// global functions

nVec operator *(nVec_var dParam,nVec &nParam){
	return (nParam.operator *(dParam));
}

nVec  operator -(const nVec_var fValue, const nVec &NParam){
	nVec TmpVec(NParam.lCDim);
#ifdef __SSE
	__m128 m128_value;
	long lSize = __SSEOP(NParam.lCDim) ;
	__m128 *dest = (__m128*)TmpVec.ppdDim;
	__m128 *src = (__m128*)NParam.ppdDim;

	m128_value = _mm_set_ps1(fValue);

	for(; lSize; lSize--){
		*dest = _mm_sub_ps(m128_value,*src);

		dest ++;
		src ++;
	}
#else
	long lschl;
	for(lschl=0;lschl < NParam.lCDim;lschl++){
		TmpVec.ppdDim[lschl] = fValue-NParam.ppdDim[lschl];
	}
#endif
	return TmpVec;
}

