/*
* FX Tool Timeline Properties
* @version 3-09-05
* @author Joseph 'Pcjoe' Florencio
*/


#include "hud.h"
#include "cl_util.h"
#include "const.h"
#include "entity_state.h"
#include "cl_entity.h"
#include "vgui_TeamFortressViewport.h"
#include "vgui_fxtimelineprop.h"
#include <vgui_slider.h>
#include "mdlcontrol.h"

#define DEFAULT_PROP_WIDE	200
#define DEFAULT_CHECK_TALL	24
#define DEFAULT_SLIDER_TALL	10
#define DEFAULT_TEXT_TALL	20
#define DEFAULT_WIDTH (DEFAULT_PROP_WIDE-getPadding()*2)

/*
* Base Timeline Property Panel
*/
// Accept Button
class AcceptButtonAction : public ActionSignal
{
public:
	// Constructor
	AcceptButtonAction( )
	{	setPanel(NULL);
	}

	// Constructor
	AcceptButtonAction( CFXBaseTimeProp *pPanel )
	{	setPanel(pPanel);
	}

	// Call complete entry, then remove
	virtual void actionPerformed(Panel* panel)
	{	if(getPanel())
		{	getPanel()->completeEntry();
			gViewPort->m_pFXToolPanel->removePropPanel(getPanel());
		}
	}

	// Accessors
	void setPanel( CFXBaseTimeProp *pPanel ) { m_pPanel = pPanel; }
	CFXBaseTimeProp *getPanel( void ) { return m_pPanel; }
private:
	CFXBaseTimeProp *m_pPanel;
};

// Cancel Button
class CancelButtonAction : public ActionSignal
{
public:
	// Constructor
	CancelButtonAction( )
	{	setPanel(NULL);
	}

	// Constructor
	CancelButtonAction( CFXBaseTimeProp *pPanel )
	{	setPanel(pPanel);
	}

	// Remove from main panel
	virtual void actionPerformed(Panel* panel)
	{	// remove
		if(getPanel())
		{	if(!getPanel()->isCreatePanel())
				getPanel()->cancelSettings();
			gViewPort->m_pFXToolPanel->removePropPanel(getPanel());
		}
	}

	// Accessors
	void setPanel( CFXBaseTimeProp *pPanel ) { m_pPanel = pPanel; }
	CFXBaseTimeProp *getPanel( void ) { return m_pPanel; }
private:
	CFXBaseTimeProp *m_pPanel;
};

// Delete Button
class DeleteButtonAction : public ActionSignal
{
public:
	// Constructor
	DeleteButtonAction( )
	{	setPanel(NULL);
	}

	// Constructor
	DeleteButtonAction( CFXBaseTimeProp *pPanel )
	{	setPanel(pPanel);
	}

	// Remove from main panel
	virtual void actionPerformed(Panel* panel)
	{	// remove
		if(getPanel())
		{	// Delete timed event then remove
			CFXEvent *pEvent = gViewPort->m_pFXToolPanel->getEvent();
			CFXObject *pObj = pEvent->getObjectByIndex(getPanel()->getObjectID());
			if(pObj)
			{	CTimeline *pTimeline = pObj->getTimelineManager()->getTimeline(getPanel()->getTimelineID());
				if(pTimeline)
				{	// remove from vgui timeline box
					std::list<CTimelineStrip>::iterator iterCurrent;
					ForEachIn(iterCurrent,(*gViewPort->m_pFXToolPanel->getTimeline()->getTimelineStripList()))
					{	// Same timeline, remove
						if(pTimeline == iterCurrent->getObjectTimeline())
						{	iterCurrent->getStripContent()->removeItem(getPanel()->getEditEvent());
							break;
						}
					}

					// Remove physical timeline event
					pTimeline->getTimedEvents()->erase(getPanel()->getEditEvent());

				}
			}
			gViewPort->m_pFXToolPanel->removePropPanel(getPanel());
		}
	}

	// Accessors
	void setPanel( CFXBaseTimeProp *pPanel ) { m_pPanel = pPanel; }
	CFXBaseTimeProp *getPanel( void ) { return m_pPanel; }
private:
	CFXBaseTimeProp *m_pPanel;
};

// Constructor
CFXBaseTimeProp::CFXBaseTimeProp(std::string strTitle, int x,int y, bool bCreatePanel, int iTimelineID) : CFXPanel(strTitle, x, y, DEFAULT_PROP_WIDE, 100)
{	// Init varibles
	setCreatePanel(bCreatePanel);
	setTimelineID(iTimelineID);
	setObjectID(gViewPort->m_pFXToolPanel->getObjectManager()->getObjectList()->getSelectedLabel());
	setEditEvent(NULL);
	setCreateTime(0);
	// Set Parent
	setParent(gViewPort->m_pFXToolPanel);
	gViewPort->m_pFXToolPanel->addPropPanel(this);
	// Set text depending on panel type
	std::string strPanelName = getPrefixName();
	strPanelName += " ";
	strPanelName += strTitle;
	getTitle()->setText(strPanelName.c_str());
}

// Configure for Edit
void CFXBaseTimeProp::configEdit( std::map<float,CTimedEvent*>::iterator iterEdit )
{	setEditEvent(iterEdit);
}

// Configure for New
void CFXBaseTimeProp::configNew( float flTime )
{	setCreateTime(flTime);
	// Set create time
	char szStart[16];
	sprintf(szStart,"%.2f",getCreateTime());
	getTimeStartText()->setText(szStart,strlen(szStart));
}

// Make Accept and Cancel buttons
// Note - Starts from getTall() and extends content panel, uses current width
#define FINISH_BUTTON_HEIGHT	30
void CFXBaseTimeProp::makeFinishButtons( void )
{	int x = getPadding();
	int y = getContentPanel()->getTall() + getPadding();
	int iWidth = getContentPanel()->getWide();
	int iButtonSize = ((iWidth-getPadding()*2)/2)-getPadding()/2;

	// Only for create panels
	if(isCreatePanel())
	{	// Make Time Start Label
		makeLabel("Time", y);
		y += DEFAULT_TEXT_TALL + getPadding();

		// Make Time Start Text Box
		setTimeStartText(makeTextEntry(y));
		y += DEFAULT_TEXT_TALL + getPadding();
	}

	// Create/Edit
	CommandButton *pAccept = new CommandButton( getPrefixName().c_str(), x, y, iButtonSize, FINISH_BUTTON_HEIGHT);
	pAccept->setContentAlignment(vgui::Label::a_center);
	pAccept->setParent( getContentPanel() );
	pAccept->addActionSignal( new AcceptButtonAction(this) );
	setAcceptButton(pAccept);

	x += iButtonSize + getPadding();
	
	// Cancel
	CommandButton *pCancel = new CommandButton( "Cancel", x, y, iButtonSize, FINISH_BUTTON_HEIGHT);
	pCancel->setContentAlignment(vgui::Label::a_center);
	pCancel->setParent( getContentPanel() );
	pCancel->addActionSignal( new CancelButtonAction(this) );
	setCancelButton(pCancel);

	// Make delete button (only on edit panels)
	if(!isCreatePanel())
	{	x = getPadding();
		y += FINISH_BUTTON_HEIGHT + getPadding();
		CommandButton *pDelete = new CommandButton( "Delete", x, y, iWidth-getPadding()*2, FINISH_BUTTON_HEIGHT);
		pDelete->setContentAlignment(vgui::Label::a_center);
		pDelete->setParent( getContentPanel() );
		pDelete->addActionSignal( new DeleteButtonAction(this) );
		setDeleteButton(pDelete);
	}


	// Resize to Y content
	y += FINISH_BUTTON_HEIGHT + getPadding();
	getContentPanel()->setSize(getContentPanel()->getWide(), y);
	resizeToContentTall();
}

// Add Timed Event
void CFXBaseTimeProp::addTimedEvent( float flTime, CTimedEvent *pEvent )
{	if(!pEvent)
	{	return;
	}

	CFXEvent *pFXEvent = gViewPort->m_pFXToolPanel->getEvent();
	if(pFXEvent)
	{	// No valid selection, dont add
		if(getObjectID() == -1)
		{	delete pEvent;
			return;
		}
		// Find object
		CFXObject *pObject = pFXEvent->getObjectByIndex(getObjectID());
		if(pObject)
		{	CTimeline *pTimeline = pObject->getTimelineManager()->getTimeline(getTimelineID());
			if(pTimeline)
			{	// add event
				pTimeline->addTimedEvent(flTime, pEvent);
				// add to vgui timeline
				std::list<CTimelineStrip>::iterator iterCurrent;
				ForEachIn(iterCurrent,(*gViewPort->m_pFXToolPanel->getTimeline()->getTimelineStripList()))
				{	// Same timeline, add
					if(pTimeline == iterCurrent->getObjectTimeline())
					{	std::map<float,CTimedEvent*>::iterator iterAdd = pTimeline->getTimedEvents()->find(flTime);
						if(iterAdd != iterCurrent->getObjectTimeline()->getTimedEvents()->end())
						{	// Add
							iterCurrent->addTimedEvent(iterAdd);
							// Realign
							iterCurrent->getStripContent()->realign();
						}
						break;
					}
				}
			}
			// Cant find timeline
			else
			{	delete pEvent;
				return;
			}
		}
		// Cant find object
		else
		{	delete pEvent;
			return;
		}
	}
}

// Complete Entry ( calls Apply Settings )
void CFXBaseTimeProp::completeEntry( void )
{	CTimedEvent *pEvent = NULL;
	// Edit panel, pass pointer to existing data
	if(!isCreatePanel())
	{	CTimedEvent *pEvent = applySettings(getEditEvent()->second);
		if(pEvent)
			getEditEvent()->second = pEvent;
	}
	// Create new and add
	else
	{	pEvent = applySettings(pEvent);
		if(pEvent)
			addTimedEvent(getTextFloat(getTimeStartText()), pEvent);
	}
}

// Make Check Box
CCheckButton2 *CFXBaseTimeProp::makeCheckBox( std::string strTitle, int y )
{	CCheckButton2 *pCheckBox = new CCheckButton2;
	pCheckBox->setParent(getContentPanel());
	pCheckBox->SetImages("gfx/vgui/checked.tga", "gfx/vgui/unchecked.tga");
	pCheckBox->SetText(strTitle.c_str());
	pCheckBox->setPos(getPadding(),y);
	pCheckBox->SetCheckboxLeft(false);
	pCheckBox->SetChecked(true);
	pCheckBox->SetHandler(NULL);
	return pCheckBox;
}

// Make Label
Label *CFXBaseTimeProp::makeLabel( std::string strTitle, int y )
{	Label *pLabel = new Label(strTitle.c_str(), getPadding(), y, DEFAULT_WIDTH, DEFAULT_TEXT_TALL);
	pLabel->setParent(getContentPanel());
	pLabel->setContentAlignment( vgui::Label::a_center );
	pLabel->setBgColor( 0, 0, 0, 255 );
	pLabel->setFgColor( 255,170,0,0 );
	pLabel->setBorder( new LineBorder( Color(255 * 0.7,170 * 0.7,0,0) ) );
	return pLabel;
}

// Make Slider
Slider2 *CFXBaseTimeProp::makeSlider( int iStartY, int iStartRange, int iEndRange )
{	Slider2 *pSlider = new Slider2(getPadding(),iStartY,DEFAULT_WIDTH,DEFAULT_SLIDER_TALL,false);
    pSlider->setRange(iStartRange,iEndRange);
	pSlider->setBgColor( 0, 0, 0, 255 );
	pSlider->setFgColor( 255,170,0,0 );
	pSlider->setBorder( new LineBorder( Color(255 * 0.7,170 * 0.7,0,0) ) );
	pSlider->setParent(getContentPanel());
	pSlider->setRangeWindow(10);
	pSlider->setRangeWindowEnabled(true);
	pSlider->setValue(iStartRange);
	return pSlider;
}

// Make Text Entry
CBotTextEntry *CFXBaseTimeProp::makeTextEntry( int iStartY )
{	CBotTextEntry *pTextEntry = new CBotTextEntry("", getPadding(), iStartY, DEFAULT_WIDTH, DEFAULT_TEXT_TALL);
	pTextEntry->setParent(getContentPanel());
	pTextEntry->setBgColor(0, 0, 0, 255);
	pTextEntry->setFgColor(100, 100, 100, 150);
	pTextEntry->SetMaxChars(128);
	return pTextEntry;
}

// Get Text from Text Entry
std::string CFXBaseTimeProp::getText( CBotTextEntry *pEntry )
{	if(!pEntry)
	{	return std::string("");
	}
	char szText[129];
	pEntry->getText(0, szText, 128);
	szText[128] = '\0';
	return std::string(szText);
}

// Get Text from Text Entry (float)
float CFXBaseTimeProp::getTextFloat( CBotTextEntry *pEntry )
{	std::string strText = getText(pEntry);
	return atof(strText.c_str());
}

/*
* Position
*/
// Constructor
CFXTimeProp_Position_VGUI::CFXTimeProp_Position_VGUI(std::string strTitle, int x,int y, bool bCreatePanel, int iTimelineID) : CFXBaseTimeProp(strTitle,x,y,bCreatePanel,iTimelineID)
{	int iStartY=getPadding();

	// Make Interp CheckBox
	setInterpCheck(makeCheckBox("Interpolate: ", iStartY));
	iStartY += DEFAULT_CHECK_TALL + getPadding();

	// Make Distance Label
	makeLabel("Distance", iStartY);
	iStartY += DEFAULT_TEXT_TALL + getPadding();

	// Make Distance Slider
	setDistanceSlider(makeSlider(iStartY, 0, 1000));
	iStartY += DEFAULT_SLIDER_TALL + getPadding();

	// Make Velocity Label
	makeLabel("Velocity", iStartY);
	iStartY += DEFAULT_TEXT_TALL + getPadding();

	// Make Velocity Text Box
	setVelocityText(makeTextEntry(iStartY));
	iStartY += DEFAULT_TEXT_TALL + getPadding();
	
	// Resize content
	getContentPanel()->setSize(getContentPanel()->getWide(), iStartY);
	resizeToContentTall();

	// Call update to refreash distance slider range
	Update();

	// Finish up
	makeFinishButtons();
}

// Configure for Edit
void CFXTimeProp_Position_VGUI::configEdit( std::map<float,CTimedEvent*>::iterator iterEdit )
{	CFXBaseTimeProp::configEdit(iterEdit);
	CTimedEventPosition *pPosition = (CTimedEventPosition*)iterEdit->second;
	// Set to selected path
	gViewPort->m_pFXToolPanel->getPathManager()->getPathList()->selectItem(pPosition->getPathManager());
	// Fill options
	getInterpCheck()->SetChecked(pPosition->canInterpTo());
	// Get Path
	CPathManager *pManager = getSelectedPath();
	if(pManager)
	{	// set range and set value
		getDistanceSlider()->setRange(0,pManager->getLength());
		getDistanceSlider()->setValue(pPosition->getDistance());
	}
	
	// Save Distance
	setOldDistance(pPosition->getDistance());

	// set timed velocity data
	if(pPosition->isTimedVelocity())
	{	CTimedEventVelocity *pTimedVel = (CTimedEventVelocity*)pPosition;
		char szText[128];
		sprintf(szText,"%.2f", pTimedVel->getVelocity());
		getVelocityText()->setText(szText,strlen(szText));
	}
}

// Apply Settings ( to edit or new )
CTimedEvent *CFXTimeProp_Position_VGUI::applySettings( CTimedEvent *pEvent )
{	// Get selected path
	CPathManager *pManager = getSelectedPath();
	if(!pManager)
	{	return NULL;
	}

	// Get Data
	bool bInterpolate = getInterpCheck()->IsChecked();
	int iDistance = getDistanceSlider()->getValue();
	float flVel = getTextFloat(getVelocityText());
	// Create position/velocity event, depending
	if(!pEvent)
	{	if(flVel)
			pEvent = new CTimedEventVelocity(pManager->getID(),iDistance,flVel,true);
		else
			pEvent = new CTimedEventPosition(pManager->getID(), iDistance);
	}
	else
	{	// Flip from timed velocity to regular, or vise versa
		if(flVel && !((CTimedEventPosition*)pEvent)->isTimedVelocity())
		{	delete pEvent;
			pEvent = new CTimedEventVelocity(pManager->getID(),iDistance,flVel,true);
		}
		else if(!flVel && ((CTimedEventPosition*)pEvent)->isTimedVelocity())
		{	delete pEvent;
			pEvent = new CTimedEventPosition(pManager->getID(), iDistance);
		}
	}
	
	// Set interpolate
	pEvent->setInterpTo(bInterpolate);
	// Set path
	((CTimedEventPosition*)pEvent)->setPathManager(pManager->getID());
	// set distance
	((CTimedEventPosition*)pEvent)->setDistance(iDistance);
	// set velocity if appropiate
	if(flVel)
		((CTimedEventVelocity*)pEvent)->setVelocity(flVel);

	// Get path info and print
	return pEvent;
}

// Update
void CFXTimeProp_Position_VGUI::Update( void )
{	if(getDistanceSlider())
	{	CPathManager *pManager = getSelectedPath();
		if(pManager)
		{	// HACK HACK: Redo later
			int iRealPathDist = pManager->getLength();
			int iMin, iMax;
			getDistanceSlider()->getRange(iMin,iMax);
			if(iMax != iRealPathDist)
			{	getDistanceSlider()->setRange(0,iRealPathDist);
				getDistanceSlider()->setValue(0);
			}
		}
	}

	// Update event
	if(getEditEvent() != NULL)
	{	CTimedEventPosition *pPosition = (CTimedEventPosition*)getEditEvent()->second;
		if(pPosition)
			pPosition->setDistance(getDistanceSlider()->getValue());
	}
}

// Cancel Settings
void CFXTimeProp_Position_VGUI::cancelSettings( void )
{	// Restore rotation
	if(getEditEvent() != NULL)
	{	((CTimedEventPosition*)getEditEvent()->second)->setDistance(getOldDistance());
	}
}

// Get Selected Path
CPathManager *CFXTimeProp_Position_VGUI::getSelectedPath( void )
{	int iPath = gViewPort->m_pFXToolPanel->getPathManager()->getPathList()->getSelectedLabel();
	if(iPath != -1)
	{	CFXEvent *pEvent = gViewPort->m_pFXToolPanel->getEvent();
		if(pEvent)
		{	return pEvent->getPathSystem()->getManager(iPath);
		}
	}
	return NULL;
}



/*
* Rotation
*/
// Constructor
CFXTimeProp_Rotation_VGUI::CFXTimeProp_Rotation_VGUI(std::string strTitle, int x,int y, bool bCreatePanel, int iTimelineID) : CFXBaseTimeProp(strTitle,x,y,bCreatePanel,iTimelineID)
{	int iStartY=getPadding();

	// Make Interp CheckBox
	setInterpCheck(makeCheckBox("Interpolate: ", iStartY));
	iStartY += DEFAULT_CHECK_TALL + getPadding();

	// Make Added Label
	makeLabel("Added Rotation (YAW/PITCH/ROLL)", iStartY);
	iStartY += DEFAULT_TEXT_TALL + getPadding();

	// Make Added Sliders
	setAddedYawSlider(makeSlider(iStartY, -360, 360));
	getAddedYawSlider()->setValue(0);
	iStartY += DEFAULT_SLIDER_TALL + getPadding();
	setAddedPitchSlider(makeSlider(iStartY, -360, 360));
	getAddedPitchSlider()->setValue(0);
	iStartY += DEFAULT_SLIDER_TALL + getPadding();
	setAddedRollSlider(makeSlider(iStartY, -360, 360));
	getAddedRollSlider()->setValue(0);
	iStartY += DEFAULT_SLIDER_TALL + getPadding();

	// Make Start Rotation Label
	makeLabel("Start Rotation (YAW/PITCH/ROLL)", iStartY);
	iStartY += DEFAULT_TEXT_TALL + getPadding();

	// Make Original Sliders
	setOriginalYawSlider(makeSlider(iStartY, -180, 180));
	getOriginalYawSlider()->setValue(0);
	iStartY += DEFAULT_SLIDER_TALL + getPadding();
	setOriginalPitchSlider(makeSlider(iStartY, -180, 180));
	getOriginalPitchSlider()->setValue(0);
	iStartY += DEFAULT_SLIDER_TALL + getPadding();
	setOriginalRollSlider(makeSlider(iStartY, -180, 180));
	getOriginalRollSlider()->setValue(0);
	iStartY += DEFAULT_SLIDER_TALL + getPadding();
	
	// Resize content
	getContentPanel()->setSize(getContentPanel()->getWide(), iStartY);
	resizeToContentTall();

	// Finish up
	makeFinishButtons();

	// save old rotation
/*	if(!bCreatePanel)
	{	gViewPort->m_pFXToolPanel->setRotationMode(true);
		gViewPort->m_pFXToolPanel->setPropertyEdit(this);
		CFXObject3D *pObj = (CFXObject3D*)gViewPort->m_pFXToolPanel->getEvent()->getObjectByIndex(getObjectID());
		if(pObj)
			setOldRotation((*pObj->getRotation()));
	}*/
}

// Disable
void CFXTimeProp_Rotation_VGUI::Disable( void )
{	// Disable Rotation Mode
/*	if(!isCreatePanel())
	{	gViewPort->m_pFXToolPanel->setRotationMode(false);
		gViewPort->m_pFXToolPanel->setPropertyEdit(NULL);
	}*/
}

// Configure for Edit
void CFXTimeProp_Rotation_VGUI::configEdit( std::map<float,CTimedEvent*>::iterator iterEdit )
{	CFXBaseTimeProp::configEdit(iterEdit);
	CTimedEventRotation *pRotation = (CTimedEventRotation*)iterEdit->second;
	// Set Added Rotations
	if(pRotation->isTimedAddRotation())
	{	CTimedEventAddRotation *pAddedRotation = (CTimedEventAddRotation*)pRotation;
		getAddedYawSlider()->setValue(pAddedRotation->getAddedRotation()[YAW]);
		getAddedPitchSlider()->setValue(pAddedRotation->getAddedRotation()[PITCH]);
		getAddedRollSlider()->setValue(pAddedRotation->getAddedRotation()[ROLL]);
	}

	// Set original rotation
	vec3_t vecRot = pRotation->getRotation()->QuaternionToEuler();
	getOriginalYawSlider()->setValue(vecRot[YAW]);
	getOriginalPitchSlider()->setValue(vecRot[PITCH]);
	getOriginalRollSlider()->setValue(vecRot[ROLL]);
	
	// Save Rotation
	setOldRotation(*pRotation->getRotation());

	// set interp
	getInterpCheck()->SetChecked(pRotation->canInterpTo());
}

// Apply Settings ( to edit or new )
CTimedEvent *CFXTimeProp_Rotation_VGUI::applySettings( CTimedEvent *pEvent )
{	// See if we're going to be making/setting a added rotation timed event
	bool bAddedRot=true;
	if(getAddedYawSlider()->getValue() == 0 && getAddedPitchSlider()->getValue() == 0 && getAddedRollSlider()->getValue() == 0)
	{	bAddedRot=false;
	}
	
	// Make event if it doesnt exist
	if(!pEvent)
	{	if(bAddedRot)
			pEvent = new CTimedEventRotation(vec3_t(0,0,0));
		else
			pEvent = new CTimedEventAddRotation(vec3_t(0,0,0),vec3_t(0,0,0));
	}
	else
	{	// Convert
		if(!bAddedRot && ((CTimedEventRotation*)pEvent)->isTimedAddRotation())
		{	delete pEvent;
			pEvent = new CTimedEventRotation(vec3_t(0,0,0));
		}
		else if(bAddedRot && !((CTimedEventRotation*)pEvent)->isTimedAddRotation())
		{	delete pEvent;
			pEvent = new CTimedEventAddRotation(vec3_t(0,0,0),vec3_t(0,0,0));
		}
	}
	CTimedEventRotation *pRotation = (CTimedEventRotation*)pEvent;
	// Set original rotation
	vec3_t vecRot;
	vecRot[YAW] = getOriginalYawSlider()->getValue();
	vecRot[PITCH] = getOriginalPitchSlider()->getValue();
	vecRot[ROLL] = getOriginalRollSlider()->getValue();
	pRotation->getRotation()->EulerToQuaternion(vecRot);
	// set added angles
	if(bAddedRot)
	{	vec3_t vecAddedRot;
		vecAddedRot[YAW] = getAddedYawSlider()->getValue();
		vecAddedRot[PITCH] = getAddedPitchSlider()->getValue();
		vecAddedRot[ROLL] = getAddedRollSlider()->getValue();
		// Set rotation
		((CTimedEventAddRotation*)pRotation)->setAddedRotation(vecAddedRot);
	}
	// set interpolation check
	pEvent->setInterpTo(getInterpCheck()->IsChecked());

	return pEvent;
}

// Update
void CFXTimeProp_Rotation_VGUI::Update( void )
{	vec3_t vecRot;
	vecRot[YAW] = getOriginalYawSlider()->getValue();
	vecRot[PITCH] = getOriginalPitchSlider()->getValue();
	vecRot[ROLL] = getOriginalRollSlider()->getValue();
	// Update event
	if(getEditEvent() != NULL)
	{	CTimedEventRotation *pRotation = (CTimedEventRotation*)getEditEvent()->second;
		if(pRotation)
			pRotation->getRotation()->EulerToQuaternion(vecRot);
	}
}

// Cancel Settings
void CFXTimeProp_Rotation_VGUI::cancelSettings( void )
{	// Restore rotation
	if(getEditEvent() != NULL)
	{	((CTimedEventRotation*)getEditEvent()->second)->getRotation()->setQuaternion(getOldRotation());
	}
}

/*
* Alpha
*/
// Constructor
CFXTimeProp_Alpha_VGUI::CFXTimeProp_Alpha_VGUI(std::string strTitle, int x,int y, bool bCreatePanel, int iTimelineID) : CFXBaseTimeProp(strTitle,x,y,bCreatePanel,iTimelineID)
{	int iStartY=getPadding();

	// Make Interp CheckBox
	setInterpCheck(makeCheckBox("Interpolate: ", iStartY));
	iStartY += DEFAULT_CHECK_TALL + getPadding();

	// Make Alpha Label
	makeLabel("Alpha", iStartY);
	iStartY += DEFAULT_TEXT_TALL + getPadding();

	// Make Alpha Slider
	setAlphaSlider(makeSlider(iStartY, 0, 255));
	iStartY += DEFAULT_SLIDER_TALL + getPadding();
	
	// Resize content
	getContentPanel()->setSize(getContentPanel()->getWide(), iStartY);
	resizeToContentTall();

	// Finish up
	makeFinishButtons();
}

// Configure for Edit
void CFXTimeProp_Alpha_VGUI::configEdit( std::map<float,CTimedEvent*>::iterator iterEdit )
{	CFXBaseTimeProp::configEdit(iterEdit);
	CTimedEventAlpha *pAlpha = (CTimedEventAlpha*)iterEdit->second;
	// set interp and alpha on slider
	getInterpCheck()->SetChecked(pAlpha->canInterpTo());
	getAlphaSlider()->setValue(pAlpha->getAlpha());
}

// Apply Settings ( to edit or new )
CTimedEvent *CFXTimeProp_Alpha_VGUI::applySettings( CTimedEvent *pEvent )
{	if(!pEvent)
		pEvent = new CTimedEventAlpha(0);
	pEvent->setInterpTo(getInterpCheck()->IsChecked());
	((CTimedEventAlpha*)pEvent)->setAlpha(getAlphaSlider()->getValue());
	return pEvent;
}

/*
* Color
*/
// Constructor
CFXTimeProp_Color_VGUI::CFXTimeProp_Color_VGUI(std::string strTitle, int x,int y, bool bCreatePanel, int iTimelineID) : CFXBaseTimeProp(strTitle,x,y,bCreatePanel,iTimelineID)
{	int iStartY=getPadding();
	Label *pColor = NULL;

	// Make Interp CheckBox
	setInterpCheck(makeCheckBox("Interpolate: ", iStartY));
	iStartY += DEFAULT_CHECK_TALL + getPadding();

	// Make Red Label
	pColor = makeLabel("Red", iStartY);
	pColor->setFgColor( 255,30,30,0 );
	iStartY += DEFAULT_TEXT_TALL + getPadding();

	// Make R Slider
	setRSlider(makeSlider(iStartY, 0, 255));
	iStartY += DEFAULT_SLIDER_TALL + getPadding();

	// Make Green Label
	pColor = makeLabel("Green", iStartY);
	pColor->setFgColor( 30,255,30,0 );
	iStartY += DEFAULT_TEXT_TALL + getPadding();

	// Make G Slider
	setGSlider(makeSlider(iStartY, 0, 255));
	iStartY += DEFAULT_SLIDER_TALL + getPadding();

	// Make Blue Label
	pColor = makeLabel("Blue", iStartY);
	pColor->setFgColor( 30,30,255,0 );
	iStartY += DEFAULT_TEXT_TALL + getPadding();

	// Make B Slider
	setBSlider(makeSlider(iStartY, 0, 255));
	iStartY += DEFAULT_SLIDER_TALL + getPadding();

	// Make Preview Label
	setPreviewLabel(makeLabel("", iStartY));
	iStartY += DEFAULT_TEXT_TALL + getPadding();
	
	// Resize content
	getContentPanel()->setSize(getContentPanel()->getWide(), iStartY);
	resizeToContentTall();

	// Finish up
	makeFinishButtons();
}

// Configure for Edit
void CFXTimeProp_Color_VGUI::configEdit( std::map<float,CTimedEvent*>::iterator iterEdit )
{	CFXBaseTimeProp::configEdit(iterEdit);
	CTimedEventColor *pColor = (CTimedEventColor*)iterEdit->second;
	// set interp and color sliders
	getInterpCheck()->SetChecked(pColor->canInterpTo());
	getRSlider()->setValue(pColor->getColor()->getR());
	getGSlider()->setValue(pColor->getColor()->getG());
	getBSlider()->setValue(pColor->getColor()->getB());
}

// Apply Settings ( to edit or new )
CTimedEvent *CFXTimeProp_Color_VGUI::applySettings( CTimedEvent *pEvent )
{	if(!pEvent)
		pEvent = new CTimedEventColor(0,0,0);
	pEvent->setInterpTo(getInterpCheck()->IsChecked());
	// Set color
	int r=getRSlider()->getValue(),g=getGSlider()->getValue(),b=getBSlider()->getValue();
	((CTimedEventColor*)pEvent)->getColor()->setColor(r,g,b);
	return pEvent;
}

// Update
void CFXTimeProp_Color_VGUI::Update( void )
{	// Update preview color label
	if(getPreviewLabel())
	{	getPreviewLabel()->setBgColor( getRSlider()->getValue(), getGSlider()->getValue(), getBSlider()->getValue(), 0 );
	}
}

/*
* Size
*/

// Constructor
CFXTimeProp_Size_VGUI::CFXTimeProp_Size_VGUI(std::string strTitle, int x,int y, bool bCreatePanel, int iTimelineID) : CFXBaseTimeProp(strTitle,x,y,bCreatePanel,iTimelineID)
{	int iStartY=getPadding();

	// Make Interp CheckBox
	setInterpCheck(makeCheckBox("Interpolate: ", iStartY));
	iStartY += DEFAULT_CHECK_TALL + getPadding();

	// Make Size Label
	makeLabel("Size", iStartY);
	iStartY += DEFAULT_TEXT_TALL + getPadding();

	// Make Size Text
	setSizeText(makeTextEntry(iStartY));
	iStartY += DEFAULT_SLIDER_TALL + getPadding();
	
	// Resize content
	getContentPanel()->setSize(getContentPanel()->getWide(), iStartY);
	resizeToContentTall();

	// Finish up
	makeFinishButtons();
}

// Configure for Edit
void CFXTimeProp_Size_VGUI::configEdit( std::map<float,CTimedEvent*>::iterator iterEdit )
{	CFXBaseTimeProp::configEdit(iterEdit);
	CTimedEventSize *pSize = (CTimedEventSize*)iterEdit->second;
	// set interp and size in text box
	getInterpCheck()->SetChecked(pSize->canInterpTo());
	char szText[256];
	sprintf(szText,"%.2f", pSize->getSize());
	getSizeText()->setText(szText,strlen(szText));
}

// Apply Settings ( to edit or new )
CTimedEvent *CFXTimeProp_Size_VGUI::applySettings( CTimedEvent *pEvent )
{	if(!pEvent)
		pEvent = new CTimedEventSize(0);
	pEvent->setInterpTo(getInterpCheck()->IsChecked());
	((CTimedEventSize*)pEvent)->setSize(getTextFloat(getSizeText()));
	return pEvent;
}

/*
* Framerate Multiplier
*/
// Constructor
CFXTimeProp_FrameMulti_VGUI::CFXTimeProp_FrameMulti_VGUI(std::string strTitle, int x,int y, bool bCreatePanel, int iTimelineID) : CFXBaseTimeProp(strTitle,x,y,bCreatePanel,iTimelineID)
{	int iStartY=getPadding();

	// Make Frame Multi Label
	makeLabel("Frame Multiplier", iStartY);
	iStartY += DEFAULT_TEXT_TALL + getPadding();

	// Make Frame Multi Text
	setFrameMultiText(makeTextEntry(iStartY));
	iStartY += DEFAULT_SLIDER_TALL + getPadding();
	
	// Resize content
	getContentPanel()->setSize(getContentPanel()->getWide(), iStartY);
	resizeToContentTall();

	// Finish up
	makeFinishButtons();
}

// Configure for Edit
void CFXTimeProp_FrameMulti_VGUI::configEdit( std::map<float,CTimedEvent*>::iterator iterEdit )
{	CFXBaseTimeProp::configEdit(iterEdit);
	CTimedEventFrameMulti *pFrameMulti = (CTimedEventFrameMulti*)iterEdit->second;
	// set frame multi in text box
	char szText[256];
	sprintf(szText,"%.2f", pFrameMulti->getMutli());
	getFrameMultiText()->setText(szText,strlen(szText));
}

// Apply Settings ( to edit or new )
CTimedEvent *CFXTimeProp_FrameMulti_VGUI::applySettings( CTimedEvent *pEvent )
{	if(!pEvent)
		pEvent = new CTimedEventFrameMulti(0);
	((CTimedEventFrameMulti*)pEvent)->setMulti(getTextFloat(getFrameMultiText()));
	return pEvent;
}

/*
* Bodypart
*/
// Constructor
CFXTimeProp_BodyPart_VGUI::CFXTimeProp_BodyPart_VGUI(std::string strTitle, int x,int y, bool bCreatePanel, int iTimelineID) : CFXBaseTimeProp(strTitle,x,y,bCreatePanel,iTimelineID)
{	int iStartY=getPadding();

	// Make Body Part Label
	makeLabel("Body Part", iStartY);
	iStartY += DEFAULT_TEXT_TALL + getPadding();

	// Make Body Part Text
	setBodyPartText(makeTextEntry(iStartY));
	iStartY += DEFAULT_SLIDER_TALL + getPadding();
	
	// Resize content
	getContentPanel()->setSize(getContentPanel()->getWide(), iStartY);
	resizeToContentTall();

	// Finish up
	makeFinishButtons();
}

// Configure for Edit
void CFXTimeProp_BodyPart_VGUI::configEdit( std::map<float,CTimedEvent*>::iterator iterEdit )
{	CFXBaseTimeProp::configEdit(iterEdit);
	CTimedEventBodyPart *pBodyPart = (CTimedEventBodyPart*)iterEdit->second;
	// set frame multi in text box
	char szText[256];
	sprintf(szText,"%i", pBodyPart->getBodyPart());
	getBodyPartText()->setText(szText,strlen(szText));
}

// Apply Settings ( to edit or new )
CTimedEvent *CFXTimeProp_BodyPart_VGUI::applySettings( CTimedEvent *pEvent )
{	if(!pEvent)
		pEvent = new CTimedEventBodyPart(0);
	((CTimedEventBodyPart*)pEvent)->setBodyPart(getTextFloat(getBodyPartText()));
	return pEvent;
}

/*
* Model Blur
*/
// Constructor
CFXTimeProp_ModelBlur_VGUI::CFXTimeProp_ModelBlur_VGUI(std::string strTitle, int x,int y, bool bCreatePanel, int iTimelineID) : CFXBaseTimeProp(strTitle,x,y,bCreatePanel,iTimelineID)
{	int iStartY=getPadding();

	// Make Model Blur CheckBox
	setBlurCheck(makeCheckBox("Model Blur: ", iStartY));
	iStartY += DEFAULT_CHECK_TALL + getPadding();
	
	// Resize content
	getContentPanel()->setSize(getContentPanel()->getWide(), iStartY);
	resizeToContentTall();

	// Finish up
	makeFinishButtons();
}

// Configure for Edit
void CFXTimeProp_ModelBlur_VGUI::configEdit( std::map<float,CTimedEvent*>::iterator iterEdit )
{	CFXBaseTimeProp::configEdit(iterEdit);
	CTimedEventModelBlur *pBlur = (CTimedEventModelBlur*)iterEdit->second;
	// set blur
	getBlurCheck()->SetChecked(pBlur->getBlur());
}

// Apply Settings ( to edit or new )
CTimedEvent *CFXTimeProp_ModelBlur_VGUI::applySettings( CTimedEvent *pEvent )
{	if(!pEvent)
		pEvent = new CTimedEventModelBlur(false);
	((CTimedEventModelBlur*)pEvent)->setBlur(getBlurCheck()->IsChecked());
	return pEvent;
}

/*
* Sequence
*/
// Constructor
CFXTimeProp_Sequence_VGUI::CFXTimeProp_Sequence_VGUI(std::string strTitle, int x,int y, bool bCreatePanel, int iTimelineID) : CFXBaseTimeProp(strTitle,x,y,bCreatePanel,iTimelineID)
{	int iStartY=getPadding();

	// Make Loop CheckBox
	setLoopCheck(makeCheckBox("Loop: ", iStartY));
	iStartY += DEFAULT_CHECK_TALL + getPadding();

	// Make Animation Label
	makeLabel("Animation", iStartY);
	iStartY += DEFAULT_TEXT_TALL + getPadding();

	// Make Animation Text
	setSequenceText(makeTextEntry(iStartY));
	iStartY += DEFAULT_SLIDER_TALL + getPadding();
	
	// Resize content
	getContentPanel()->setSize(getContentPanel()->getWide(), iStartY);
	resizeToContentTall();

	// Finish up
	makeFinishButtons();
}

// Configure for Edit
void CFXTimeProp_Sequence_VGUI::configEdit( std::map<float,CTimedEvent*>::iterator iterEdit )
{	CFXBaseTimeProp::configEdit(iterEdit);
	CTimedEventSequence *pSequence = (CTimedEventSequence*)iterEdit->second;
	// set loop and animation in text box
	getLoopCheck()->SetChecked(pSequence->canLoop());
	// Find animation string and put it in text box
	CFXObjectMDL *pMdl = (CFXObjectMDL*)gViewPort->m_pFXToolPanel->getEvent()->getObjectByIndex(getObjectID());
	if(pMdl)
	{	CMDLControl *pCtrl = pMdl->getModelControl();
		if(pCtrl)
		{/*	mstudioseqdesc_t *pseqdesc = pCtrl->getSequenceDesc(pSequence->getSequence());
			if(pseqdesc)
			{	getSequenceText()->setText(pseqdesc->label,strlen(pseqdesc->label));
			}*/
			getSequenceText()->setText(pSequence->getSequence().c_str(), pSequence->getSequence().length());
		}
	}
}

// Apply Settings ( to edit or new )
CTimedEvent *CFXTimeProp_Sequence_VGUI::applySettings( CTimedEvent *pEvent )
{	if(!pEvent)
		pEvent = new CTimedEventSequence(0,true);
	// Set loop
	((CTimedEventSequence*)pEvent)->setLoop(getLoopCheck()->IsChecked());
	// Set sequence
	((CTimedEventSequence*)pEvent)->setSequence(getText(getSequenceText()));
	return pEvent;
}

/*
* Sound
*/
// Constructor
CFXTimeProp_Sound_VGUI::CFXTimeProp_Sound_VGUI(std::string strTitle, int x,int y, bool bCreatePanel, int iTimelineID) : CFXBaseTimeProp(strTitle,x,y,bCreatePanel,iTimelineID)
{	int iStartY=getPadding();

	// Make Sound Label
	makeLabel("*.wav file", iStartY);
	iStartY += DEFAULT_TEXT_TALL + getPadding();

	// Make Sound Text
	setSoundText(makeTextEntry(iStartY));
	iStartY += DEFAULT_TEXT_TALL + getPadding();

	// Make Channel Label
	makeLabel("Channel", iStartY);
	iStartY += DEFAULT_TEXT_TALL + getPadding();

	// Make Channel Text
	setChannelText(makeTextEntry(iStartY));
	iStartY += DEFAULT_TEXT_TALL + getPadding();
	
	// Resize content
	getContentPanel()->setSize(getContentPanel()->getWide(), iStartY);
	resizeToContentTall();

	// Finish up
	makeFinishButtons();
}

// Configure for Edit
void CFXTimeProp_Sound_VGUI::configEdit( std::map<float,CTimedEvent*>::iterator iterEdit )
{	CFXBaseTimeProp::configEdit(iterEdit);
	CTimedEventSound *pSound = (CTimedEventSound*)iterEdit->second;
	// set loop and animation in text box
	getSoundText()->setText(pSound->getSound().c_str(),pSound->getSound().length());
	char szChannel[8];
	sprintf(szChannel,"%i",pSound->getChannelIndex());
	getChannelText()->setText(szChannel,strlen(szChannel));
}

// Apply Settings ( to edit or new )
CTimedEvent *CFXTimeProp_Sound_VGUI::applySettings( CTimedEvent *pEvent )
{	if(!pEvent)
		pEvent = new CTimedEventSound();
	
	// Set Sound
	((CTimedEventSound*)pEvent)->setSound(getText(getSoundText()));
	((CTimedEventSound*)pEvent)->setChannelIndex(int(getTextFloat(getChannelText())));

	return pEvent;
}








/*
* Sound Stream
*/
// Constructor
CFXTimeProp_SoundStream_VGUI::CFXTimeProp_SoundStream_VGUI(std::string strTitle, int x,int y, bool bCreatePanel, int iTimelineID) : CFXBaseTimeProp(strTitle,x,y,bCreatePanel,iTimelineID)
{	int iStartY=getPadding();

	// Make Sound Label
	makeLabel("sound file", iStartY);
	iStartY += DEFAULT_TEXT_TALL + getPadding();

	// Make Sound Text
	setSoundStreamText(makeTextEntry(iStartY));
	iStartY += DEFAULT_TEXT_TALL + getPadding();
	
	// Resize content
	getContentPanel()->setSize(getContentPanel()->getWide(), iStartY);
	resizeToContentTall();

	// Finish up
	makeFinishButtons();
}

// Configure for Edit
void CFXTimeProp_SoundStream_VGUI::configEdit( std::map<float,CTimedEvent*>::iterator iterEdit )
{	CFXBaseTimeProp::configEdit(iterEdit);
	CTimedEventSoundStream *pSoundStream = (CTimedEventSoundStream*)iterEdit->second;
	// set loop and animation in text box
	getSoundStreamText()->setText(pSoundStream->getStreamFile().c_str(),pSoundStream->getStreamFile().length());
}

// Apply Settings ( to edit or new )
CTimedEvent *CFXTimeProp_SoundStream_VGUI::applySettings( CTimedEvent *pEvent )
{	if(!pEvent)
		pEvent = new CTimedEventSoundStream();
	
	// Set Sound
	((CTimedEventSoundStream*)pEvent)->setStreamFile(getText(getSoundStreamText()));

	return pEvent;
}

/*
* Volume
*/
// Constructor
CFXTimeProp_Volume_VGUI::CFXTimeProp_Volume_VGUI(std::string strTitle, int x,int y, bool bCreatePanel, int iTimelineID) : CFXBaseTimeProp(strTitle,x,y,bCreatePanel,iTimelineID)
{	int iStartY=getPadding();

	// Make Interp CheckBox
	setInterpCheck(makeCheckBox("Interpolate: ", iStartY));
	iStartY += DEFAULT_CHECK_TALL + getPadding();

	// Make Alpha Label
	makeLabel("Volume", iStartY);
	iStartY += DEFAULT_TEXT_TALL + getPadding();

	// Make Alpha Slider
	setVolumeSlider(makeSlider(iStartY, 0, 100));
	iStartY += DEFAULT_SLIDER_TALL + getPadding();
	
	// Resize content
	getContentPanel()->setSize(getContentPanel()->getWide(), iStartY);
	resizeToContentTall();

	// Finish up
	makeFinishButtons();
}

// Configure for Edit
void CFXTimeProp_Volume_VGUI::configEdit( std::map<float,CTimedEvent*>::iterator iterEdit )
{	CFXBaseTimeProp::configEdit(iterEdit);
	CTimedEventVolume *pVolume = (CTimedEventVolume*)iterEdit->second;
	// set interp and Volume on slider
	getInterpCheck()->SetChecked(pVolume->canInterpTo());
	getVolumeSlider()->setValue(pVolume->getVolume());
}

// Apply Settings ( to edit or new )
CTimedEvent *CFXTimeProp_Volume_VGUI::applySettings( CTimedEvent *pEvent )
{	if(!pEvent)
		pEvent = new CTimedEventVolume(0);
	pEvent->setInterpTo(getInterpCheck()->IsChecked());
	((CTimedEventVolume*)pEvent)->setVolume(getVolumeSlider()->getValue());
	return pEvent;
}

/*
* Radial Blur
*/
// Constructor
CFXTimeProp_RadialBlur_VGUI::CFXTimeProp_RadialBlur_VGUI(std::string strTitle, int x,int y, bool bCreatePanel, int iTimelineID) : CFXBaseTimeProp(strTitle,x,y,bCreatePanel,iTimelineID)
{	int iStartY=getPadding();

	// Make Interp CheckBox
	setInterpCheck(makeCheckBox("Interpolate: ", iStartY));
	iStartY += DEFAULT_CHECK_TALL + getPadding();

	// Make RadialBlur Label
	makeLabel("Radial Blur", iStartY);
	iStartY += DEFAULT_TEXT_TALL + getPadding();

	// Make RadialBlur Slider
	setRadialBlurSlider(makeSlider(iStartY, 0, 1));
	iStartY += DEFAULT_SLIDER_TALL + getPadding();
	
	// Resize content
	getContentPanel()->setSize(getContentPanel()->getWide(), iStartY);
	resizeToContentTall();

	// Finish up
	makeFinishButtons();
}

// Configure for Edit
void CFXTimeProp_RadialBlur_VGUI::configEdit( std::map<float,CTimedEvent*>::iterator iterEdit )
{	CFXBaseTimeProp::configEdit(iterEdit);
	CTimedEventRadialBlur *pRadialBlur = (CTimedEventRadialBlur*)iterEdit->second;
	// set interp and RadialBlur on slider
	getInterpCheck()->SetChecked(pRadialBlur->canInterpTo());
	getRadialBlurSlider()->setValue(pRadialBlur->getBlur());
}

// Apply Settings ( to edit or new )
CTimedEvent *CFXTimeProp_RadialBlur_VGUI::applySettings( CTimedEvent *pEvent )
{	if(!pEvent)
		pEvent = new CTimedEventRadialBlur(0);
	pEvent->setInterpTo(getInterpCheck()->IsChecked());
	((CTimedEventRadialBlur*)pEvent)->setBlur(getRadialBlurSlider()->getValue());
	return pEvent;
}