/**********************************************************************************
* AUTHOR		: Bharath A.
* DATE			: 03-SEP-2007
* NAME			: affineTransform
* DESCRIPTION	: scales the tracegroup according to the x and y scale factors.
*				  After scaling, the "referenceCorner" of the tracegroup is translated to
*				  (translateToX,translateToY)
* ARGUMENTS		: xScaleFactor - factor by which x dimension has to be scaled
*				  yScaleFactor - factor by which y dimension has to be scaled
*				  referenceCorner - corner to be retained after scaling and moved to (translateToX,translateToY)
* RETURNS		: SUCCESS on successful scale operation
* NOTES			:
* CHANGE HISTROY
* Author			Date				Description of change
*************************************************************************************/
int LTKTraceGroup::affineTransform(float xScaleFactor,float yScaleFactor,
								   float translateToX,float translateToY,
								   TGCORNER referenceCorner)
{
	LOG( LTKLogger::LTK_LOGLEVEL_DEBUG) <<
		"Enter: LTKTraceGroup::translateTo()"<<endl;

	LTKTrace trace;

	vector<LTKTrace> scaledTracesVec;	// holds the scaled traces

	floatVector scaledXVec;				//	scaled x channel values of a trace
	floatVector scaledYVec;				//	scaled y channel values of a trace

	float x, y;
	float xReference, yReference;
	float xMin=0.0f;
	float yMin=0.0f;
	float xMax=0.0f;
	float yMax=0.0f;

	int traceIndex, index;
	int errorCode;
	int numPoints;

	if(xScaleFactor <= 0)
	{
		LOG( LTKLogger::LTK_LOGLEVEL_ERR) <<
        "Error: "<<EINVALID_X_SCALE_FACTOR <<": "<<
		getErrorMessage(EINVALID_X_SCALE_FACTOR) <<
		"LTKTraceGroup::scale()"<<endl;

		LTKReturnError(EINVALID_X_SCALE_FACTOR);
	}

	if(yScaleFactor <= 0)
	{
		LOG( LTKLogger::LTK_LOGLEVEL_ERR) <<
        "Error: "<<EINVALID_X_SCALE_FACTOR <<": "<<
		getErrorMessage(EINVALID_X_SCALE_FACTOR) <<
		"LTKTraceGroup::scale()"<<endl;

		LTKReturnError(EINVALID_Y_SCALE_FACTOR);
	}

	if((errorCode = getBoundingBox(xMin,yMin,xMax,yMax))!=SUCCESS)
	{
		LOG( LTKLogger::LTK_LOGLEVEL_ERR) <<
        "Error: LTKTraceGroup::affineTransform()"<<endl;

		LTKReturnError(errorCode);
	}

	switch(referenceCorner)
	{

		case XMIN_YMIN:

			xReference=xMin;
			yReference=yMin;
			break;

		case XMIN_YMAX:

			xReference=xMin;
			yReference=yMax;

			break;

		case XMAX_YMIN:

			xReference=xMax;
			yReference=yMin;

			break;

		case XMAX_YMAX:
			xReference=xMax;
			yReference=yMax;

			break;

		default: break;//define an exception

	}

    int numTraces = m_traceVector.size();
    for(traceIndex=0; traceIndex < numTraces; ++traceIndex)
    {
        getTraceAt(traceIndex, trace);

		floatVector xVec;
		
		//no error handling required as the bounding box is found
        trace.getChannelValues(X_CHANNEL_NAME, xVec);

        
		floatVector yVec;
		
		
        trace.getChannelValues(Y_CHANNEL_NAME, yVec);
		

		numPoints = xVec.size();
		
		for(index=0; index < numPoints; index++)
		{
			//the additive term is to translate back the scaled tracegroup
			//so that the corner asked for is preserved at the destination
			//(translateToX,translateToY)
			x = ( (xVec.at(index) * xScaleFactor)/m_xScaleFactor) +
			     (translateToX - (xReference*(xScaleFactor/m_xScaleFactor)) );

			scaledXVec.push_back(x);

			//the additive term is to translate back the scaled tracegroup
			//so that the corner asked for is preserved at the destination
			//(translateToX,translateToY)
			y= ( (yVec.at(index) * yScaleFactor)/m_yScaleFactor) +
			     (translateToY - (yReference*(yScaleFactor/m_yScaleFactor)));

			scaledYVec.push_back(y);

		}

		trace.reassignChannelValues(X_CHANNEL_NAME,scaledXVec);

		trace.reassignChannelValues(Y_CHANNEL_NAME,scaledYVec);

		scaledXVec.clear();

		scaledYVec.clear();

		scaledTracesVec.push_back(trace);

    }


	m_traceVector = scaledTracesVec;

	m_xScaleFactor = xScaleFactor;
	m_yScaleFactor = yScaleFactor;

	LOG( LTKLogger::LTK_LOGLEVEL_DEBUG) <<
		"Enter: LTKTraceGroup::affineTransform()"<<endl;

	return SUCCESS;
}
/******************************************************************************
* AUTHOR		: Bharath A.
* DATE			: 03-SEP-2007
* NAME			: translateTo
* DESCRIPTION	: translates the tracegroup so that the "referenceCorner" is
				  moved to (x,y)
* ARGUMENTS		: x: x value of point to which referenceCorner has to be moved
*				  y: y value of point to which referenceCorner has to be moved
*				  referenceCorner - the reference corner in the tracegroup that
				  has to be moved to (x,y)
* RETURNS		: SUCCESS on successful translation operation
* NOTES			:
* CHANGE HISTROY
* Author			Date				Description of change
*******************************************************************************/
int LTKTraceGroup::translateTo(float x,float y,TGCORNER referenceCorner)
{

	LOG( LTKLogger::LTK_LOGLEVEL_DEBUG) <<
		"Enter: LTKTraceGroup::translateTo()"<<endl;

	LTKTrace trace;

	vector<LTKTrace> translatedTracesVec;	// holds the translated traces

	floatVector translatedXVec;				//	translated x channel values of a trace
	floatVector translatedYVec;				//	translated y channel values of a trace

	float xValue, yValue;
	float xReference, yReference;
	float xMin=0.0f;
	float yMin=0.0f;
	float xMax=0.0f;
	float yMax=0.0f;

	int errorCode;
	int traceIndex, index;
	int numPoints;


	if((errorCode = getBoundingBox(xMin,yMin,xMax,yMax))!=SUCCESS)
	{
		LOG( LTKLogger::LTK_LOGLEVEL_ERR) <<
           "Error: LTKTraceGroup::translateTo()"<<endl;

		LTKReturnError(errorCode);
	}

	switch(referenceCorner)
	{

		case XMIN_YMIN:

			xReference=xMin;
			yReference=yMin;
			break;

		case XMIN_YMAX:

			xReference=xMin;
			yReference=yMax;

			break;


		case XMAX_YMIN:

			xReference=xMax;
			yReference=yMin;

			break;


		case XMAX_YMAX:
			xReference=xMax;
			yReference=yMax;

			break;


		default: break;//define an exception

	}

    int numTraces = getNumTraces();
    for(traceIndex=0; traceIndex < numTraces; ++traceIndex)
    {
        getTraceAt(traceIndex, trace);
		
		floatVector xVec;
		
		//no error handling required as the bounding box is found
        trace.getChannelValues(X_CHANNEL_NAME, xVec);

        
		floatVector yVec;
		
        trace.getChannelValues(Y_CHANNEL_NAME, yVec);

        
		numPoints = xVec.size();

		for(index=0; index < numPoints; index++)
		{

			xValue=xVec.at(index)+(x-xReference);
			translatedXVec.push_back(xValue);

			yValue=yVec.at(index)+(y-yReference);
			translatedYVec.push_back(yValue);

		}

		trace.reassignChannelValues(X_CHANNEL_NAME,translatedXVec);

		trace.reassignChannelValues(Y_CHANNEL_NAME,translatedYVec);

		translatedXVec.clear();

		translatedYVec.clear();

		translatedTracesVec.push_back(trace);

    }

	m_traceVector=translatedTracesVec;

	LOG( LTKLogger::LTK_LOGLEVEL_DEBUG) <<
		"Exit: LTKTraceGroup::translateTo()"<<endl;

	return SUCCESS;

}