#include <origin.h>

/**
		Origin C function to demonstrate Code Builder debugger.
	Returns:
		Returns 0.
*/
int DebugTutorial()
{
	// *** Declare and initialize variables and vectors ***
	double dDelta, dTol;
	dTol = 0.05;
	
	int i1, i2;
	BOOL bVectorIsUniform;
	
	vector vUniform = {-10,-9,-8,-7,-6,-5,-4,-3,-2,-1,0,1,2,3,4,5,6,7,8,9,10};
	vector vNotUniform, vWithinTolerance;

	vNotUniform = vUniform;
	vNotUniform[3] = -10;

	vWithinTolerance = 	vUniform;
	vWithinTolerance[3] = -7.01;
	
	// *** Check vectors for uniform spacing ***
	// Check vUniform
	i1 = 0;
	i2 = vUniform.GetSize() - 1; // O based indices...from 0 to N - 1
	bVectorIsUniform = VectorHasUniformSpacing( dDelta, vUniform, dTol, i1, i2 );

	// Check vNotUniform
	i1 = 0;
	i2 = vNotUniform.GetSize() - 1; // O based indices...from 0 to N - 1
	bVectorIsUniform = VectorHasUniformSpacing( dDelta, vNotUniform, dTol, i1, i2 );

	// Check vWithinTolerance
	i1 = 0;
	i2 = vWithinTolerance.GetSize() - 1; // O based indices...from 0 to N - 1
	bVectorIsUniform = VectorHasUniformSpacing( dDelta, vWithinTolerance, dTol, i1, i2 );
	
	return 0;
}


/**
		Determine whether or not the specified elements of a vectorbase derived object are uniformly
		spaced.
	Parameters:
		dDelta=Output difference between elements if uniform spacing else 0.0
		vIn=Input vectorbase derived object
		dTol=Input relative tolerance between 0 and 1
		i1=Input beginning 0 based index of vector to test
		i2=Input ending 0 based index of vector to test
	Return:
		Returns TRUE and NANUM if only one element is tested, returns TRUE and the difference between the first
		two elements tested if the spacing is uniform, returns FALSE and the difference between the first two
		elements tested if the spacing is not uniform, or returns FALSE and NANUM if there is an error.
*/
BOOL VectorHasUniformSpacing( double& dDelta, vectorbase& vIn, double dTol, int i1, int i2 )
{
	int ii;
	double dDeltaLo, dDeltaHi, dDeltaCur;

	dDelta = NANUM;                             // Initialized value
	
	if( i2 == -1 )                              // If default i2 loop to end of vector
		i2 = vIn.GetSize() - 1;
	
	if( dTol < 0.0 || dTol > 1.0 )              // If relative tolerance is not between 0 and 1 return FALSE and NANUM
		return FALSE;
	
	if( i1 < 0 || i2 < i1  || i2 >= vIn.GetSize() ) // If vector indices are illogical return FALSE and NANUM
		return FALSE;

	if( i1 == i2 )                              // If only testing one element return TRUE and NANUM
		return TRUE;
	
	dDelta = vIn[i1] - vIn[ i1 + 1 ];           // Get delta between first two elements
	if( dDelta < 0 )                            // If dDelta is negative...
	{
		dDeltaLo = ( 1.0 + dTol ) * dDelta;     // Compute lower absolute dDelta from relative tolerance
		dDeltaHi = ( 1.0 - dTol ) * dDelta;     // Compute higher absolute dDelta from relative tolerance
	}
	else                                        // Else if dDelta is not negative...
	{
		dDeltaLo = ( 1.0 - dTol ) * dDelta;     // Compute lower absolute dDelta from relative tolerance
		dDeltaHi = ( 1.0 + dTol ) * dDelta;     // Compute higher absolute dDelta from relative tolerance
	}

	for( ii = i1 + 1; ii < i2; ii++ )           // For each element in specified range of vector...
	{
		dDeltaCur = vIn[ii] - vIn[ ii + 1 ];    // Get absolute delta between current and next element 
		if( dDeltaCur < dDeltaLo || dDeltaCur > dDeltaHi ) // If current absolute delta is not within tolerance... 
			return FALSE;                       // Elements of vector not uniformly spaced
	}
	
	return TRUE;                                // Elements of vector are uniformly spaced (within tolerance)
}