#include <qapplication.h>
#include <qvaluelist.h>
#include <qregexp.h>

#include "utils.h"

QValueList <Utils::toolsPaths *> g_listToolsPaths;

QValueList <Utils::toolsPaths *> getToolsPaths ()
{
	Utils::toolsPaths *pEntry = new Utils::toolsPaths;
	pEntry->qsExecutableName = QString("jpeg2yuv");
	pEntry->qsFullPath = QString ("/usr/bin/jpeg2yuv");
	pEntry->bPresent = true;
	g_listToolsPaths.append (pEntry);

	pEntry = new Utils::toolsPaths;
	pEntry->qsExecutableName = QString("spumux");
	pEntry->qsFullPath = QString ("/usr/local/bin/spumux");
	pEntry->bPresent = true;
	g_listToolsPaths.append (pEntry);

	pEntry = new Utils::toolsPaths;
	pEntry->qsExecutableName = QString("dvdauthor");
	pEntry->qsFullPath = QString ("dvdauthor");
	pEntry->bPresent = false;
	g_listToolsPaths.append (pEntry);

	pEntry = new Utils::toolsPaths;
	pEntry->qsExecutableName = QString("mpeg2enc");
	pEntry->qsFullPath = QString ("/usr/local/bin/mpeg2enc");
	pEntry->bPresent = true;
	g_listToolsPaths.append (pEntry);

	return g_listToolsPaths;
}

QString getToolsPath(QString qsCommandLine)
{
	// This function will take the command line as an input and add the full path to each of the tools used in this cmmand line.
	// E.g. 
	// jpeg2yuv -n 50 -I p -f 25 -j "/tmp/Test_colors/Main Menu VMGMbackground.jpg" | mpeg2enc -n p -f 8 -o "/tmp/Test_colors//Main Menu VMGM.m2v"
	// will be converted into 
	// /usr/bin/jpeg2yuv -n 50 -I p -f 25 -j "/tmp/Test_colors/Main Menu VMGMbackground.jpg" | /usr/local/bin/mpeg2enc -n p -f 8 -o "/tmp/Test_colors//Main Menu VMGM.m2v"
	/////////////////////////////////////////////////////////////////////

	uint t;
	QString qsReturn;
	QString qsCommand;
	QRegExp regExp;
	qsReturn = qsCommandLine;
//	QValueList <Utils::toolsPaths *> listToolsPaths = m_pInitObject->getToolsPaths ();
	QValueList <Utils::toolsPaths *> listToolsPaths = getToolsPaths ();
	for (t=0;t<listToolsPaths.count ();t++)	{
//printf ("<%s><%s>\n", (const char *)listToolsPaths[t]->qsExecutableName, (const char *)listToolsPaths[t]->qsFullPath);
//		regExp = QRegExp (QString ("(?!\^)%1 ").arg(listToolsPaths[t]->qsExecutableName));
		if (listToolsPaths[t]->bPresent)	{
 			// The first regExp takes care of all occurances of the tool which do NOT start with a '/'
			regExp = QRegExp ("(^|\\s(?!/+))"+listToolsPaths[t]->qsExecutableName+" ");
			qsReturn.replace (regExp, listToolsPaths[t]->qsFullPath+" ");
			// The second regExp takes care of the case where the user does not leave a blank between the pipe symbol '|' and the tool.
 			regExp = QRegExp ("\\|"+listToolsPaths[t]->qsExecutableName+" ");
			qsReturn.replace (regExp, "| "+listToolsPaths[t]->qsFullPath+" ");
		}
		else
			printf ("WARNING, %s not present in system.\n", (const char *) listToolsPaths[t]->qsExecutableName);
	}
	return qsReturn;
}
/*
int main( int, char ** )
{


    QString qsTest ("jpeg2yuv -n 50 -I p -f 25 -j \"/tmp/Test_spumux/Main Menu VMGMbackground.jpg\" |mpeg2enc -n p -f 8 -o \"/tmp/Test_spumux/Main Menu VMGM.m2v\"");
	
	printf ("<%s>\n", (const char *)qsTest);
	qsTest = getToolsPath (qsTest);
	printf ("<%s>\n", (const char *)qsTest);
    return 0;
}
*/

#include <qfile.h>
#include <qrect.h>
#include <qvaluelist.h>

#define TYPE_COLOR_RED   0
#define TYPE_COLOR_GREEN 1 
#define TYPE_COLOR_BLUE  2
    
class CallbackClass
{
public:
    // The member function(s) will take and return an int
    virtual int operator()( int ) = 0;
}; 

template <class T>
class FunctionCallback : public CallbackClass
{
public:
    typedef void (T::*Fn)( int );
    typedef void (T::*colorFn)( int, int, int );

    FunctionCallback( T& obj, Fn fn )
	: m_obj( obj ), m_fn( fn ), m_iWhichType ( -1 )
    {}
    FunctionCallback( T& obj, int c )
	: m_obj( obj ), m_iWhichType ( c )
    {}

    virtual int operator()( int n )
    {
	// call the function on the object
	if (m_iWhichType == -1)	{
		(m_obj.*m_fn)( n );
	}
	else if ( (m_iWhichType >= TYPE_COLOR_RED) && (m_iWhichType <= TYPE_COLOR_BLUE) )	{// Special handling for QColor
		QColor &theColor = ((QColor &)m_obj);
		int r = theColor.red  ();
		int g = theColor.green();
		int b = theColor.blue ();
		switch (m_iWhichType)	{
		case TYPE_COLOR_RED:   r = n; break;
		case TYPE_COLOR_GREEN: g = n; break;
		case TYPE_COLOR_BLUE:  b = n; break;
		}
		theColor.setRgb(r, g, b);
//		(m_obj.*m_colorFn)( n, ((QColor &)m_obj).green(), ((QColor &)m_obj).blue() );
	}
	return 0;
    }

private:
    T&    m_obj; 	// object reference
    Fn    m_fn;  	// function pointer
    int   m_iWhichType;	// which color to set 
}; 


class AnimationAttribute
{
public:
	 AnimationAttribute (long, QString, int  ,   CallbackClass *);
	 AnimationAttribute (long, QString, int  ,   int   *);
	 AnimationAttribute (long, QString, float,   float *);
	 AnimationAttribute (long, QString, QString, QString *);
	~AnimationAttribute ();

	const QString name ();
	void    setValue   (long);
	int     iValue     (long);
	float   fValue     (long);
	QString qsValue    (long);
	void    append     (long, QString);
	long    maxFrames  ();;

private:
	int           *m_piValue;	// Pointer to the real deal (if int)
	float         *m_pfValue;	// pointer to the real deal (if float)
	QString       *m_pqsValue;	// pointer to the real deal (if string)
	CallbackClass *m_setFunction;	// Pointer to function to set value (E.g. QRect::setX(int))

	int           *m_arrayInts;	// Holds the values (if int)
	float         *m_arrayFloats;	// holds the values (if float)
	QString       *m_arrayStrings;	// Holds the values (if string)
	QString        m_qsName;	// is the property name (E.g. rect.x1 or zoom)
	int            m_iMaxFrames;	// Number of frames (also size of the array)
};

AnimationAttribute::AnimationAttribute (long iFrames, QString qsName, int iOrigValue, CallbackClass *fnc )
{
	long t;
	m_setFunction  = fnc; 
	m_piValue      = NULL;
	m_pfValue      = NULL;
	m_arrayFloats  = NULL;
	m_arrayStrings = NULL;
	m_arrayInts    = new int[iFrames+1];
	for (t=0;t<iFrames+1;t++)
		m_arrayInts[t] = -1;
	m_arrayInts[0] = iOrigValue;
	m_qsName       = qsName;
	m_iMaxFrames   = iFrames;
}

AnimationAttribute::~AnimationAttribute ()
{
	if (m_arrayFloats)
		delete []m_arrayFloats;
	if (m_arrayInts)
		delete []m_arrayInts;
	if (m_arrayStrings)
		delete []m_arrayStrings;
	if (m_setFunction)
		delete m_setFunction;
	m_arrayInts    = NULL;
	m_arrayFloats  = NULL;
	m_arrayStrings = NULL;
	m_setFunction  = NULL;
}

void loadAnimationData (QString qsFileName)
{
//	char *standardProperties[] = {"rect", "rotate", "zoom", "scale", "shear", "transparency"}; // index 0-12
//	char *frameProperties   [] = {"color", "frameWidth", "frameStyle", "frameJoin"}; // index 13-24
//	char *imageProperties [] = {"backgroundFileName", "showBackground", "startPos", "res", "aspectRatio", "blendColor", "brightness" }; // index 13-24
//	char *movieProperties [] = {"backgroundFileName", "showBackground", "startPos", "res", "aspectRatio", "blendColor", "brightness", "frameNo" }; // index 13-25
//	char *textProperties  [] = {"text", "font", "textAlign", "foregroundColor", "backgroundColor"}; // index 13-25

	// Called from MenuPreview::createAnimationData
	// Loads in the pure data from a file.
	// Note: changes are done on a per frame basis
	// If no value for a prop at a fram is defined, 
	// then the last value is the winner.
	///////////////////////////////////////////////
	
	// Note, these values will change the true props 
	// of the object.
	// Once rendering is done the original values are re-set.
	QFile file (qsFileName);
	file.open ( IO_ReadOnly );
	QTextStream stream( &file );
	QString line;
	uint t;
	long i;
	int iPos, iPos2, iFrameNumber, iMaxNumberOfFrames = 25;
	bool bFound;
	QString qsProperty, qsValue;
	
	QValueList<AnimationAttribute *> listAnimationAttributes;
	AnimationAttribute *pAnimAttr;

	static QRect   m_testRect  = QRect (10, 10, 100, 100);
	static QPoint  m_testPoint = QPoint (11, 22);
	static QColor  m_testColor = QColor ( 10, 110, 210 );
	static QString m_qsTestString("empty");
	static float   m_fZoom     = 0.0f;
	static int     m_iTestInt  = -1;
	
	while ( !stream.atEnd() ) {
		line = stream.readLine(); // line of text excluding '\n'
		iPos = line.find ("::");
		iPos2 = line.find ("=");
		if ( (iPos == -1) || (iPos2 == -1) )
			continue;
		qsProperty  = QString ("");
		qsValue     = QString ("");
		bFound      = false;

		iFrameNumber = line.left (iPos).toInt();
		qsProperty = line.mid (iPos+2, iPos2-iPos-2);
		
		qsValue = line.right (line.length() - iPos2-1);
		if (qsValue == "SolidLine")
			qsValue = QString ("%1").arg(Qt::SolidLine);
		else if (qsValue == "DashLine")
			qsValue = QString ("%1").arg(Qt::DashLine);
		else if (qsValue == "DashDotLine")
			qsValue = QString ("%1").arg(Qt::DashDotLine);
		else if (qsValue == "DashDotDotLine")
			qsValue = QString ("%1").arg(Qt::DashDotDotLine);
		else if (qsValue == "MiterJoin")
			qsValue = QString ("%1").arg(Qt::MiterJoin);
		else if (qsValue == "BevelJoin")
			qsValue = QString ("%1").arg(Qt::BevelJoin);
		else if (qsValue == "RoundJoin")
			qsValue = QString ("%1").arg(Qt::RoundJoin);

		printf ("load <%d> <%s>=<%s>\n", iFrameNumber, (const char *)qsProperty, (const char *)qsValue);

		for (t=0;t<listAnimationAttributes.count ();t++)	{
			pAnimAttr = listAnimationAttributes[t];
			if (pAnimAttr->name() == qsProperty)	{
				pAnimAttr->append (iFrameNumber, qsValue);
				bFound = true;
			}
		}
		if ( ! bFound )	{
			if (qsProperty == "rect.x1")	{
				FunctionCallback<QRect> *callMeBack = new FunctionCallback<QRect>(m_testRect, &QRect::setX);
				pAnimAttr = new AnimationAttribute (iMaxNumberOfFrames, qsProperty, m_testRect.x(), callMeBack);
			}
			if (qsProperty == "rect.x2")	{
				FunctionCallback<QRect> *callMeBack = new FunctionCallback<QRect>(m_testRect, &QRect::setRight);
				pAnimAttr = new AnimationAttribute (iMaxNumberOfFrames, qsProperty, m_testRect.x(), callMeBack);
			}
			if (qsProperty == "rect.y1")	{
				FunctionCallback<QRect> *callMeBack = new FunctionCallback<QRect>(m_testRect, &QRect::setY);
				pAnimAttr = new AnimationAttribute (iMaxNumberOfFrames, qsProperty, m_testRect.x(), callMeBack);
			}
			if (qsProperty == "rect.y2")	{
				FunctionCallback<QRect> *callMeBack = new FunctionCallback<QRect>(m_testRect, &QRect::setBottom);
				pAnimAttr = new AnimationAttribute (iMaxNumberOfFrames, qsProperty, m_testRect.x(), callMeBack);
			}
			if (qsProperty == "rect.width")	{
				FunctionCallback<QRect> *callMeBack = new FunctionCallback<QRect>(m_testRect, &QRect::setWidth);
				pAnimAttr = new AnimationAttribute (iMaxNumberOfFrames, qsProperty, m_testRect.x(), callMeBack);
			}
			if (qsProperty == "rect.height")	{
				FunctionCallback<QRect> *callMeBack = new FunctionCallback<QRect>(m_testRect, &QRect::setHeight);
 				pAnimAttr = new AnimationAttribute (iMaxNumberOfFrames, qsProperty, m_testRect.x(), callMeBack);
			}
			else if (qsProperty == "zoom")
				pAnimAttr = new AnimationAttribute (iMaxNumberOfFrames, qsProperty, m_fZoom, &m_fZoom);
			else if (qsProperty == "rotate")
				pAnimAttr = new AnimationAttribute (iMaxNumberOfFrames, qsProperty, m_fZoom, &m_fZoom);
			else if (qsProperty == "shear.x")	{
				FunctionCallback<QPoint> *callMeBack = new FunctionCallback<QPoint>(m_testPoint, &QPoint::setX);
 				pAnimAttr = new AnimationAttribute (iMaxNumberOfFrames, qsProperty, m_testPoint.x(), callMeBack);
			}
			else if (qsProperty == "shear.y")	{
				FunctionCallback<QPoint> *callMeBack = new FunctionCallback<QPoint>(m_testPoint, &QPoint::setY);
 				pAnimAttr = new AnimationAttribute (iMaxNumberOfFrames, qsProperty, m_testPoint.x(), callMeBack);
			}
			else if (qsProperty == "scale.x")	{
				FunctionCallback<QPoint> *callMeBack = new FunctionCallback<QPoint>(m_testPoint, &QPoint::setX);
 				pAnimAttr = new AnimationAttribute (iMaxNumberOfFrames, qsProperty, m_testPoint.x(), callMeBack);
			}
			else if (qsProperty == "scale.y")	{
				FunctionCallback<QPoint> *callMeBack = new FunctionCallback<QPoint>(m_testPoint, &QPoint::setY);
 				pAnimAttr = new AnimationAttribute (iMaxNumberOfFrames, qsProperty, m_testPoint.x(), callMeBack);
			}
			else if (qsProperty == "transparency")
				pAnimAttr = new AnimationAttribute (iMaxNumberOfFrames, qsProperty, m_fZoom, &m_fZoom);
			// Here are the object specifics ...
			else if (qsProperty == "color.red")	{
				FunctionCallback<QColor> *callMeBack = new FunctionCallback<QColor>(m_testColor, TYPE_COLOR_RED);
 				pAnimAttr = new AnimationAttribute (iMaxNumberOfFrames, qsProperty, m_testColor.red(), callMeBack);
			}
			else if (qsProperty == "color.green")	{
				FunctionCallback<QColor> *callMeBack = new FunctionCallback<QColor>(m_testColor, TYPE_COLOR_GREEN);
 				pAnimAttr = new AnimationAttribute (iMaxNumberOfFrames, qsProperty, m_testColor.green(), callMeBack);
			}
			else if (qsProperty == "color.blue")	{
				FunctionCallback<QColor> *callMeBack = new FunctionCallback<QColor>(m_testColor, TYPE_COLOR_BLUE);
 				pAnimAttr = new AnimationAttribute (iMaxNumberOfFrames, qsProperty, m_testColor.blue(), callMeBack);
			}
			else if (qsProperty == "frameWidth")
				pAnimAttr = new AnimationAttribute (iMaxNumberOfFrames, qsProperty, m_fZoom, &m_fZoom);
			else if (qsProperty == "frameStyle")
				pAnimAttr = new AnimationAttribute (iMaxNumberOfFrames, qsProperty, m_iTestInt, &m_iTestInt);
			else if (qsProperty == "frameJoin")
				pAnimAttr = new AnimationAttribute (iMaxNumberOfFrames, qsProperty, m_iTestInt, &m_iTestInt);
			
			else if (qsProperty == "backgroundFileName")
				pAnimAttr = new AnimationAttribute (iMaxNumberOfFrames, qsProperty, m_qsTestString, &m_qsTestString);
			else if (qsProperty == "showBackground")
				pAnimAttr = new AnimationAttribute (iMaxNumberOfFrames, qsProperty, m_iTestInt, &m_iTestInt);
			else if (qsProperty == "startPos.x")	{
				FunctionCallback<QPoint> *callMeBack = new FunctionCallback<QPoint>(m_testPoint, &QPoint::setX);
 				pAnimAttr = new AnimationAttribute (iMaxNumberOfFrames, qsProperty, m_testPoint.x(), callMeBack);
			}
			else if (qsProperty == "startPos.y")	{
				FunctionCallback<QPoint> *callMeBack = new FunctionCallback<QPoint>(m_testPoint, &QPoint::setY);
 				pAnimAttr = new AnimationAttribute (iMaxNumberOfFrames, qsProperty, m_testPoint.y(), callMeBack);
			}
			else if (qsProperty == "res.x")	{
				FunctionCallback<QPoint> *callMeBack = new FunctionCallback<QPoint>(m_testPoint, &QPoint::setX);
 				pAnimAttr = new AnimationAttribute (iMaxNumberOfFrames, qsProperty, m_testPoint.x(), callMeBack);
			}
			else if (qsProperty == "res.y")	{
				FunctionCallback<QPoint> *callMeBack = new FunctionCallback<QPoint>(m_testPoint, &QPoint::setY);
 				pAnimAttr = new AnimationAttribute (iMaxNumberOfFrames, qsProperty, m_testPoint.y(), callMeBack);
			}
			else if (qsProperty == "aspectRatio")
				pAnimAttr = new AnimationAttribute (iMaxNumberOfFrames, qsProperty, m_fZoom, &m_fZoom);
			else if (qsProperty == "blendColor.red")	{
				FunctionCallback<QColor> *callMeBack = new FunctionCallback<QColor>(m_testColor, TYPE_COLOR_RED);
 				pAnimAttr = new AnimationAttribute (iMaxNumberOfFrames, qsProperty, m_testColor.red(), callMeBack);
			}
			else if (qsProperty == "blendColor.green")	{
				FunctionCallback<QColor> *callMeBack = new FunctionCallback<QColor>(m_testColor, TYPE_COLOR_GREEN);
 				pAnimAttr = new AnimationAttribute (iMaxNumberOfFrames, qsProperty, m_testColor.green(), callMeBack);
			}
			else if (qsProperty == "blendColor.blue")	{
				FunctionCallback<QColor> *callMeBack = new FunctionCallback<QColor>(m_testColor, TYPE_COLOR_BLUE);
 				pAnimAttr = new AnimationAttribute (iMaxNumberOfFrames, qsProperty, m_testColor.blue(), callMeBack);
			}
			else if (qsProperty == "brightness")
				pAnimAttr = new AnimationAttribute (iMaxNumberOfFrames, qsProperty, m_fZoom, &m_fZoom);
			else if (qsProperty == "frameNo")
				pAnimAttr = new AnimationAttribute (iMaxNumberOfFrames, qsProperty, m_iTestInt, &m_iTestInt);
			else if (qsProperty == "text")
				pAnimAttr = new AnimationAttribute (iMaxNumberOfFrames, qsProperty, m_qsTestString, &m_qsTestString);
			else if (qsProperty == "font")
				pAnimAttr = new AnimationAttribute (iMaxNumberOfFrames, qsProperty, m_qsTestString, &m_qsTestString);
			else if (qsProperty == "textAlign")
				pAnimAttr = new AnimationAttribute (iMaxNumberOfFrames, qsProperty, m_iTestInt, &m_iTestInt);
			else if (qsProperty == "foregroundColor.red")	{
				FunctionCallback<QColor> *callMeBack = new FunctionCallback<QColor>(m_testColor, TYPE_COLOR_RED);
 				pAnimAttr = new AnimationAttribute (iMaxNumberOfFrames, qsProperty, m_testColor.red(), callMeBack);
			}
			else if (qsProperty == "foregroundColor.green")	{
				FunctionCallback<QColor> *callMeBack = new FunctionCallback<QColor>(m_testColor, TYPE_COLOR_GREEN);
 				pAnimAttr = new AnimationAttribute (iMaxNumberOfFrames, qsProperty, m_testColor.green(), callMeBack);
			}
			else if (qsProperty == "foregroundColor.blue")	{
				FunctionCallback<QColor> *callMeBack = new FunctionCallback<QColor>(m_testColor, TYPE_COLOR_BLUE);
 				pAnimAttr = new AnimationAttribute (iMaxNumberOfFrames, qsProperty, m_testColor.blue(), callMeBack);
			}
			else if (qsProperty == "backgroundColor.red")	{
				FunctionCallback<QColor> *callMeBack = new FunctionCallback<QColor>(m_testColor, TYPE_COLOR_RED);
 				pAnimAttr = new AnimationAttribute (iMaxNumberOfFrames, qsProperty, m_testColor.red(), callMeBack);
			}
			else if (qsProperty == "backgroundColor.green")	{
				FunctionCallback<QColor> *callMeBack = new FunctionCallback<QColor>(m_testColor, TYPE_COLOR_GREEN);
 				pAnimAttr = new AnimationAttribute (iMaxNumberOfFrames, qsProperty, m_testColor.green(), callMeBack);
			}
			else if (qsProperty == "backgroundColor.blue")	{
				FunctionCallback<QColor> *callMeBack = new FunctionCallback<QColor>(m_testColor, TYPE_COLOR_BLUE);
 				pAnimAttr = new AnimationAttribute (iMaxNumberOfFrames, qsProperty, m_testColor.blue(), callMeBack);
			}

			pAnimAttr->append (iFrameNumber, qsValue);
			listAnimationAttributes.append ( pAnimAttr );
		}
	}
	file.close();
	
	if (listAnimationAttributes.count() < 1)
		return;
	iMaxNumberOfFrames = listAnimationAttributes[0]->maxFrames();
	for (i=0;i<iMaxNumberOfFrames;i++)	{
		for (t=0;t<listAnimationAttributes.count();t++)	{
			listAnimationAttributes[t]->setValue (i);
		}
		printf ("<%d : %ld>X1=<%d> zoom=<%03f>\n", t, i, m_testRect.x(), m_fZoom);
	}
}

/** 34::rect.x1=68 */

AnimationAttribute::AnimationAttribute (long iFrames, QString qsName, int iOrigValue, int *pTheLocation)
{
	long t;
	m_pfValue      = NULL;
	m_setFunction  = NULL;
	m_arrayFloats  = NULL;
	m_arrayStrings = NULL;
	m_arrayInts    = new int[iFrames+1];
	for (t=0;t<iFrames+1;t++)
		m_arrayInts[t] = -1;
	m_piValue      = pTheLocation;
	m_arrayInts[0] = iOrigValue;
	m_qsName       = qsName;
	m_iMaxFrames   = iFrames;
}

AnimationAttribute::AnimationAttribute (long iFrames, QString qsName, float fOrigValue, float *pTheLocation)
{
	long t;
	m_piValue        = NULL;
	m_setFunction    = NULL;
	m_arrayInts      = NULL;
	m_arrayStrings   = NULL;
	m_arrayFloats    = new float[iFrames+1];
	for (t=0;t<iFrames+1;t++)
		m_arrayFloats[t] = -9999.99f;
	m_pfValue        = pTheLocation;
	m_arrayFloats[0] = fOrigValue;
	m_qsName         = qsName;
	m_iMaxFrames     = iFrames;
}

AnimationAttribute::AnimationAttribute (long iFrames, QString qsName, QString qsOrigValue, QString *pTheLocation)
{
	m_piValue         = NULL;
	m_setFunction     = NULL;
	m_arrayInts       = NULL;
	m_arrayFloats     = NULL;
	m_arrayStrings    = new QString[iFrames+1];
	m_pqsValue        = pTheLocation;
	m_arrayStrings[0] = qsOrigValue;
	m_qsName          = qsName;
	m_iMaxFrames      = iFrames;
}

const QString AnimationAttribute::name ()
{
	return m_qsName;
}

int AnimationAttribute::iValue (long iFrame)
{
	if (!m_arrayInts)
		return -1;
	if ( ( iFrame < 0 ) || ( iFrame > m_iMaxFrames ) )
		return -1;
	return (m_arrayInts[iFrame]);
}

float AnimationAttribute::fValue (long iFrame)
{
	if (!m_arrayFloats)
		return 0.0;
	if ( ( iFrame < 0 ) || ( iFrame > m_iMaxFrames ) )
		return 0.0;
	return (m_arrayFloats[iFrame]);
}

QString AnimationAttribute::qsValue (long iFrame)
{
	if (!m_arrayStrings)
		return QString ();
	if ( ( iFrame < 0 ) || ( iFrame > m_iMaxFrames ) )
		return QString ();
	return (m_arrayStrings[iFrame]);
}

long AnimationAttribute::maxFrames ()
{
	return m_iMaxFrames;;
}

void AnimationAttribute::setValue (long iFrame)
{
	if ( ( ! m_arrayFloats ) && ( ! m_arrayInts ) )
		return;
	if ( ( iFrame < 0 ) || ( iFrame > m_iMaxFrames ) )
		return;

	if (m_arrayInts && m_piValue)	{
		if (m_arrayInts[iFrame] == -1)
			return;
		*m_piValue = m_arrayInts[iFrame];
	}
	else if (m_arrayInts && m_setFunction)	{
		if (m_arrayInts[iFrame] == -1)
			return;
		(*m_setFunction)(m_arrayInts[iFrame]);
	}

	else if (m_arrayFloats && m_pfValue)	{
		if (m_arrayFloats[iFrame] == -9999.99f)
			return;
		*m_pfValue = m_arrayFloats[iFrame];
	}
	else if (m_arrayStrings && m_pqsValue)	{
		if (m_arrayStrings[iFrame].isEmpty())
			return;
		*m_pqsValue = m_arrayStrings[iFrame];
	}
}

void AnimationAttribute::append (long iFrame, QString qsValue)
{
	if ( (iFrame < 0) || (iFrame > m_iMaxFrames) )
		return;
	if (m_arrayInts)
		m_arrayInts[iFrame] = qsValue.toInt ();
	else if (m_arrayFloats)
		m_arrayFloats[iFrame] = qsValue.toFloat ();
	else
		m_arrayStrings[iFrame] = qsValue;
}

#include <qregexp.h>
int main( int, char ** )
{
//    loadAnimationData ("test.anim");
  	QRegExp rx ( "<[^>]*>"); //"s/</p>/HHH/g" );
	QString qsFick, qsFuck ( "<p align=\"center\">FUCK THIS</p>" );

	qsFick = qsFuck.remove ( rx );

	printf ( "%s  -  %s\n", qsFuck.ascii ( ), qsFick.ascii ( ) ) ;
  
    return 0;
}


