/*
* FX Tool Panel
* @version 3-07-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_fxtoolpanel.h"
#include <vgui_slider.h>
#include "vgui_fxtimelineprop.h"

// TEMP: Time used to link to event system
//extern float gEventTimeTest;
extern vec3_t g_CamOrigin;
extern vec3_t g_CamAngles;

#define EDIT_PANELS_START_X	300
#define EDIT_PANELS_START_Y	100

#define TITLE_HEIGHT	24
#define HIDE_BUTTON_PAD	4

/*
* FX Panel
*/
// Hide panel action
class HidePanelAction : public ActionSignal
{
public:
	HidePanelAction( )
	{	m_pFXPanel = NULL;
	}

	HidePanelAction( CFXPanel *pFXPanel )
	{	m_pFXPanel = pFXPanel;
	}

	virtual void actionPerformed(Panel* panel)
	{	if(m_pFXPanel)
		{	// Hidden, unhide
			if(m_pFXPanel->getHideStatus())
			{	// Resize to normal size
				m_pFXPanel->resizeToContentTall();
				// Set content panel to visible
				m_pFXPanel->getContentPanel()->setVisible(true);
				// Set hide status
				m_pFXPanel->setHideStatus(false);
				// Set Text (sign)
				m_pFXPanel->getHideButton()->setText("-");
			}
			// Hide
			else
			{	// Set content panel to not-visible
				m_pFXPanel->getContentPanel()->setVisible(false);
				// resize to size of title bar
				m_pFXPanel->setSize(m_pFXPanel->getWide(), TITLE_HEIGHT+3);
				// Set hide status
				m_pFXPanel->setHideStatus(true);
				// Set Text (sign)
				m_pFXPanel->getHideButton()->setText("+");
			}
			// Do align check
			gViewPort->m_pFXToolPanel->alignCheck();
		}
	}
private:
	CFXPanel *m_pFXPanel;
};

// Drag FX Box Input Signal
class CFXDragPanelSignal : public InputSignal
{
public:
	// Constructors
	CFXDragPanelSignal()
	{	setFXPanel(NULL);
	}
	CFXDragPanelSignal( CFXPanel *pPanel )
	{	setFXPanel(pPanel);
	}

	// Mouse pressed
	virtual void mousePressed(MouseCode code,Panel* panel) 
	{	if(getFXPanel())
		{	getFXPanel()->dragClick();
		}
	}

	virtual void cursorMoved(int x,int y,Panel* panel) {}
	virtual void cursorEntered(Panel* panel) {}
	virtual void cursorExited(Panel* panel) { }
	virtual void mouseDoublePressed(MouseCode code,Panel* panel) {}
	virtual void mouseWheeled(int delta,Panel* panel) {}
	virtual void mouseReleased(MouseCode code,Panel* panel) { }
	virtual void keyPressed(KeyCode code,Panel* panel) {}
	virtual void keyTyped(KeyCode code,Panel* panel) {}
	virtual void keyReleased(KeyCode code,Panel* panel) {}
	virtual void keyFocusTicked(Panel* panel) {}

	// Accessors
	void setFXPanel( CFXPanel *pPanel ) { m_pFXPanel = pPanel; }
	CFXPanel *getFXPanel ( void ) { return m_pFXPanel; }
private:
	CFXPanel *m_pFXPanel;
};

// Constructor
CFXPanel::CFXPanel(std::string strTitle, int x,int y,int wide,int tall) : CTransparentPanel(0, x, y, wide, tall)
{
	// Set main panels border
	setBorder( new LineBorder( Color(255 * 0.7,170 * 0.7,0,0) ) );

	// get local width/height
	wide = getWide();
	tall = getTall();
	
	// Set title
	Label *pTitle = new Label( strTitle.c_str(), 0, 0, wide-1, TITLE_HEIGHT);
	pTitle->setParent( this );
	pTitle->setBgColor( 0, 0, 200, 150 );
	pTitle->setFgColor( 200, 200, 200, 100 );
	pTitle->setContentAlignment( vgui::Label::a_center );
	pTitle->addInputSignal(new CFXDragPanelSignal(this));
	setTitle(pTitle);

	// Create hide button
	int iButtonSize = TITLE_HEIGHT - HIDE_BUTTON_PAD*2;
	CommandButton *pButton = new CommandButton("-", wide-HIDE_BUTTON_PAD-iButtonSize-1, HIDE_BUTTON_PAD, iButtonSize, iButtonSize);
	pButton->setParent( this );
	pButton->setContentAlignment(vgui::Label::a_center);
	pButton->addActionSignal( new HidePanelAction(this) );
	setHideButton(pButton);
	setHideStatus(false);

	// Reset drag varibles
	setDraggingStatus( false );
	setDragStartPos( Vector2D(0,0) );

	// Set content panel
	CTransparentPanel *pContentPanel = new CTransparentPanel( 200, 0, TITLE_HEIGHT, wide-1, tall-TITLE_HEIGHT);
	pContentPanel->setParent( this );
	pContentPanel->setBorder( NULL );
	setContentPanel(pContentPanel);
}

// Align left
void CFXPanel::alignLeft( int iLeftX )
{	int x,y;
	getPos(x,y);
	setPos(iLeftX,y);
}

// Align right
void CFXPanel::alignRight( int iRightX )
{	int x,y;
	getPos(x,y);
	setPos(iRightX-getWide(),y);
}

// Align bottom
void CFXPanel::alignBottom( int iBottomY )
{	int x,y;
	getPos(x,y);
	setPos(x,iBottomY-getTall());
}

// Align top
void CFXPanel::alignTop( int iTopY )
{	int x,y;
	getPos(x,y);
	setPos(x,iTopY);
}

// Resize to content wide
void CFXPanel::resizeToContentWide( void )
{	setSize(getContentPanel()->getWide(), getTall());
	// resize title bar
	getTitle()->setSize(getWide(),getTitle()->getTall());

	// Replace hide button
	int iButtonSize = TITLE_HEIGHT - HIDE_BUTTON_PAD*2;
	getHideButton()->setPos(getWide()-HIDE_BUTTON_PAD-iButtonSize-1,HIDE_BUTTON_PAD);
}

// Resize to content tall
void CFXPanel::resizeToContentTall( void )
{	setSize(getWide(), TITLE_HEIGHT+getContentPanel()->getTall());
}

// Resize to content wide
void CFXPanel::resizeToContent( void )
{	resizeToContentWide();
	resizeToContentTall();
}

// Drag Click
void CFXPanel::dragClick( void )
{	int x,y;
	if(canDrag() && !getDraggingStatus())
	{	// Enable dragging
		setDraggingStatus( true );
		// Set start drag pos
		App::getInstance()->getCursorPos(x,y);
		setDragStartPos( Vector2D(x,y) );
	}
}

// Drag Release
void CFXPanel::dragRelease( void )
{	if(getDraggingStatus())
	{	// Disable dragging and reset vars
		setDraggingStatus( false );
		setDragStartPos( Vector2D(0,0) );
	}
}

// Drag Think
extern CMouseCapture g_MouseCap;
void CFXPanel::dragThink( void )
{	if(getDraggingStatus())
	{	// Only drag as long as we hold down mouse 1
		if(g_MouseCap.getStatus(0))
		{	int x,y;
			Vector2D vecCursor, vecPanel;
			// Get cursor and panel pos
			App::getInstance()->getCursorPos(x,y);
			vecCursor = Vector2D(x,y);
			getPos(x,y);
			vecPanel = Vector2D(x,y);
			// Get move offset and reset drag pos
			vecPanel = vecPanel + (vecCursor - getDragStartPos());
			setDragStartPos(vecCursor);
			// move panel
			setPos(vecPanel.x,vecPanel.y);
		}
		else
		{	dragRelease();
		}
	}
}

// Hacked scroll panel constructor
CFXScrollPanel::CFXScrollPanel(int x,int y,int wide,int tall) : CTFScrollPanel(x,y,wide,tall)
{
}

/*
* List Box
*/

// List box click
class CFXListBoxLabelClick : public InputSignal
{
public:
	// Constructors
	CFXListBoxLabelClick()
	{	setListBox(NULL);
	}
	CFXListBoxLabelClick( CFXListBox *pList )
	{	setListBox(pList);
	}

	// Mouse pressed
	virtual void mousePressed(MouseCode code,Panel* panel) 
	{	if(getListBox())
		{	getListBox()->mouseClick();
		}
	}

	virtual void cursorMoved(int x,int y,Panel* panel) {}
	virtual void cursorEntered(Panel* panel) {}
	virtual void cursorExited(Panel* panel) {}
	virtual void mouseDoublePressed(MouseCode code,Panel* panel) {}
	virtual void mouseReleased(MouseCode code,Panel* panel) {}
	virtual void mouseWheeled(int delta,Panel* panel) {}
	virtual void keyPressed(KeyCode code,Panel* panel) {}
	virtual void keyTyped(KeyCode code,Panel* panel) {}
	virtual void keyReleased(KeyCode code,Panel* panel) {}
	virtual void keyFocusTicked(Panel* panel) {}

	// Accessors
	void setListBox( CFXListBox *pList ) { m_pListBox = pList; }
	CFXListBox *getListBox ( void ) { return m_pListBox; }
private:
	CFXListBox *m_pListBox;
};

#define LISTBOX_ROWHEIGHT	20
// Constructor
CFXListBox::CFXListBox(int x,int y,int wide,int tall) : CFXScrollPanel(x,y,wide,tall)
{	setRowHeight(LISTBOX_ROWHEIGHT);
	setSelectedLabel(-1);
	setMouseOverLabel(-1);
	// Set options
	setScrollBarAutoVisible(false, false);
	setScrollBarVisible(false, true);
	setBorder( new LineBorder( Color(255 * 0.7,170 * 0.7,0,0) ) );
	validate();
}

// Add item
#define LISTBOX_RIGHTOFFSET 2
void CFXListBox::addItem( int idx, std::string strText )
{	// Create new label
	Label *pLabel = new  Label( strText.c_str(), 0, getItemList()->size()*getRowHeight(), getClient()->getWide()-LISTBOX_RIGHTOFFSET, getRowHeight());
	pLabel->setContentAlignment( vgui::Label::a_west );
	// Set colors
	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) ) );
	// Set parent
	pLabel->setParent(getClient());
	pLabel->addInputSignal(new CFXListBoxLabelClick(this));

	// Create new item and add
	fxlistboxitem_s newitem;
	newitem.m_iIndex = idx;
	newitem.m_pLabel = pLabel;
	getItemList()->push_back(newitem);

	realignItems();
}

// Realign items inside listbox
void CFXListBox::realignItems( void )
{	std::list<fxlistboxitem_s>::iterator iterCurrent;
	int iNum=0;
	ForEachIn(iterCurrent, (*getItemList()))
	{	Label *pLabel = iterCurrent->m_pLabel;
		// Reset size
		pLabel->setSize(getClientClip()->getWide()-LISTBOX_RIGHTOFFSET, getRowHeight());
		// Reset position
		pLabel->setPos(0,iNum*getRowHeight());
		// Remove highlight
		removeHighlight(pLabel);
		// Inc
		iNum++;
	}
	// Reset selections
	setSelectedLabel(-1);
	setMouseOverLabel(-1);
	validate();
}

// Remove item
void CFXListBox::removeItem( int idx )
{	std::list<fxlistboxitem_s>::iterator iterRemove;
	ForEachIn(iterRemove, (*getItemList()))
	{	if(iterRemove->m_iIndex == idx)
		{	getClient()->removeChild(iterRemove->m_pLabel);
			getItemList()->erase(iterRemove);
			break;
		}
	}
	realignItems();
}

// Remove all items
void CFXListBox::removeAll( void )
{	std::list<fxlistboxitem_s>::iterator iterRemove;
	ForEachIn(iterRemove, (*getItemList()))
	{	getClient()->removeChild(iterRemove->m_pLabel);
	}
	getItemList()->clear();
}

// Get mouse enter status
bool CFXListBox::getMouseEntered( void )
{	int x,y;
	App::getInstance()->getCursorPos(x,y);
	screenToLocal(x,y);
	if(x > 0 && y > 0 && x < getClientClip()->getWide() && y < getClientClip()->getTall())
	{	return true;
	}
	return false;
}

// Get mouse over label slect
fxlistboxitem_s *CFXListBox::getMouseOverLabelSelect( void )
{	if(getMouseEntered())
	{	int x,y;
		App::getInstance()->getCursorPos(x,y);
		getClient()->screenToLocal(x,y);
		std::list<fxlistboxitem_s>::iterator iterCurrent;
		ForEachIn(iterCurrent, (*getItemList()))
		{	Label *pLabel = iterCurrent->m_pLabel;
			int xl,yl;
			pLabel->getPos(xl,yl);
			// Label is selected
			if(x>xl && y>yl && x<xl+pLabel->getWide() && y<yl+pLabel->getTall())
			{	return (&(*iterCurrent));
			}
		}
	}
	return NULL;
}

// Mouse Click (called by inputsignal)
void CFXListBox::mouseClick( void )
{	fxlistboxitem_s *pMouseOver = getMouseOverLabelSelect();
	if(pMouseOver)
	{	// Select Label
		selectItem(pMouseOver->m_iIndex);
	}
}

// Get label by index
Label *CFXListBox::getLabelByIndex( int idx )
{	std::list<fxlistboxitem_s>::iterator iterCurrent;
	ForEachIn(iterCurrent, (*getItemList()))
	{	if(iterCurrent->m_iIndex == idx)
		{	return iterCurrent->m_pLabel;
		}
	}
	return NULL;
}

// Select item
void CFXListBox::selectItem( int idx )
{	// Already selected
	if(isSelected(idx))
	{	return;
	}
	// Remove select
	if(getSelectedLabel() != -1)
	{	removeHighlight(getLabelByIndex(getSelectedLabel()));
	}
	if(idx != -1)
	{	// Remove mouseover
		if(isMousedOver(idx))
			mouseOverItem(-1);
		// Set new label
		setSelectedLabel(idx);
		// Highlight
		addHighlight(getLabelByIndex(idx), getSelectColor());
	}
}

// Mouse Over item
void CFXListBox::mouseOverItem( int idx )
{	// Already moused over
	if(isMousedOver(idx))
	{	return;
	}
	// Remove mouse over
	if(getMouseOverLabel() != -1)
	{	removeHighlight(getLabelByIndex(getMouseOverLabel()));
	}
	// Make sure we're not trying to change the color of the selected label
	if(idx != -1 && idx != getSelectedLabel())
	{	// Set new label
		setMouseOverLabel(idx);
		// Highlight
		addHighlight(getLabelByIndex(idx), getMouseOverColor());
		return;
	}
	setMouseOverLabel(-1);
}

// Is Moused Over
bool CFXListBox::isSelected( int idx )
{	if(getSelectedLabel() == -1)
		return false;
	if(getSelectedLabel() == idx)
		return true;
	return false;
}

// Is Moused Over
bool CFXListBox::isMousedOver( int idx )
{	if(getMouseOverLabel() == -1)
		return false;
	if(getMouseOverLabel() == idx)
		return true;
	return false;
}

// Add Highlight
void CFXListBox::addHighlight( Label *pLabel, Color color )
{	if(!pLabel)
	{	return;
	}
	pLabel->setBgColor(color[0],color[1],color[2],color[3]);
}

// Remove Highlight
void CFXListBox::removeHighlight( Label *pLabel )
{	if(!pLabel)
	{	return;
	}
	pLabel->setBgColor( 0, 0, 0, 255 );
}

// Update
void CFXListBox::Update( void )
{	fxlistboxitem_s *pMouseOver = getMouseOverLabelSelect();
	// Set mouse over
	if(pMouseOver)
	{	mouseOverItem(pMouseOver->m_iIndex);
	}
	// Clear mouse overs
	else
	{	if(getMouseOverLabel() != -1)
			mouseOverItem(-1);
	}
}

// Reset
void CFXListBox::Reset( void )
{	removeAll();
	setRowHeight(LISTBOX_ROWHEIGHT);
	setSelectedLabel(-1);
	setMouseOverLabel(-1);
}

/*
* FX Timeline
*/
// Play button for timeline
class TimelinePlay : public ActionSignal
{
public:
	virtual void actionPerformed(Panel* panel)
	{	CFXTimeline_VGUI *pTimeline = gViewPort->m_pFXToolPanel->getTimeline();
		if(pTimeline)
		{	pTimeline->Play();
		}
		// HACK HACK: Reset triggers
		if(gViewPort->m_pFXToolPanel->getEvent())
		{	std::list<CFXObject*> *pFXObjects = gViewPort->m_pFXToolPanel->getEvent()->getFXObjects();
			std::list<CFXObject*>::iterator iterCurrent = pFXObjects->begin();
			while(iterCurrent != pFXObjects->end())
			{	CFXEvent *pEvent = gViewPort->m_pFXToolPanel->getEvent();
				float flRelTime = pEvent->getTime()-pEvent->getStartTime();
				(*iterCurrent)->getTimelineManager()->resetTriggers(flRelTime);
				iterCurrent++;
			}
		}
	}
};

// Pause button for timeline
class TimelinePause : public ActionSignal
{
public:
	virtual void actionPerformed(Panel* panel)
	{	CFXTimeline_VGUI *pTimeline = gViewPort->m_pFXToolPanel->getTimeline();
		if(pTimeline)
		{	pTimeline->Pause();
		}
	}
};

// Pause button for timeline
class InCameraSwitch : public ActionSignal
{
public:
	InCameraSwitch( CommandButton *pButton )
	{	setButton(pButton);
	}

	virtual void actionPerformed(Panel* panel)
	{	CFXTimeline_VGUI *pTimeline = gViewPort->m_pFXToolPanel->getTimeline();
		if(pTimeline && getButton())
		{	// Disable
			if(pTimeline->getInCamera())
			{	pTimeline->setInCamera(false);
				getButton()->setText("C");
			}
			// Enable
			else
			{	pTimeline->setInCamera(true);
				getButton()->setText("I");
			}
		}
	}

	// Accessors
	void setButton( CommandButton *pButton ) { m_pButton = pButton; }
	CommandButton *getButton( void ) { return m_pButton; }
private:
	CommandButton *m_pButton;
};

#define TIMELINE_TICK_HEIGHT	40
#define TIMELINE_STRIP_HEIGHT	20
#define TIMELINE_LABEL_WIDTH	150
#define TIMELINE_BUTTON_SPACE	4
#define TIMELINE_BUTTON_SIZE	26
// Constructor
CFXTimeline_VGUI::CFXTimeline_VGUI(std::string strTitle, int x,int y,int wide,int tall) : CFXPanel(strTitle,x,y,wide,tall)
{	// Get basic data for buttons
	int iStartX = TIMELINE_BUTTON_SPACE;
	int iY = TIMELINE_TICK_HEIGHT/2-TIMELINE_BUTTON_SIZE/2;

	// Make buttons

	// In Camera
	CommandButton *pInCam = new CommandButton( "C", iStartX, iY, TIMELINE_BUTTON_SIZE, TIMELINE_BUTTON_SIZE);
	pInCam->setContentAlignment(vgui::Label::a_center);
	pInCam->setParent( getContentPanel() );
	pInCam->addActionSignal( new InCameraSwitch(pInCam) );
	setInCameraButton(pInCam);
	// set incam status to true
	setInCamera(true);

	iStartX += TIMELINE_BUTTON_SIZE + TIMELINE_BUTTON_SPACE;

	// Load
	CommandButton *pLoadButton = new CommandButton( "L", iStartX, iY, TIMELINE_BUTTON_SIZE, TIMELINE_BUTTON_SIZE);
	pLoadButton->setContentAlignment(vgui::Label::a_center);
	pLoadButton->setParent( getContentPanel() );
	setLoadButton(pLoadButton);

	iStartX += TIMELINE_BUTTON_SIZE + TIMELINE_BUTTON_SPACE;

	// Save
	CommandButton *pSaveButton = new CommandButton( "S", iStartX, iY, TIMELINE_BUTTON_SIZE, TIMELINE_BUTTON_SIZE);
	pSaveButton->setContentAlignment(vgui::Label::a_center);
	pSaveButton->setParent( getContentPanel() );
	setSaveButton(pSaveButton);

	iStartX += TIMELINE_BUTTON_SIZE + TIMELINE_BUTTON_SPACE;

	// Pause
	CommandButton *pPauseButton = new CommandButton( "||", iStartX, iY, TIMELINE_BUTTON_SIZE, TIMELINE_BUTTON_SIZE);
	pPauseButton->setContentAlignment(vgui::Label::a_center);
	pPauseButton->setParent( getContentPanel() );
	pPauseButton->addActionSignal( new TimelinePause );
	setPauseButton(pPauseButton);

	iStartX += TIMELINE_BUTTON_SIZE + TIMELINE_BUTTON_SPACE;

	// Play
	CommandButton *pPlayButton = new CommandButton( "P", iStartX, iY, TIMELINE_BUTTON_SIZE, TIMELINE_BUTTON_SIZE);
	pPlayButton->setContentAlignment(vgui::Label::a_center);
	pPlayButton->setParent( getContentPanel() );
	pPlayButton->addActionSignal( new TimelinePlay );
	setPlayButton(pPlayButton);

	iStartX += TIMELINE_BUTTON_SIZE + TIMELINE_BUTTON_SPACE;

	// Timed event data panel
	ScrollPanel *pTimedPanel = new CFXScrollPanel( iStartX, 0, getWide()-iStartX-1, 200 );
	pTimedPanel->setParent( getContentPanel() );
	pTimedPanel->setScrollBarAutoVisible(false, false);
	pTimedPanel->setScrollBarVisible(true, false);
	pTimedPanel->setBorder( new LineBorder( Color(255 * 0.7,170 * 0.7,0,0) ) );
	pTimedPanel->validate();
	setTimedEventDataPanel(pTimedPanel);
	// Get bar height
	int iBarHeight = pTimedPanel->getHorizontalScrollBar()->getTall();
	// resize scroll panel & validate
	((CFXScrollPanel*)pTimedPanel)->setSize(pTimedPanel->getWide(), TIMELINE_TICK_HEIGHT+iBarHeight);
	pTimedPanel->validate();

	// Timeline meter
	CTimelineMeter *pMeter = new CTimelineMeter(0, 0, 400, 20);
	pMeter->setParent(pTimedPanel->getClient());
	pMeter->setSize(pMeter->calcMaxWidth(),TIMELINE_TICK_HEIGHT);
	setTimelineMeter(pMeter);
	pTimedPanel->validate();

	// Resize to content
	getContentPanel()->setSize(getContentPanel()->getWide(), pTimedPanel->getTall()+1);
	resizeToContentTall();

	// 
	setCurrentObject(-1);
}

// Refit timeline ( used to resize timeline after timestrips are added )
void CFXTimeline_VGUI::refitTimeline( void )
{	// Chaneg height of data panel
	int iBarHeight = getTimedEventDataPanel()->getHorizontalScrollBar()->getTall();
	int iNewHeight = TIMELINE_TICK_HEIGHT+getTimelineStripList()->size()*TIMELINE_STRIP_HEIGHT+iBarHeight;
	((CFXScrollPanel*)getTimedEventDataPanel())->setSize(getTimedEventDataPanel()->getWide(), iNewHeight);

	// Change height of content panel
	getContentPanel()->setSize(getContentPanel()->getWide(), getTimedEventDataPanel()->getTall()+1);
	// Dont resize hidden panels, they'll resize themselves
	if(!getHideStatus())
	{	// Resize
		resizeToContentTall();
		// Realign
		gViewPort->m_pFXToolPanel->alignCheck();
	}
}

// Update
void CFXTimeline_VGUI::Update( void )
{	if(getContentPanel()->isVisible())
	{	getTimelineMeter()->Update();
	}

	if(gViewPort->m_pFXToolPanel->getEvent())
	{	int iSelLabel = gViewPort->m_pFXToolPanel->getObjectManager()->getObjectList()->getSelectedLabel();
		// Change entity, update
		if((getCurrentObject() == -1 && getCurrentObject() != iSelLabel) || (getCurrentObject() != -1 && getCurrentObject() != iSelLabel))
		{	// Reset timeline
			if(iSelLabel == -1)
			{	setCurrentObject(-1);
				resetStripList();
				refitTimeline();
			}
			// Change to new entity
			else
			{	resetStripList();
				int i = 0;
				setCurrentObject(iSelLabel);
				CFXObject *pObj = gViewPort->m_pFXToolPanel->getEvent()->getObjectByIndex(iSelLabel);
				if(pObj)
				{//	pObj->getTimelineManager()
					std::list<CTimeline*>::iterator iterCurrent;
					ForEachIn(iterCurrent,(*pObj->getTimelineManager()->getTimeLines()))
					{	int x,y;
						getTimedEventDataPanel()->getPos(x,y);
						x--;
						int iXPos = x-TIMELINE_LABEL_WIDTH;
						int iYPos = TIMELINE_TICK_HEIGHT+TIMELINE_STRIP_HEIGHT*i;

						// Create label
						std::string strText = (*iterCurrent)->getName();
						strText += " ";
						Label *pLabel = new Label(strText.c_str(), iXPos, iYPos+1, TIMELINE_LABEL_WIDTH, TIMELINE_STRIP_HEIGHT);
						pLabel->setParent(getContentPanel());
						pLabel->setContentAlignment( vgui::Label::a_east );
						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) ) );

						// Create content strip
						iXPos=0;
						CTimelineStripContent *pStrip = new CTimelineStripContent(iXPos,iYPos,getTimelineMeter()->getWide(),TIMELINE_STRIP_HEIGHT);
						pStrip->setParent(getTimedEventDataPanel()->getClient());
						pStrip->setBgColor( 0, 0, 0, 255 );
						pStrip->setBorder( new LineBorder( Color(255 * 0.7,170 * 0.7,0,0) ) );

						getTimelineStripList()->push_back(CTimelineStrip((*iterCurrent), pLabel, pStrip));
						i++;
					}
					// Refit timeline
					refitTimeline();
				}
			}
		}
		// Update timeline strips
		std::list<CTimelineStrip>::iterator iterCurrentStrip;
		ForEachIn(iterCurrentStrip,(*getTimelineStripList()))
		{	iterCurrentStrip->getStripContent()->Update();
		}
	}
}

// Reset
void CFXTimeline_VGUI::Reset( void )
{	getTimelineMeter()->Reset();
	resetStripList();
	setCurrentObject(-1);
	refitTimeline();
}

// Reset Strip List
void CFXTimeline_VGUI::resetStripList( void )
{	std::list<CTimelineStrip>::iterator iterCurrent;
	ForEachIn(iterCurrent,(*getTimelineStripList()))
	{	iterCurrent->Remove();
	}
	getTimelineStripList()->clear();
}

// Realign Strips
void CFXTimeline_VGUI::realignStrips( void )
{	std::list<CTimelineStrip>::iterator iterCurrent;
	ForEachIn(iterCurrent,(*getTimelineStripList()))
	{	if(iterCurrent->getStripContent())
			iterCurrent->getStripContent()->realign();
	}
}

// Update Event Data
void CFXTimeline_VGUI::updateEventData( void )
{	CFXEvent *pEvent = gViewPort->m_pFXToolPanel->getEvent();
	if(pEvent)
	{	// Update timeline meter
		getTimelineMeter()->setTotalTime(pEvent->getEndTime()-pEvent->getStartTime());
		getTimelineMeter()->setCurrentTime(0);
		getTimelineMeter()->setDragging(false);
		getTimelineMeter()->setScale(1);
		getTimelineMeter()->setSize(getTimelineMeter()->calcMaxWidth(),TIMELINE_TICK_HEIGHT);
		getTimedEventDataPanel()->validate();
		// Set Time
		g_FXSystem.setDeveloperEventTime(getTimelineMeter()->getCurrentTime());
	}
}

// Play
void CFXTimeline_VGUI::Play( void )
{	if(getTimelineMeter()->getPlayStatus() == TIMELINE_PAUSE)
	{	getTimelineMeter()->setPlayStatus(TIMELINE_PLAY);
	}
}

// Pause
void CFXTimeline_VGUI::Pause( void )
{	if(getTimelineMeter()->getPlayStatus() == TIMELINE_PLAY)
	{	getTimelineMeter()->setPlayStatus(TIMELINE_PAUSE);
	}
}

// * Timeline meter
#define TIMEDEVENT_BUTTON_WIDE	16
// Constructor
CTimelineMeter::CTimelineMeter(int x,int y,int wide,int tall) : Panel(x,y,wide,tall)
{	Reset();
}

// Update
void CTimelineMeter::Update( void )
{	// Time delta for play
	float flDelta = gEngfuncs.GetClientTime() - getLastTime();
	setLastTime(gEngfuncs.GetClientTime());

	// Play
	if(getPlayStatus() == TIMELINE_PLAY)
	{	setCurrentTime(getCurrentTime()+flDelta);
		// Reset time if we go over
		if(getCurrentTime() > getTotalTime())
		{	setCurrentTime(0);
			setPlayStatus(TIMELINE_PAUSE);
		}
		// Update time
		g_FXSystem.setDeveloperEventTime(getCurrentTime());
	}
	// Drag update
	else if(getDragging())
	{	int x,y;
		App::getInstance()->getCursorPos(x,y);
		screenToLocal(x,y);
		// set time
		setCurrentTime(getTime(x));
		g_FXSystem.setDeveloperEventTime(getCurrentTime());
	}
}

// Reset
void CTimelineMeter::Reset( void )
{	setTotalTime(10);
	setLastTime(0);
	setCurrentTime(0);
	setScale(1);
	setPixelsPerSecond(50);
	setSidesOffset(10);
	setDragging(false);
	setPlayStatus(TIMELINE_PAUSE);
}

// Get time in respect to local X Coord
float CTimelineMeter::getTime( int iX )
{	float flMaxSize = getTotalTime()*float(getPixelsPerSecond())*getScale();

	// Account for sideoffset
	iX-=getSidesOffset();
	if(iX<0)
		iX=0;
	else if(iX>getWide()-getSidesOffset())
		iX=getWide()-getSidesOffset();

	float flPercent = float(iX)/flMaxSize;
	return (getTotalTime()*flPercent);
}

// Get coord in respect to time
int CTimelineMeter::getXCoord( float flTime )
{	float flPercent = flTime/getTotalTime();
	float flStart = getSidesOffset();
	return (getSidesOffset()+(getTotalTime()*float(getPixelsPerSecond())*getScale()*flPercent));
}

// Draw timeline ticks
void CTimelineMeter::paint( void )
{	// Set color, draw surrounding box
	drawSetColor(255 * 0.7,170 * 0.7,0,0);
	drawSetTextColor(255,170,0,0);
	drawOutlinedRect(0,0,calcMaxWidth(),TIMELINE_TICK_HEIGHT);
	
	// Tick loop
	for(int i = 0; i < ceil(getTotalTime()); i++)
	{	// Get numbers string form
		char szNum[8];
		int iNumOff = 0;
		sprintf(szNum,"%i",i);
		// HACK HACK: Calculate offset
		if(strlen(szNum) >= 3)
			iNumOff = 13;
		else if(strlen(szNum) >= 2)
			iNumOff = 10;
		else
			iNumOff = 5;
		
		// Get base and increment
		float flBaseX = getSidesOffset() + float(i*getPixelsPerSecond())*getScale();
		float flInc = float(getPixelsPerSecond())/float(4)*getScale();

		// Draw number(s)
		drawPrintText(flBaseX-iNumOff, 0, szNum, strlen(szNum));

		// draw ticks
		drawOutlinedRect(flBaseX,TIMELINE_TICK_HEIGHT*.5,flBaseX+2,TIMELINE_TICK_HEIGHT);
		drawOutlinedRect(flBaseX+flInc,TIMELINE_TICK_HEIGHT*.85,flBaseX+flInc+2,TIMELINE_TICK_HEIGHT);
		drawOutlinedRect(flBaseX+flInc*2,TIMELINE_TICK_HEIGHT*.65,flBaseX+flInc*2+2,TIMELINE_TICK_HEIGHT);
		drawOutlinedRect(flBaseX+flInc*3,TIMELINE_TICK_HEIGHT*.85,flBaseX+flInc*3+2,TIMELINE_TICK_HEIGHT);

		// Last peice, draw 'last' one
		if(i == ceil(getTotalTime())-1 && (i > 1))
		{	sprintf(szNum,"%i",i+1);
			if(strlen(szNum) >= 3)
				iNumOff = 13;
			else if(strlen(szNum) >= 2)
				iNumOff = 10;
			else
				iNumOff = 5;
			
			drawOutlinedRect(flBaseX+flInc*4,TIMELINE_TICK_HEIGHT*.5,flBaseX+flInc*4+2,TIMELINE_TICK_HEIGHT);
			drawPrintText(flBaseX+flInc*4-iNumOff, 0, szNum, strlen(szNum));
		}
	}
}

// Draw red progress bar
void CTimelineMeter::paintBackground( void )
{	// Draw progress bar
	if(getCurrentTime() > 0)
	{	drawSetColor(0,255,0,165);
		drawFilledRect(getSidesOffset(),0,getXCoord(getCurrentTime()),TIMELINE_TICK_HEIGHT);
	}
}
// Calculate Max Width
int CTimelineMeter::calcMaxWidth( void )
{	return ((ceil(getTotalTime())*float(getPixelsPerSecond())*getScale())+getSidesOffset()*2);
}

// Mouse functions: Pressed
void CTimelineMeter::internalMousePressed(MouseCode code)
{	if(code == MOUSE_LEFT)
	{	// Pause if we're playing
		if(getPlayStatus() == TIMELINE_PLAY)
		{	setPlayStatus(TIMELINE_PAUSE);
		}
		setDragging(true);
	}
}

// Mouse functions: Relased
void CTimelineMeter::internalMouseReleased(MouseCode code)
{	setDragging(false);
}

// Mouse functions: Exit local space
void CTimelineMeter::internalCursorExited()
{	setDragging(false);
}

// * Timeline Strip Item
// List box click
class CFXContentStripClick : public InputSignal
{
public:
	// Constructors
	CFXContentStripClick()
	{	setContentStrip(NULL);
	}
	CFXContentStripClick( CTimelineStripContent *pContent )
	{	setContentStrip(pContent);
	}

	// Mouse pressed
	virtual void mousePressed(MouseCode code,Panel* panel) 
	{	if(getContentStrip())
		{	getContentStrip()->internalMousePressed(code);
		}
	}

	// Mouse released
	virtual void mouseReleased(MouseCode code,Panel* panel)
	{	if(getContentStrip())
		{	getContentStrip()->internalMouseReleased(code);
		}
	}

	virtual void cursorMoved(int x,int y,Panel* panel) {}
	virtual void cursorEntered(Panel* panel) {}
	virtual void cursorExited(Panel* panel) {}
	virtual void mouseDoublePressed(MouseCode code,Panel* panel) {}
	virtual void mouseWheeled(int delta,Panel* panel) {}
	virtual void keyPressed(KeyCode code,Panel* panel) {}
	virtual void keyTyped(KeyCode code,Panel* panel) {}
	virtual void keyReleased(KeyCode code,Panel* panel) {}
	virtual void keyFocusTicked(Panel* panel) {}

	// Accessors
	void setContentStrip( CTimelineStripContent *pContent ) { m_pContent = pContent; }
	CTimelineStripContent *getContentStrip ( void ) { return m_pContent; }
private:
	CTimelineStripContent *m_pContent;
};

// Constructor
CTimelineStripItem::CTimelineStripItem(int x,int y,int wide,int tall) : Label("0",x,y,wide,tall)
{
}

// Point Over Item
bool CTimelineStripItem::pointOverItem( int x, int y )
{	int xp,yp;
	getPos(xp,yp);
	if((x >= xp) && (x <= (xp+getWide())))
	{	return true;
	}
	return false;
}

// * Timeline Strip Content
// Constructor
CTimelineStripContent::CTimelineStripContent(int x,int y,int wide,int tall) : Panel(x,y,wide,tall)
{	setDraggingItem(NULL);
	setDragging(false);
}
// Align with Timelinemeter
void CTimelineStripContent::realign( void )
{	CTimelineMeter *pTimelineMeter = gViewPort->m_pFXToolPanel->getTimeline()->getTimelineMeter();
	if(pTimelineMeter)
	{	setSize(pTimelineMeter->calcMaxWidth(),TIMELINE_TICK_HEIGHT);
		std::list<CTimelineStripItem>::iterator iterCurrent;
		ForEachIn(iterCurrent,(*getItemList()))
		{	float flStart = getFXObject()->getStartTime()+iterCurrent->getTimedEvent()->first;
			iterCurrent->setPos(pTimelineMeter->getXCoord(flStart)-TIMEDEVENT_BUTTON_WIDE/2,0);
		}
	}
}

// Get Moused Over Item
std::list<CTimelineStripItem>::iterator CTimelineStripContent::getMousedOverItem( void )
{	int x,y;
	App::getInstance()->getCursorPos(x,y);
	screenToLocal(x,y);
	// Get moused over item
	std::list<CTimelineStripItem>::iterator iterCurrent;
	ForEachIn(iterCurrent,(*getItemList()))
	{	if(iterCurrent->pointOverItem(x,y))
			return iterCurrent;
	}
	return NULL;
}

// Add Item
Label *CTimelineStripContent::addItem( std::map<float,CTimedEvent*>::iterator iterItem )
{	CTimelineStripItem item(0,0,TIMEDEVENT_BUTTON_WIDE,TIMELINE_STRIP_HEIGHT);
	item.setTimedEvent(iterItem);
	getItemList()->push_back(item);
	std::list<CTimelineStripItem>::iterator iterEnd = getItemList()->end();
	iterEnd--;
	return (&(*iterEnd));
}

// Remove Item
void CTimelineStripContent::removeItem( std::map<float,CTimedEvent*>::iterator iterItem )
{	std::list<CTimelineStripItem>::iterator iterRemove;
	ForEachIn(iterRemove,(*getItemList()))
	{	// found, erase now
		if(iterRemove->getTimedEvent() == iterItem)
		{	// Remove child
			removeChild((&(*iterRemove)));
			// remove from list
			getItemList()->erase(iterRemove);
			// Validate box
			gViewPort->m_pFXToolPanel->getTimeline()->getTimedEventDataPanel()->validate();
			return;
		}
	}
}

// Finish dragging (update physical time event)
void CTimelineStripContent::finishDragging( void )
{	if(getDragging())
	{	CTimelineMeter *pTimeline = gViewPort->m_pFXToolPanel->getTimeline()->getTimelineMeter();
		if(pTimeline && getDraggingItem() != NULL)
		{	// Get cursor position
			int x,y;
			App::getInstance()->getCursorPos(x,y);
			screenToLocal(x,y);
			// Get time...
			float flTime = pTimeline->getTime(x);
			// in respect to objects start time
			flTime -= getFXObject()->getStartTime();

			// Update time
			getDraggingItem()->setTimedEvent((getObjectTimeline()->updateTime(getDraggingItem()->getTimedEvent(), flTime)));
			// Update failed, remove item (shouldn't happen)
			if(getDraggingItem()->getTimedEvent() == NULL)
			{	getItemList()->erase(getDraggingItem());
				setDraggingItem(NULL);
				setDragging(false);
				return;
			}
			else
			{	// Set pos
				flTime = getFXObject()->getStartTime() + getDraggingItem()->getTimedEvent()->first;
				getDraggingItem()->setPos(pTimeline->getXCoord(flTime)-TIMEDEVENT_BUTTON_WIDE/2,0);
			}
		}
		setDragging(false);
		setDraggingItem(NULL);
	}
}

// Update
void CTimelineStripContent::Update( void )
{	if(getDragging())
	{	// Move it so it corresponds with timeline
		if(getDraggingItem() != NULL)
		{	int x,y;
			App::getInstance()->getCursorPos(x,y);
			screenToLocal(x,y);
			// Stop dragging if we get off of the content strip
			if(y<0 || y>getDraggingItem()->getTall())
			{	finishDragging();
				return;
			}

			// Get timeline, move event along content strip
			CTimelineMeter *pTimeline = gViewPort->m_pFXToolPanel->getTimeline()->getTimelineMeter();
			if(pTimeline)
			{	// Get time corresponding with mouse position
				float flTime = pTimeline->getTime(x);
				// Set pos
				getDraggingItem()->setPos(pTimeline->getXCoord(flTime)-TIMEDEVENT_BUTTON_WIDE/2,0);
			}
		}
		else
		{	setDragging(false);
		}
	}
}

// Mouse functions: Pressed
void CTimelineStripContent::internalMousePressed(MouseCode code)
{	if(code == MOUSE_LEFT)
	{	std::list<CTimelineStripItem>::iterator iterOver = getMousedOverItem();
		// We have an item to drag, take a hold of it
		if(iterOver != NULL)
		{	setDragging(true);
			setDraggingItem(iterOver);
		}
	}
	// Create/Edit node
	else if(code == MOUSE_RIGHT)
	{	// Get time & set
		int x,y;
		CTimelineMeter *pMeter = gViewPort->m_pFXToolPanel->getTimeline()->getTimelineMeter();
		App::getInstance()->getCursorPos(x,y);
		pMeter->screenToLocal(x,y);
		float flTime = pMeter->getTime(x);

		std::list<CTimelineStripItem>::iterator iterOver = getMousedOverItem();
		// Create new
		if(iterOver == NULL)
		{	CFXBaseTimeProp *pNewTimeProp = NULL;

			switch(getObjectTimeline()->getID())
			{
			case TLID_ROTATION:
					pNewTimeProp = new CFXTimeProp_Rotation_VGUI("Rotation", 200, 200, true, getObjectTimeline()->getID());
					break;
			case TLID_SIZE:
					pNewTimeProp = new CFXTimeProp_Size_VGUI("Size", 200, 200, true, getObjectTimeline()->getID());
					break;
			case TLID_ALPHA:
					pNewTimeProp = new CFXTimeProp_Alpha_VGUI("Alpha", 200, 200, true, getObjectTimeline()->getID());
					break;
			case TLID_COLOR:
					pNewTimeProp = new CFXTimeProp_Color_VGUI("Color", 200, 200, true, getObjectTimeline()->getID());
					break;
			case TLID_SOUND:
					pNewTimeProp = new CFXTimeProp_Sound_VGUI("Sound", 200, 200, true, getObjectTimeline()->getID());
					break;
			case TLID_SNDSTREAM1:
					pNewTimeProp = new CFXTimeProp_SoundStream_VGUI("Sound Stream 1", 200, 200, true, getObjectTimeline()->getID());
					break;
			case TLID_SNDSTREAM2:
					pNewTimeProp = new CFXTimeProp_SoundStream_VGUI("Sound Stream 2", 200, 200, true, getObjectTimeline()->getID());
					break;
			case TLID_SNDVOL1:
					pNewTimeProp = new CFXTimeProp_Volume_VGUI("Volume 1", 200, 200, true, getObjectTimeline()->getID());
					break;
			case TLID_SNDVOL2:
					pNewTimeProp = new CFXTimeProp_Volume_VGUI("Volume 2", 200, 200, true, getObjectTimeline()->getID());
					break;
			case TLID_POSITION:
					pNewTimeProp = new CFXTimeProp_Position_VGUI("Position", 200, 200, true, getObjectTimeline()->getID());
					break;
			case TLID_SEQUENCE:
					pNewTimeProp = new CFXTimeProp_Sequence_VGUI("Animation", 200, 200, true, getObjectTimeline()->getID());
					break;
			case TLID_FRAMEMULTI:
					pNewTimeProp = new CFXTimeProp_FrameMulti_VGUI("Frame Multiplier", 200, 200, true, getObjectTimeline()->getID());
					break;
			case TLID_BODYPART:
					pNewTimeProp = new CFXTimeProp_BodyPart_VGUI("Body Part", 200, 200, true, getObjectTimeline()->getID());
					break;
			case TLID_MDLBLUR:
					pNewTimeProp = new CFXTimeProp_ModelBlur_VGUI("Model Blur", 200, 200, true, getObjectTimeline()->getID());
					break;
			case TLID_RADIALBLUR:
					pNewTimeProp = new CFXTimeProp_RadialBlur_VGUI("Radial Blur", 200, 200, true, getObjectTimeline()->getID());
					break;
			}

			if(pNewTimeProp)
				pNewTimeProp->configNew(flTime);
		}
		// Edit
		else
		{	CFXBaseTimeProp *pEditTimeProp = NULL;

			switch(getObjectTimeline()->getID())
			{
			case TLID_ROTATION:
					pEditTimeProp = new CFXTimeProp_Rotation_VGUI("Rotation", 200, 200, false, getObjectTimeline()->getID());
					break;
			case TLID_SIZE:
					pEditTimeProp = new CFXTimeProp_Size_VGUI("Size", 200, 200, false, getObjectTimeline()->getID());
					break;
			case TLID_ALPHA:
					pEditTimeProp = new CFXTimeProp_Alpha_VGUI("Alpha", 200, 200, false, getObjectTimeline()->getID());
					break;
			case TLID_COLOR:
					pEditTimeProp = new CFXTimeProp_Color_VGUI("Color", 200, 200, false, getObjectTimeline()->getID());
					break;
			case TLID_SOUND:
					pEditTimeProp = new CFXTimeProp_Sound_VGUI("Sound", 200, 200, false, getObjectTimeline()->getID());
					break;
			case TLID_SNDSTREAM1:
					pEditTimeProp = new CFXTimeProp_SoundStream_VGUI("Sound Stream 1", 200, 200, false, getObjectTimeline()->getID());
					break;
			case TLID_SNDSTREAM2:
					pEditTimeProp = new CFXTimeProp_SoundStream_VGUI("Sound Stream 2", 200, 200, false, getObjectTimeline()->getID());
					break;
			case TLID_SNDVOL1:
					pEditTimeProp = new CFXTimeProp_Volume_VGUI("Volume 1", 200, 200, false, getObjectTimeline()->getID());
					break;
			case TLID_SNDVOL2:
					pEditTimeProp = new CFXTimeProp_Volume_VGUI("Volume 2", 200, 200, false, getObjectTimeline()->getID());
					break;
			case TLID_POSITION:
					pEditTimeProp = new CFXTimeProp_Position_VGUI("Position", 200, 200, false, getObjectTimeline()->getID());
					break;
			case TLID_SEQUENCE:
					pEditTimeProp = new CFXTimeProp_Sequence_VGUI("Animation", 200, 200, false, getObjectTimeline()->getID());
					break;
			case TLID_FRAMEMULTI:
					pEditTimeProp = new CFXTimeProp_Size_VGUI("Frame Multiplier", 200, 200, false, getObjectTimeline()->getID());
					break;
			case TLID_BODYPART:
					pEditTimeProp = new CFXTimeProp_BodyPart_VGUI("Body Part", 200, 200, false, getObjectTimeline()->getID());
					break;
			case TLID_MDLBLUR:
					pEditTimeProp = new CFXTimeProp_ModelBlur_VGUI("Model Blur", 200, 200, false, getObjectTimeline()->getID());
					break;
			case TLID_RADIALBLUR:
					pEditTimeProp = new CFXTimeProp_RadialBlur_VGUI("RadialBlur", 200, 200, false, getObjectTimeline()->getID());
					break;
			}

			if(pEditTimeProp)
				pEditTimeProp->configEdit(iterOver->getTimedEvent());
		}
	}
}

// Mouse functions: Relased
void CTimelineStripContent::internalMouseReleased(MouseCode code)
{	finishDragging();
}


// * Timeline Strip Storage
// Constructor
CTimelineStrip::CTimelineStrip(CTimeline *pTimeline, Label *pLabel, CTimelineStripContent *pContent)
{	setObjectTimeline(pTimeline);
	setLabel(pLabel);
	setStripContent(pContent);
	if(pTimeline)
	{	pContent->setFXObject(pTimeline->getFXObject());
		pContent->setObjectTimeline(pTimeline);
	}
	else
	{	pContent->setFXObject(NULL);
		pContent->setObjectTimeline(NULL);
	}
	// Add items
	if(pTimeline)
	{	CTimelineMeter *pTimelineMeter = gViewPort->m_pFXToolPanel->getTimeline()->getTimelineMeter();
		if(pTimelineMeter)
		{	std::map<float,CTimedEvent*>::iterator iterEvents;
			ForEachIn(iterEvents, (*pTimeline->getTimedEvents()))
			{	addTimedEvent(iterEvents);
			}
			// Realign all elements
			pContent->realign();
		}
	}
}

// Add Timed Event
void CTimelineStrip::addTimedEvent( std::map<float,CTimedEvent*>::iterator iterItem )
{	// Add item
	Label *pEvent = getStripContent()->addItem(iterItem);
	pEvent->setParent(getStripContent());
	// Set pos
	pEvent->setPos(0,0);
	pEvent->setContentAlignment(vgui::Label::a_center);
	pEvent->setBgColor( 255, 255, 255, 255 );
	pEvent->setFgColor( 255, 255, 255, 0 );
	pEvent->addInputSignal(new CFXContentStripClick(getStripContent()));
	pEvent->setBorder( new LineBorder( Color(255 * 0.7,170 * 0.7,0,0) ) );
}

// Remove
void CTimelineStrip::Remove( void )
{	if(getLabel())
	{	Panel *pParent = getLabel()->getParent();
		if(pParent)
		{	pParent->removeChild(getLabel());
			setLabel(NULL);
		}
	}

	if(getStripContent())
	{	Panel *pParent = getStripContent()->getParent();
		if(pParent)
		{	pParent->removeChild(getStripContent());
			setStripContent(NULL);
		}
	}
}

// Update Content (correspond with timeline data)
void CTimelineStrip::updateContent( void )
{	if(getObjectTimeline())
	{	// Set Label
		getLabel()->setText(getObjectTimeline()->getName());

		// Align with timeline meter
		getStripContent()->realign();
	}
}

/*
* FX Object Manager
*/
// Delete selected object
class DeleteSelObjAction : public ActionSignal
{
public:
	virtual void actionPerformed(Panel* panel)
	{	CFXListBox *pListBox = gViewPort->m_pFXToolPanel->getObjectManager()->getObjectList();
		int iSel = pListBox->getSelectedLabel();
		// Delete object
		if(iSel != -1)
		{	CFXEvent *pEvent = gViewPort->m_pFXToolPanel->getEvent();
			if(pEvent)
			{	pEvent->removeObject(iSel);
			}
			pListBox->removeItem(iSel);
		}
	}
};
// Create Object Panel Button object
class CreateObjectPanelAction : public ActionSignal
{
public:
	virtual void actionPerformed(Panel* panel)
	{	if(!gViewPort->m_pFXToolPanel->getObjectManager()->getCreateFXPanel())
		{	CCreateFXObject_VGUI *pPanel = new CCreateFXObject_VGUI("Create Object", EDIT_PANELS_START_X, EDIT_PANELS_START_Y, 200, 200);
			gViewPort->m_pFXToolPanel->getObjectManager()->setCreateFXPanel(pPanel);
			pPanel->setParent(gViewPort->m_pFXToolPanel);
			gViewPort->m_pFXToolPanel->setEnteringText(true);
		}
	}
};
// Edit Object Panel Button object
class EditObjectPanelAction : public ActionSignal
{
public:
	virtual void actionPerformed(Panel* panel)
	{	if(!gViewPort->m_pFXToolPanel->getObjectManager()->getEditFXPanel())
		{	if(gViewPort->m_pFXToolPanel->getObjectManager()->getObjectList()->getSelectedLabel() != -1)
			{	CEditFXObject_VGUI *pPanel = new CEditFXObject_VGUI("Edit Object (time)", EDIT_PANELS_START_X, EDIT_PANELS_START_Y, 200, 200);
				gViewPort->m_pFXToolPanel->getObjectManager()->setEditFXPanel(pPanel);
				pPanel->setParent(gViewPort->m_pFXToolPanel);
				gViewPort->m_pFXToolPanel->setEnteringText(true);
			}
		}
	}
};
#define OBJMAN_LISTBOX_HEIGHT	120
#define OBJMAN_PADDING			6
#define OBJMAN_BUTTONSIZE_Y		30
// Constructor
CFXObjectManager_VGUI::CFXObjectManager_VGUI(std::string strTitle, int x,int y,int wide,int tall) : CFXPanel(strTitle,x,y,wide,tall)
{	setCreateFXPanel(NULL);
	setEditFXPanel(NULL);

	// Create list box
	CFXListBox *pListBox = new CFXListBox(0,0, getContentPanel()->getWide(), OBJMAN_LISTBOX_HEIGHT);
	pListBox->setParent(getContentPanel());
	pListBox->validate();
	setObjectList(pListBox);

	int iStartY = pListBox->getTall() + OBJMAN_PADDING;
	int iStartX = OBJMAN_PADDING;
	float flButtonSizeX = (getContentPanel()->getWide() - OBJMAN_PADDING*2)/3-OBJMAN_PADDING/2;

	// Create Button
	CommandButton *pCreate = new CommandButton( "Create", iStartX, iStartY, flButtonSizeX, OBJMAN_BUTTONSIZE_Y);
	pCreate->setContentAlignment(vgui::Label::a_center);
	pCreate->setParent( getContentPanel() );
	pCreate->addActionSignal( new CreateObjectPanelAction );
	setCreateButton(pCreate);

	iStartX += flButtonSizeX + OBJMAN_PADDING;
	// Edit Button
	CommandButton *pEdit = new CommandButton( "Edit", iStartX, iStartY, flButtonSizeX, OBJMAN_BUTTONSIZE_Y);
	pEdit->setContentAlignment(vgui::Label::a_center);
	pEdit->setParent( getContentPanel() );
	pEdit->addActionSignal( new EditObjectPanelAction );
	setEditButton(pEdit);

	iStartX += flButtonSizeX + OBJMAN_PADDING;
	// Delete Button
	CommandButton *pDelete = new CommandButton( "Delete", iStartX, iStartY, flButtonSizeX, OBJMAN_BUTTONSIZE_Y);
	pDelete->setContentAlignment(vgui::Label::a_center);
	pDelete->setParent( getContentPanel() );
	pDelete->addActionSignal( new DeleteSelObjAction );
	setDeleteButton(pDelete);

	// Resize content panel to fit
	getContentPanel()->setSize(getContentPanel()->getWide(), iStartY + OBJMAN_BUTTONSIZE_Y + OBJMAN_PADDING);
	resizeToContentTall();
}

// Update
void CFXObjectManager_VGUI::Update( void )
{	if(getContentPanel()->isVisible())
	{	getObjectList()->Update();
		if(getCreateFXPanel())
		{	getCreateFXPanel()->Update();
		}
	}
}

// Reset
void CFXObjectManager_VGUI::Reset( void )
{	getObjectList()->Reset();
}

// Update Event Data
void CFXObjectManager_VGUI::updateEventData( void )
{	CFXEvent *pEvent = gViewPort->m_pFXToolPanel->getEvent();
	// Fill list with objects
	if(pEvent)
	{	getObjectList()->removeAll();
		std::list<CFXObject*>::iterator iterCurrent;
		ForEachIn(iterCurrent, (*pEvent->getFXObjects()))
		{	getObjectList()->addItem((*iterCurrent)->getID(), (*iterCurrent)->getName());
		}
	}
}



// * Edit FX Object Menu ( just time for now )
// Accept Edit Object Action
class AcceptEditObjectAction : public ActionSignal
{
public:
	virtual void actionPerformed(Panel* panel)
	{	CFXObjectManager_VGUI *pObjMan = gViewPort->m_pFXToolPanel->getObjectManager();
		CEditFXObject_VGUI *pFXPanel = pObjMan->getEditFXPanel();
		int idx = pObjMan->getObjectList()->getSelectedLabel();
		if(pFXPanel)
		{	if(idx != -1)
			{	char szSTime[256];
				char szETime[256];
				pFXPanel->getTimeStartText()->getText(0, szSTime, 32);
				pFXPanel->getTimeEndText()->getText(0, szETime, 32);
				szSTime[255] = '\0';
				szETime[255] = '\0';
				float flStart,flEnd;
				flStart = atof(szSTime);
				flEnd = atof(szETime);

				// set new start/end time
				CFXObject *pObject = gViewPort->m_pFXToolPanel->getEvent()->getObjectByIndex(idx);
				if(pObject)
				{	pObject->setStartTime(flStart);
					pObject->setEndTime(flEnd);
				}
			}
			gViewPort->m_pFXToolPanel->setEnteringText(false);
			pObjMan->setEditFXPanel(NULL);
			gViewPort->m_pFXToolPanel->removeChild(pFXPanel);
			// Realign timed events
			gViewPort->m_pFXToolPanel->getTimeline()->realignStrips();
		}
	}
};

// Constructor
#define FXOBJECT_EDIT_WIDE	220
#define EDITFXOBJET_PAD	15
#define EDITXOBJECT_BUTTONTALL	30
CEditFXObject_VGUI::CEditFXObject_VGUI(std::string strTitle, int x,int y,int wide,int tall) : CFXPanel(strTitle,x,y,wide,tall)
{
	int iObject = gViewPort->m_pFXToolPanel->getObjectManager()->getObjectList()->getSelectedLabel();
	if(iObject == -1)
	{	return;
	}

	CFXObject *pObject = gViewPort->m_pFXToolPanel->getEvent()->getObjectByIndex(iObject);


	int iWide = FXOBJECT_EDIT_WIDE/2-EDITFXOBJET_PAD*2;
	x = EDITFXOBJET_PAD;
	y = EDITFXOBJET_PAD;
	char szData[32];
	// Create text boxes (start time)
	sprintf(szData,"%f",pObject->getStartTime());
	CBotTextEntry *pStartTime = new CBotTextEntry(szData, x, y, iWide, YRES(15));
	pStartTime->setParent(getContentPanel());
	pStartTime->setBgColor(0, 0, 0, 255);
	pStartTime->setFgColor(100, 100, 100, 150);
	pStartTime->SetMaxChars(32);
	setTimeStartText(pStartTime);

	x += iWide + EDITFXOBJET_PAD;
	// Create text boxes (end time)
	sprintf(szData,"%f",pObject->getEndTime());
	CBotTextEntry *pEndTime = new CBotTextEntry(szData, x, y, iWide, YRES(15));
	pEndTime->setParent(getContentPanel());
	pEndTime->setBgColor(0, 0, 0, 255);
	pEndTime->setFgColor(100, 100, 100, 150);
	pEndTime->SetMaxChars(32);
	setTimeEndText(pEndTime);

	// Accept Button
	x = EDITFXOBJET_PAD;
	y += YRES(15) + EDITFXOBJET_PAD;
	CommandButton *pAccept = new CommandButton( "Accept", x, y, FXOBJECT_EDIT_WIDE-EDITFXOBJET_PAD*2, EDITXOBJECT_BUTTONTALL);
	pAccept->setContentAlignment(vgui::Label::a_center);
	pAccept->setParent( getContentPanel() );
	pAccept->addActionSignal( new AcceptEditObjectAction );
	setAcceptButton(pAccept);

	// Resize windows
	getContentPanel()->setSize( FXOBJECT_EDIT_WIDE, y + EDITXOBJECT_BUTTONTALL + EDITFXOBJET_PAD );
	resizeToContent();
}

// * Create FX Object Menu
// Create Object Action
class CreateObjectAction : public ActionSignal
{
public:
	virtual void actionPerformed(Panel* panel)
	{	CCreateFXObject_VGUI *pFXPanel = gViewPort->m_pFXToolPanel->getObjectManager()->getCreateFXPanel();
		if(pFXPanel)
		{	CFXListBox *pListBox = pFXPanel->getObjectTypeList();
			CFXEvent *pEvent = gViewPort->m_pFXToolPanel->getEvent();
			if(pEvent && (pListBox->getSelectedLabel() != -1))
			{
				char szName[256];
				char szModel[256];
				char szSprite[256];
				char szSTime[256];
				char szETime[256];
				pFXPanel->getNameText()->getText(0, szName, 64);
				pFXPanel->getModelText()->getText(0, szModel, 64);
				pFXPanel->getSpriteText()->getText(0, szSprite, 64);
				pFXPanel->getTimeStartText()->getText(0, szSTime, 32);
				pFXPanel->getTimeEndText()->getText(0, szETime, 32);
				szName[255] = '\0';
				szModel[255] = '\0';
				szSprite[255] = '\0';
				szSTime[255] = '\0';
				szETime[255] = '\0';

				float flSTime = atof(szSTime);
				float flETime = atof(szETime);

				CFXObject *pCreate = NULL;
				CFXObjectMDL *pModel;
				CFXObjectWRL *pWRL;
				CFXObjectCamera *pCam;
				CFXObjectSound *pSnd;
				switch(pListBox->getSelectedLabel())
				{
				case OBJECT_CREATE_MDL:
					{	// Create object
						pModel = new CFXObjectMDL(pEvent);
						pModel->setName(szName);
						pEvent->addObject(pModel, flSTime, flETime);
						pModel->setupModel(szModel);
						pCreate = (CFXObject*)pModel;

						break;
					}
				case OBJECT_CREATE_LOCAL:
					{	// Create object
						cl_entity_t *pLocal = gEngfuncs.GetLocalPlayer();
						if(pLocal)
						{	pModel = new CFXObjectMDL(pEvent);
							pModel->setName(szName);
							pEvent->addObject(pModel, flSTime, flETime);
							pModel->setupModel(pLocal->index);
							pCreate = (CFXObject*)pModel;
						}

						break;
					}
				case OBJECT_CREATE_WRL:
					{	// Create object
						pWRL = new CFXObjectWRL(pEvent);
						pWRL->setName(szName);
						pEvent->addObject(pWRL, flSTime, flETime);
						pWRL->setModelName(szModel);
						pWRL->setTextureName(szSprite);
						pWRL->updateModelData();
						pCreate = (CFXObject*)pWRL;

						break;
					}
				case OBJECT_CREATE_CAMERA:
					{	// Create object
						pCam = new CFXObjectCamera(pEvent);
						pCam->setName(szName);
						pEvent->addObject(pCam, flSTime, flETime);
						pCam->setModelName("models/camera.wrl");
						pCam->setTextureName("sprites/camera.spr");
						pCam->updateModelData();
						// add size, slpha, and rotation timeline elements at time 0
						CTimeline *pTimeline = pCam->getTimelineManager()->getTimeline(TLID_SIZE);
						if(pTimeline)
							pTimeline->addTimedEvent(0, new CTimedEventSize(1));

						pTimeline = pCam->getTimelineManager()->getTimeline(TLID_ALPHA);
						if(pTimeline)
							pTimeline->addTimedEvent(0, new CTimedEventAlpha(255));

						pTimeline = pCam->getTimelineManager()->getTimeline(TLID_ROTATION);
						if(pTimeline)
							pTimeline->addTimedEvent(0, new CTimedEventRotation(vec3_t(0,0,0)));

						pCreate = (CFXObject*)pCam;

						break;
					}
				case OBJECT_CREATE_SOUND:
					{	// Create object
						pSnd = new CFXObjectSound(pEvent);
						pSnd->setName(szName);
						pEvent->addObject(pSnd, flSTime, flETime);

						pCreate = (CFXObject*)pSnd;

						break;
					}
				}
				// Update list
				if(pCreate)
				{	gViewPort->m_pFXToolPanel->getObjectManager()->getObjectList()->addItem(pCreate->getID(), pCreate->getName());
				}
			}
			gViewPort->m_pFXToolPanel->setEnteringText(false);
			gViewPort->m_pFXToolPanel->getObjectManager()->setCreateFXPanel(NULL);
			gViewPort->m_pFXToolPanel->removeChild(pFXPanel);
		}
	};
};
#define CREATEFXOBJECT_TALL 80
#define CREATEFXOBJECT_WIDE	150
#define CREATEFXOBJET_PAD	15
#define CREATEFXOBJECT_TEXTWIDE 300
#define CREATEFXOBJECT_BUTTONTALL	30
// Constructor
CCreateFXObject_VGUI::CCreateFXObject_VGUI(std::string strTitle, int x,int y,int wide,int tall) : CFXPanel(strTitle,x,y,wide,tall)
{	setCurrentSelection(-1);
	// Create list box
	CFXListBox *pListBox = new CFXListBox(0,0, CREATEFXOBJECT_WIDE, CREATEFXOBJECT_TALL);
	pListBox->setParent(getContentPanel());
	// Add info
	pListBox->addItem(OBJECT_CREATE_MDL, "Add MDL");
	pListBox->addItem(OBJECT_CREATE_LOCAL, "Add Local MDL");
	pListBox->addItem(OBJECT_CREATE_WRL, "Add WRL");
	pListBox->addItem(OBJECT_CREATE_CAMERA, "Add Camera");
	pListBox->addItem(OBJECT_CREATE_SOUND, "Add Sound");
	pListBox->validate();
	setObjectTypeList(pListBox);

	int iY = 0;
	int iX = pListBox->getWide()+CREATEFXOBJET_PAD;

	// Create text boxes (name)
	CBotTextEntry *pName = new CBotTextEntry("Name Here",iX,iY, CREATEFXOBJECT_TEXTWIDE, YRES(15));
	pName->setParent(getContentPanel());
	pName->setBgColor(0, 0, 0, 255);
	pName->setFgColor(100, 100, 100, 150);
	pName->SetMaxChars(64);
	pName->setVisible(false);
	setNameText(pName);

	iY += YRES(15)+CREATEFXOBJET_PAD;

	// Create text boxes (model name)
	CBotTextEntry *pModelName = new CBotTextEntry("Model Name Here",iX,iY, CREATEFXOBJECT_TEXTWIDE, YRES(15));
	pModelName->setParent(getContentPanel());
	pModelName->setBgColor(0, 0, 0, 255);
	pModelName->setFgColor(100, 100, 100, 150);
	pModelName->SetMaxChars(64);
	pModelName->setVisible(false);
	setModelText(pModelName);

	iY += YRES(15)+CREATEFXOBJET_PAD;
	// Create text boxes (sprite name)
	CBotTextEntry *pSpriteName = new CBotTextEntry("Sprite Name Here",iX,iY, CREATEFXOBJECT_TEXTWIDE, YRES(15));
	pSpriteName->setParent(getContentPanel());
	pSpriteName->setBgColor(0, 0, 0, 255);
	pSpriteName->setFgColor(100, 100, 100, 150);
	pSpriteName->SetMaxChars(64);
	pSpriteName->setVisible(false);
	setSpriteText(pSpriteName);

	iY += YRES(15)+CREATEFXOBJET_PAD;
	int iTimeTextWidth = CREATEFXOBJECT_TEXTWIDE/2-CREATEFXOBJET_PAD/2;
	// Create text boxes (start time)
	CBotTextEntry *pStartTime = new CBotTextEntry("0",iX,iY, iTimeTextWidth, YRES(15));
	pStartTime->setParent(getContentPanel());
	pStartTime->setBgColor(0, 0, 0, 255);
	pStartTime->setFgColor(100, 100, 100, 150);
	pStartTime->SetMaxChars(32);
	pStartTime->setVisible(false);
	setTimeStartText(pStartTime);

	// Create text boxes (end time)
	CBotTextEntry *pEndTime = new CBotTextEntry("999",iX+iTimeTextWidth+CREATEFXOBJET_PAD,iY, iTimeTextWidth, YRES(15));
	pEndTime->setParent(getContentPanel());
	pEndTime->setBgColor(0, 0, 0, 255);
	pEndTime->setFgColor(100, 100, 100, 150);
	pEndTime->SetMaxChars(32);
	pEndTime->setVisible(false);
	setTimeEndText(pEndTime);

	iY += YRES(15)+CREATEFXOBJET_PAD;
	// Create Button
	CommandButton *pCreate = new CommandButton( "Create", iX,iY, CREATEFXOBJECT_TEXTWIDE, CREATEFXOBJECT_BUTTONTALL);
	pCreate->setContentAlignment(vgui::Label::a_center);
	pCreate->setParent( getContentPanel() );
	pCreate->addActionSignal( new CreateObjectAction );
	setCreateButton(pCreate);

	iY += CREATEFXOBJECT_BUTTONTALL+CREATEFXOBJET_PAD;

	// Set listbox height
	pListBox->setSize(pListBox->getWide(), iY-CREATEFXOBJET_PAD);

	// Resize
	getContentPanel()->setSize(iX+CREATEFXOBJECT_TEXTWIDE+CREATEFXOBJET_PAD, iY);
	resizeToContent();
}

// Update
void CCreateFXObject_VGUI::Update( void )
{	if(getObjectTypeList())
	{	getObjectTypeList()->Update();
	}
	int iSel = getObjectTypeList()->getSelectedLabel();

	// Hide/show appropiate items
	if(iSel != getCurrentSelection())
	{	// Unhide name, and times
		if(getCurrentSelection()==-1)
		{	getNameText()->setVisible(true);
			getTimeStartText()->setVisible(true);
			getTimeEndText()->setVisible(true);
		}
		setCurrentSelection(iSel);
		// hide/show when appropiate
		switch(iSel)
		{
		case OBJECT_CREATE_MDL:
			{	getModelText()->setVisible(true);
				getSpriteText()->setVisible(false);
				break;
			}
		case OBJECT_CREATE_LOCAL:
			{	getModelText()->setVisible(false);
				getSpriteText()->setVisible(false);
				break;
			}
		case OBJECT_CREATE_WRL:
			{	getModelText()->setVisible(true);
				getSpriteText()->setVisible(true);
				break;
			}
		case OBJECT_CREATE_CAMERA:
			{	getModelText()->setVisible(false);
				getSpriteText()->setVisible(false);
				break;
			}
		case OBJECT_CREATE_SOUND:
			{	getModelText()->setVisible(false);
				getSpriteText()->setVisible(false);
				break;
			}
		}
	}
}

/*
* FX Path Manager
*/
CFXDataPoint *gPathSelect = NULL;
// Create Path
class CreatePathAction : public ActionSignal
{
public:
	virtual void actionPerformed(Panel* panel)
	{	CFXListBox *pListBox = gViewPort->m_pFXToolPanel->getPathManager()->getPathList();
		CFXEvent *pEvent = gViewPort->m_pFXToolPanel->getEvent();
		if(pEvent)
		{	CPathManager *pManager = pEvent->getPathSystem()->addManager();
			char szName[32];
			sprintf(szName,"Path %i", pManager->getID());
			pManager->setName(szName);
			pListBox->addItem(pManager->getID(), pManager->getName());
		}
	};
};

// Delete Selected Path
class DeleteSelPathAction : public ActionSignal
{
public:
	virtual void actionPerformed(Panel* panel)
	{	CFXListBox *pListBox = gViewPort->m_pFXToolPanel->getPathManager()->getPathList();
		int iSel = pListBox->getSelectedLabel();
		// Delete object
		if(iSel != -1)
		{	CFXEvent *pEvent = gViewPort->m_pFXToolPanel->getEvent();
			if(pEvent)
			{	pEvent->getPathSystem()->removeManager(iSel);
			}
			pListBox->removeItem(iSel);
		}
	};
};

// Linear Point Action
class LinearPointAction : public ActionSignal
{
public:
	virtual void actionPerformed(Panel* panel)
	{	CFXPathManager_VGUI *pPathManager = gViewPort->m_pFXToolPanel->getPathManager();
		if(pPathManager->getMakePointStatus()==MAKEPOINT_LINEAR)
		{	pPathManager->setMakePointStatus(MAKEPOINT_NONE);
		}
		else
		{	pPathManager->setMakePointStatus(MAKEPOINT_LINEAR);
		}
		pPathManager->getVectorPoints()->clear();
		pPathManager->setPointMakeStage(0);
		if(gPathSelect)
		{	gPathSelect = NULL;
			pPathManager->setDragPoint(false);
			pPathManager->setDragDist(0);
		}
	}
};

bool gbreakp = false;
// Bezier Point Action
class BezierPointAction : public ActionSignal
{
public:
	virtual void actionPerformed(Panel* panel)
	{	CFXPathManager_VGUI *pPathManager = gViewPort->m_pFXToolPanel->getPathManager();
		if(pPathManager->getMakePointStatus()==MAKEPOINT_BEZIER)
		{	pPathManager->setMakePointStatus(MAKEPOINT_NONE);
		}
		else
		{	pPathManager->setMakePointStatus(MAKEPOINT_BEZIER);
			gbreakp = true;
		}
		pPathManager->getVectorPoints()->clear();
		pPathManager->setPointMakeStage(0);
		if(gPathSelect)
		{	gPathSelect = NULL;
			pPathManager->setDragPoint(false);
			pPathManager->setDragDist(0);
		}
	}
};

// By Yahn I believe
Vector CreatePickingRay( int mousex, int mousey )
{	// HACK HACK: No idea, weird offset
	float dx, dy;
	float c_x, c_y;
	float dist;
	vec3_t vpn, vup, vright;
	Vector vecPickingRay;
	vec3_t vecViewAngles;

	c_x = ScreenWidth / 2;
	c_y = ScreenHeight / 2;

	dx = (float)mousex - c_x;
	// Invert Y
	dy = c_y - (float)mousey;

	// Convert view plane distance
	float fov = 90;
	dist = c_x / tan( M_PI * float(fov) / 360.0 );

	// Decompose view angles
	vecViewAngles = g_CamAngles;
	vecViewAngles[ROLL] = 0;
	AngleVectors( vecViewAngles, vpn, vright, vup );

	// Offset forward by view plane distance, and then by pixel offsets
	vecPickingRay = vpn * dist + vright * ( dx ) + vup * ( dy );

	// Convert to unit vector
	VectorNormalize( vecPickingRay );
	return vecPickingRay;
}

#define PATHMAN_LISTBOX_HEIGHT	120
#define PATHMAN_PADDING			6
#define PATHMAN_BUTTONSIZE_Y	30
// Constructor
CFXPathManager_VGUI::CFXPathManager_VGUI(std::string strTitle, int x,int y,int wide,int tall) : CFXPanel(strTitle,x,y,wide,tall)
{	setDragPoint(false);
	setDragDist(0);
	setPointMakeStage(0);
	setMakePointStatus(MAKEPOINT_NONE);

	// Create list box
	CFXListBox *pListBox = new CFXListBox(0,0, getContentPanel()->getWide(), PATHMAN_LISTBOX_HEIGHT);
	pListBox->setParent(getContentPanel());
	pListBox->validate();
	setPathList(pListBox);

	int iStartY = pListBox->getTall() + PATHMAN_PADDING;
	int iStartX = PATHMAN_PADDING;
	float flButtonSizeX = (getContentPanel()->getWide() - PATHMAN_PADDING*2)/3-PATHMAN_PADDING/2;

	// Create Button
	CommandButton *pCreate = new CommandButton( "Create", iStartX, iStartY, flButtonSizeX, PATHMAN_BUTTONSIZE_Y);
	pCreate->setContentAlignment(vgui::Label::a_center);
	pCreate->setParent( getContentPanel() );
	pCreate->addActionSignal( new CreatePathAction );
	setCreateButton(pCreate);

	iStartX += flButtonSizeX + PATHMAN_PADDING;
	// Edit Button
	CommandButton *pEdit = new CommandButton( "Edit", iStartX, iStartY, flButtonSizeX, PATHMAN_BUTTONSIZE_Y);
	pEdit->setContentAlignment(vgui::Label::a_center);
	pEdit->setParent( getContentPanel() );
	setEditButton(pEdit);

	iStartX += flButtonSizeX + PATHMAN_PADDING;
	// Delete Button
	CommandButton *pDelete = new CommandButton( "Delete", iStartX, iStartY, flButtonSizeX, PATHMAN_BUTTONSIZE_Y);
	pDelete->setContentAlignment(vgui::Label::a_center);
	pDelete->setParent( getContentPanel() );
	pDelete->addActionSignal( new DeleteSelPathAction );
	setDeleteButton(pDelete);

	iStartX = PATHMAN_PADDING;
	iStartY += PATHMAN_BUTTONSIZE_Y + PATHMAN_PADDING;
	flButtonSizeX = (getContentPanel()->getWide() - PATHMAN_PADDING*2)/2-PATHMAN_PADDING/2;
	// Linear Button
	CommandButton *pLinear = new CommandButton( "Linear P", iStartX, iStartY, flButtonSizeX, PATHMAN_BUTTONSIZE_Y);
	pLinear->setContentAlignment(vgui::Label::a_center);
	pLinear->setParent( getContentPanel() );
	pLinear->addActionSignal( new LinearPointAction );
	setLinearButton(pLinear);

	iStartX += flButtonSizeX + PATHMAN_PADDING;
	// Bezier Button
	CommandButton *pBezier = new CommandButton( "Bezier P", iStartX, iStartY, flButtonSizeX, PATHMAN_BUTTONSIZE_Y);
	pBezier->setContentAlignment(vgui::Label::a_center);
	pBezier->setParent( getContentPanel() );
	pBezier->addActionSignal( new BezierPointAction );
	setBezierButton(pBezier);

	// Resize content panel to fit
	getContentPanel()->setSize(getContentPanel()->getWide(), iStartY + PATHMAN_BUTTONSIZE_Y + PATHMAN_PADDING);
	resizeToContentTall();
}

// Update
#include "pm_defs.h"
#include "pmtrace.h"
void CFXPathManager_VGUI::Update( void )
{	if(gbreakp)
	{	int aaaa = 5;
	}
	if(getContentPanel()->isVisible())
	{	getPathList()->Update();
	}
	// Drag point around
	if(gPathSelect && getDragPoint())
	{	int x,y;
		App::getInstance()->getCursorPos(x,y);
		gViewPort->m_pFXToolPanel->screenToLocal(x,y);
		vec3_t vecPos = g_CamOrigin + CreatePickingRay(x,y)*getDragDist();
		vecPos = vecPos - gViewPort->m_pFXToolPanel->getEvent()->getBasePosition();
		gPathSelect->setStaticPosition(vecPos);
		// Recalculate bezier points
		CPathManager *pManager = gViewPort->m_pFXToolPanel->getEvent()->getPathSystem()->getManager(getPathList()->getSelectedLabel());
		if(pManager)
		{	pManager->calculateLength();
		}
	}

	// Point making
	if(getMakePointStatus()!=MAKEPOINT_NONE)
	{	// move around point, depending on stage
		if(getPointMakeStage()>0)
		{	int x,y;
			App::getInstance()->getCursorPos(x,y);
			gViewPort->m_pFXToolPanel->screenToLocal(x,y);

			// move around point using picking ray
			if(getPointMakeStage()==1)
			{	std::vector<vec3_t>::iterator iterLast = getVectorPoints()->end();
				iterLast--;
				
				// do traceline
				vec3_t vecTraceEnd = g_CamOrigin + CreatePickingRay(x,y) * 8192;
				
				pmtrace_t tr;
				tr = *(gEngfuncs.PM_TraceLine((float *)&g_CamOrigin, (float *)&vecTraceEnd , PM_TRACELINE_PHYSENTSONLY ,2, -1));

				(*iterLast) = tr.endpos;
			}
			// Move front/back
			else
			{	std::vector<vec3_t>::iterator iterLast = getVectorPoints()->end();
				iterLast--;

				float flFraction = float(y)/float(ScreenHeight-gViewPort->m_pFXToolPanel->getTimeline()->getTall());
				if(flFraction > 1)
					flFraction = 1;
				(*iterLast) = g_CamOrigin + getTempVecDir().Normalize() * (float(getDragDist())*flFraction);
			}
		}

		// Render sparks for all points
		std::vector<vec3_t>::iterator iterRender;
		ForEachIn(iterRender,(*getVectorPoints()))
		{	gEngfuncs.pEfxAPI->R_SparkShower( (*iterRender) );
		}
	}
}

// Update Event Data
void CFXPathManager_VGUI::updateEventData( void )
{	CFXEvent *pEvent = gViewPort->m_pFXToolPanel->getEvent();
	// Fill list with paths
	if(pEvent)
	{	getPathList()->removeAll();
		std::list<CPathManager>::iterator iterPath;
		ForEachIn(iterPath, (*pEvent->getPathSystem()->getPaths()))
		{	getPathList()->addItem(iterPath->getID(), iterPath->getName());
		}
	}
}

// Reset
void CFXPathManager_VGUI::Reset( void )
{	getPathList()->Reset();
	gPathSelect = NULL;
	setDragPoint(false);
	setPointMakeStage(0);
	getVectorPoints()->clear();
}

// Get selectable path point at cursor position
#define MIN_SELECT_DOT	0.995
CFXDataPoint *CFXPathManager_VGUI::getSelectPathPoint( void )
{	// We have a selected path, get closest point
	if(getPathList()->getSelectedLabel() != -1)
	{	CPathManager *pManager = gViewPort->m_pFXToolPanel->getEvent()->getPathSystem()->getManager(getPathList()->getSelectedLabel());
		if(pManager)
		{	int x,y;
			App::getInstance()->getCursorPos(x,y);
			gViewPort->m_pFXToolPanel->screenToLocal(x,y);
			vec3_t vecRay = CreatePickingRay(x,y);
			CFXDataPoint *pClosest = pManager->getClosestPointToRay(vecRay);
			if(pClosest)
			{	// In range, select
				if(DotProduct(vecRay,(pClosest->getPosition()-g_CamOrigin).Normalize()) > MIN_SELECT_DOT)
				{	return pClosest;
				}
			}
		}
	}
	return NULL;
}

// Mouse Click
void CFXPathManager_VGUI::mouseClick( void )
{	if(getMakePointStatus()==MAKEPOINT_NONE)
	{	CFXDataPoint *pPoint = getSelectPathPoint();
		// Select
		if(pPoint)
		{	// Second click on this object, drag
			if(gPathSelect && (gPathSelect == pPoint))
			{	setDragPoint(true);
				setDragDist((gPathSelect->getPosition()-g_CamOrigin).Length());
			}
			else
				gPathSelect = pPoint;
		}
		// Deselect
		else if(gPathSelect)
		{	gPathSelect=NULL;
		}
	}
	// Make points
	else
	{	// We're moving a point
		if(getPointMakeStage()>0)
		{	// moving around using picking ray 
			if(getPointMakeStage()==1)
			{	setPointMakeStage(2);
				// store off distance, turn point into directional vector
				std::vector<vec3_t>::iterator iterLast = getVectorPoints()->end();
				iterLast--;
				setDragDist((g_CamOrigin-(*iterLast)).Length());
				setTempVecDir(((*iterLast)-g_CamOrigin).Normalize());
			}
			// Moving forward/backwards, complete
			else
			{	setPointMakeStage(0);
				setDragDist(0);

				// Complete! Try to add to selected path
				if(getPathList()->getSelectedLabel() != -1)
				{	CPathManager *pManager = gViewPort->m_pFXToolPanel->getEvent()->getPathSystem()->getManager(getPathList()->getSelectedLabel());
					if(pManager)
					{	vec3_t vOrg = gViewPort->m_pFXToolPanel->getEvent()->getBasePosition();
						CPathSegment *pSeg = pManager->getCurrentSegment();
						// Blank path, add points
						if(!pSeg || ((pSeg->linearPath() && (getMakePointStatus()==MAKEPOINT_BEZIER)) ||
									((pSeg->bezierPath() && (getMakePointStatus()==MAKEPOINT_LINEAR)))))
						{	if((getVectorPoints()->size() == 2) && getMakePointStatus()==MAKEPOINT_LINEAR)
							{	pManager->addLinearPath((*getVectorPoints())[0]-vOrg, (*getVectorPoints())[1]-vOrg);
								getVectorPoints()->clear();
							}
							else if((getVectorPoints()->size() == 4) && getMakePointStatus()==MAKEPOINT_BEZIER)
							{	pManager->addBezierPath((*getVectorPoints())[0]-vOrg, (*getVectorPoints())[1]-vOrg, (*getVectorPoints())[2]-vOrg, (*getVectorPoints())[3]-vOrg);
								getVectorPoints()->clear();
							}
						}
						// Current segment
						else
						{	// add single linear point
							if(pSeg->linearPath() && getMakePointStatus() == MAKEPOINT_LINEAR)
							{	((CLinearPath*)pSeg)->addPoint((*getVectorPoints())[0]-vOrg);
								getVectorPoints()->clear();
							}
							// add pair of bezier points
							else if(pSeg->bezierPath() && getMakePointStatus() == MAKEPOINT_BEZIER && (getVectorPoints()->size() == 2))
							{	((CBezierPath*)pSeg)->addPoints((*getVectorPoints())[1]-vOrg, (*getVectorPoints())[0]-vOrg);
								getVectorPoints()->clear();
							}
						}
					}
				}
				// No selection, dont bother.. delete points
				else
				{	getVectorPoints()->clear();
				}
			}
		}
		// Add new vector
		else if(getPathList()->getSelectedLabel() != -1)
		{	getVectorPoints()->push_back(vec3_t(0,0,0));
			setPointMakeStage(1);
		}
	}
}

// Mouse Release
void CFXPathManager_VGUI::mouseRelease( void )
{	if(gPathSelect && getDragPoint())
	{	setDragPoint(false);
		setDragDist(0);
	}
}

/*
* FX Tool Bar
*/
#define INCMAG_SCALE	2.00
#define DECMAG_SCALE	0.50
#define MAXMAG_SCALE	16.00
#define MINMAG_SCALE	0.50
// Magnification action
class MagAction : public ActionSignal
{
public:
	MagAction( )
	{	setIncMag(true);
	}

	MagAction( bool inc )
	{	setIncMag(inc);
	}

	virtual void actionPerformed(Panel* panel)
	{	CTimelineMeter *pTimelineMeter = gViewPort->m_pFXToolPanel->getTimeline()->getTimelineMeter();
		if(pTimelineMeter)
		{	// Increase magnification
			if(getIncMag())
			{	if(pTimelineMeter->getScale() < MAXMAG_SCALE)
					pTimelineMeter->setScale(pTimelineMeter->getScale()*INCMAG_SCALE);
			}
			// Decrease magnification
			else
			{	if(pTimelineMeter->getScale() > MINMAG_SCALE)
					pTimelineMeter->setScale(pTimelineMeter->getScale()*DECMAG_SCALE);
			}
			// Resize and validate
			pTimelineMeter->setSize(pTimelineMeter->calcMaxWidth(),TIMELINE_TICK_HEIGHT);
			// Calc size for timeline strips too
			gViewPort->m_pFXToolPanel->getTimeline()->realignStrips();

			// validate
			gViewPort->m_pFXToolPanel->getTimeline()->getTimedEventDataPanel()->validate();
		}
	}

	// Accessors
	void setIncMag( bool mag ) { m_bIncMag = mag; }
	bool getIncMag( void ) { return m_bIncMag; }
private:
	bool m_bIncMag;
};
#include "VGUI_TextImage.h"
#include "vgui_loadtga.h"
#define TOOLBAR_PADDING	16
#define TOOLBAR_SEPDIST	5
// Constructor
CFXToolBar_VGUI::CFXToolBar_VGUI(std::string strTitle, int x,int y,int wide,int tall) : CFXPanel(strTitle,x,y,wide,tall)
{	// Align text to right
	getTitle()->setContentAlignment( vgui::Label::a_west );
	
	int iButtonSize = getContentPanel()->getWide()-TOOLBAR_PADDING*2;
	int iStartX = TOOLBAR_PADDING;
	int iStartY = TOOLBAR_SEPDIST;

	// Select Button
	CommandButton *pSelect = new CommandButton( "S", iStartX, iStartY, iButtonSize, iButtonSize);
	pSelect->setContentAlignment(vgui::Label::a_center);
	pSelect->setParent( getContentPanel() );
	setSelectButton(pSelect);

	iStartY += iButtonSize + TOOLBAR_SEPDIST;

	// Move Button
	CommandButton *pMove = new CommandButton( "M", iStartX, iStartY, iButtonSize, iButtonSize);
	pMove->setContentAlignment(vgui::Label::a_center);
	pMove->setParent( getContentPanel() );
	setMoveButton(pMove);

	iStartY += iButtonSize + TOOLBAR_SEPDIST;

	// Rotate Button
	CommandButton *pRotate = new CommandButton( "R", iStartX, iStartY, iButtonSize, iButtonSize);
	pRotate->setContentAlignment(vgui::Label::a_center);
	pRotate->setParent( getContentPanel() );
	setRotateButton(pRotate);

	iStartY += iButtonSize + TOOLBAR_SEPDIST;

	// IncMag Button
	CommandButton *pIncMag = new CommandButton( "M+", iStartX, iStartY, iButtonSize, iButtonSize);
	pIncMag->setContentAlignment(vgui::Label::a_center);
	pIncMag->setParent( getContentPanel() );
	pIncMag->addActionSignal( new MagAction(true) );
	setIncMagButton(pIncMag);

	iStartY += iButtonSize + TOOLBAR_SEPDIST;

	// DecMag Button
	CommandButton *pDecMag = new CommandButton( "M-", iStartX, iStartY, iButtonSize, iButtonSize);
	pDecMag->setContentAlignment(vgui::Label::a_center);
	pDecMag->setParent( getContentPanel() );
	pDecMag->addActionSignal( new MagAction(false) );
	setDecMagButton(pDecMag);

	iStartY += iButtonSize + TOOLBAR_SEPDIST;
	// Set size
	getContentPanel()->setSize(getContentPanel()->getWide(), iStartY);
}

#include "vgui_fxeditormisc.h"
#include "vgui_fxeditorwindow.h"
#include "vgui_fxeditortabbed.h"
#include "vgui_fxeditorlistbox.h"
/*
* FX Tool Panel
*/
#define RIGHT_WIDTH		190
#define LEFT_WIDTH		250
#define TBAR_WIDTH		65
#define TBAR_HEIGHT		200
// Constructor
CFXToolPanel_VGUI::CFXToolPanel_VGUI() : CMenuPanel(0, 0, 0, 0, ScreenWidth, ScreenHeight)
{	setEvent(NULL);
//	setPropertyEdit(NULL);
	setEnteringText(false);
/*	setRotationMode(false);
	setMovementMode(false);
	setDragging(false);
	setDragInside(false);*/
	// Create timeline
	CFXTimeline_VGUI *pTimeline = new CFXTimeline_VGUI("Timeline", 0, ScreenHeight-100, ScreenWidth, 100);
	// Resize to content
	pTimeline->resizeToContentTall();
	// Set parent
	pTimeline->setParent(this);
	setTimeline(pTimeline);

	// Create object manager
	m_pObjectManager = new CFXObjectManager_VGUI("Object Manager", 0, 0, RIGHT_WIDTH, 100);
	// Resize to content
	m_pObjectManager->resizeToContentTall();
	// Set parent
	m_pObjectManager->setParent(this);

	// Create path manager
	CFXPathManager_VGUI *pPathManager = new CFXPathManager_VGUI("Path Manager", 0, 0, RIGHT_WIDTH, 100);
	// Resize to content
	pPathManager->resizeToContentTall();
	// Set parent
	pPathManager->setParent(this);
	setPathManager(pPathManager);

	// Create toolbar
	CFXToolBar_VGUI *pToolBar = new CFXToolBar_VGUI(" TBar", 0, 0, TBAR_WIDTH, TBAR_HEIGHT);
	// Resize to content
	pToolBar->resizeToContentTall();
	// Set parent
	pToolBar->setParent(this);
	setToolBar(pToolBar);

	/*
	*  TESTING ***********
	*/
	CManagedWindow *pWindow = new CManagedWindow(100,168,700,200,"Testing window", false);
	pWindow->setParent( this );

	CWindowTab *pTab = NULL;
	// Create tabbed window panel
	CTabbedWindow *pTabbedWindow = new CTabbedWindow(10, 10, 550, 150);

	pTab = pTabbedWindow->addTab("Fuckin Tab A");
	pTab->getPanel()->addChild(new Label("Label A content, pretty nifty!", 20, 20, 300, 20));

	pTab = pTabbedWindow->addTab("Fuckin Awesome B Extra Long Test");
//	pTab->getPanel()->addChild(new Label("Label B content, Sugoi!", 15, 15, 300, 20));
	CFileListBoxMenu *pFileList = new CFileListBoxMenu(15, 15, 300, 16*6, gEngfuncs.pfnGetGameDirectory(),"dropd_btn", "dropd_mo_btn", "dropd_sel_btn");
	pFileList->addFileType("mdl");
	pFileList->addFileType("spr");
	pFileList->addFileType("bsp");
	pFileList->buildFileList();
	pTab->getPanel()->addChild(pFileList);

	pTab = pTabbedWindow->addTab("Fuckin Pcjoe C");
	CDropDownMenu *pDropDown = new CDropDownMenu(10, 10, 256, 16);
	pDropDown->setParent(pTab->getPanel());

	CListBoxMenu *pListBox = pDropDown->getMenu();
//	CListBoxMenu *pListBox = new CListBoxMenu(10, 10, 256, 16*5, "tab_btn", "tab_mo_btn", "tab_sel_btn");
	pListBox->addItem("C Menu Item 1");
	pListBox->addItem("C Menu Item 2");
	pListBox->addItem("C Menu Item 3");
	pListBox->addItem("C Menu Item 4");
	pListBox->addItem("C Menu Item 5");
	pListBox->addItem("C Menu Item 6");
	pListBox->addItem("C Menu Item 7");
	pListBox->addItem("C Menu Item 8");

	pTab = pTabbedWindow->addTab("Fuckin Awesome D");
	CListBoxMenu *pListBox2 = new CListBoxMenu(10, 10, 256, 16*5, "dropd_btn", "dropd_mo_btn", "dropd_sel_btn");
	pListBox2->addItem("C Menu Item 1");
	pListBox2->addItem("C Menu Item 2");
	pListBox2->addItem("C Menu Item 3");
	pListBox2->addItem("C Menu Item 4");
	pListBox2->addItem("C Menu Item 5");
	pListBox2->addItem("C Menu Item 6");
	pListBox2->addItem("C Menu Item 7");
	pListBox2->addItem("C Menu Item 8");
	pListBox2->setParent(pTab->getPanel());

	pWindow->getContentPanel()->addChild(pTabbedWindow);
/*
	pWindow = new CManagedWindow(2,2,512,128,"Fuckin' Hoes");
	pWindow->setParent( this );*/

	// Align check
	alignCheck();

	// Setup rotation circle image
/*	vgui::BitmapTGA *pRotImage = vgui_LoadTGA("gfx/vgui/640_rotationcircle.tga");
	if(pRotImage)
		pRotImage->setColor(Color(255,255,256,1));
	setRotationCircleImage(pRotImage);

	// Setup rotation circle label
	Label *pRotLabel = new Label("", 200, 200, 256, 256);
	pRotLabel->setBgColor( 0, 0, 0, 255 );
	pRotLabel->setFgColor( 0, 0, 0, 255 );
	pRotLabel->setContentAlignment( vgui::Label::a_center );
	pRotLabel->setParent(this);
	pRotLabel->setImage(pRotImage);
	pRotLabel->setVisible(false);
	setRotationCircleLabel(pRotLabel);*/

/*	m_pPanel = new CTransparentPanel( 0, 40, 40, ScreenWidth/2, ScreenHeight/2);
	m_pPanel->setParent( this );
	m_pPanel->setBorder( new LineBorder( Color(255 * 0.7,170 * 0.7,0,0) ) );*/
//	m_ptestScroll
	//CTFScrollPanel
	// Create the Scroll panel
/*	m_ptestScroll = new CTFScrollPanel( 20, 20, 400, 400 );
	m_ptestScroll->setParent(this);
	//force the scrollbars on, so after the validate clientClip will be smaller
	m_ptestScroll->setScrollBarAutoVisible(false, false);
	m_ptestScroll->setScrollBarVisible(true, false);
	m_ptestScroll->setBorder( new LineBorder( Color(255 * 0.7,170 * 0.7,0,0) ) );
	m_ptestScroll->validate();

	// Test Button
	CommandButton *pButtonTest = NULL;
	for( int i = 0; i < 40; i++ )
	{	char szString[256];
		sprintf(szString, "Button Number %i", i+1);
		pButtonTest = new CommandButton( szString, 180*i, 5, 150, 30);
		pButtonTest->setParent( m_ptestScroll->getClient() );
		pButtonTest->setContentAlignment(vgui::Label::a_center);
		pButtonTest->addActionSignal( new FXNumberDisplayer(i+1) );
	}
	m_ptestScroll->validate();

	// Test Slider functionality
	gpSliderTest = new Slider( 10, 100, 100, 30, false );
	gpSliderTest->setParent( m_ptestScroll->getClient() );
	gpSliderTest->setRange(0, 200);
	m_ptestScroll->validate();*/
}


// Realign all items
void CFXToolPanel_VGUI::alignCheck( void )
{	
	// Align timeline to bottom
	getTimeline()->alignBottom(ScreenHeight);

	// Get timeline pos
	int iTimelineSide, iTimelineTop;
	getTimeline()->getPos(iTimelineSide, iTimelineTop);

	// Align object manager to right above timeline
	getObjectManager()->alignRight(ScreenWidth);
	getObjectManager()->alignBottom(iTimelineTop-1);

	// Get object manager pos
	int iObjectManagerSide, iObjectManagerTop;
	getObjectManager()->getPos(iObjectManagerSide, iObjectManagerTop);

	// Align path manager above object manager
	getPathManager()->alignRight(ScreenWidth);
	getPathManager()->alignBottom(iObjectManagerTop-1);
	
	// Align toolbar to left screen above timeline
	getToolBar()->alignLeft(0);
	getToolBar()->alignBottom(iTimelineTop-1);
}

// Update
#include "pm_defs.h"
#include "pmtrace.h"
void CFXToolPanel_VGUI::Update( void )
{	getObjectManager()->Update();
	getPathManager()->Update();
	getToolBar()->Update();
	getTimeline()->Update();
//	updateSelectedEnt();
	updatePropPanels();

	// TEST
/*	if(isVisible())
	{	int x,y;
		App::getInstance()->getCursorPos(x,y);
		vec3_t vecRay = CreatePickingRay(x,y);

		vec3_t vecTraceEnd = g_CamOrigin + vecRay * 1024;
		
		pmtrace_t tr;
		tr = *(gEngfuncs.PM_TraceLine((float *)&g_CamOrigin, (float *)&vecTraceEnd , PM_TRACELINE_PHYSENTSONLY ,2, -1));

		gEngfuncs.pEfxAPI->R_SparkShower( tr.endpos );
	}*/
}

// Update Event Data
void CFXToolPanel_VGUI::updateEventData( void )
{	getObjectManager()->updateEventData();
	getPathManager()->updateEventData();
	getToolBar()->updateEventData();
	getTimeline()->updateEventData();
	resetPropPanels();
}

// Reset
void CFXToolPanel_VGUI::Reset( void )
{	getObjectManager()->Reset();
	getPathManager()->Reset();
	getToolBar()->Reset();
	getTimeline()->Reset();
	resetPropPanels();
}

// Update Property Panels
void CFXToolPanel_VGUI::updatePropPanels( void )
{	// Disable keys for panel
	std::list<CFXBaseTimeProp*>::iterator iterUpdate;
	ForEachIn(iterUpdate,(*getPropertyPanels()))
	{	(*iterUpdate)->Update();
		(*iterUpdate)->dragThink();
	}
}

// Add Property Panel
void CFXToolPanel_VGUI::addPropPanel( CFXBaseTimeProp *pPanel )
{	getPropertyPanels()->push_back(pPanel);
}

// Remove Property Panel
void CFXToolPanel_VGUI::removePropPanel( CFXBaseTimeProp *pPanel )
{	std::list<CFXBaseTimeProp*>::iterator iterRemove;
	ForEachIn(iterRemove,(*getPropertyPanels()))
	{	if((*iterRemove) == pPanel)
		{	pPanel->Disable();
			removeChild(pPanel);
			getPropertyPanels()->erase(iterRemove);
			return;
		}
	}
}
// Reset Property Panels
void CFXToolPanel_VGUI::resetPropPanels( void )
{	std::list<CFXBaseTimeProp*>::iterator iterRemove;
	ForEachIn(iterRemove,(*getPropertyPanels()))
	{	removeChild((*iterRemove));
	}
	getPropertyPanels()->clear();
}
/*
// Update Entity Movement/Rotational Status
void CFXToolPanel_VGUI::updateSelectedEnt( void )
{	// Update Rotation Data
	if(getRotationMode())
	{	// Handle Rotation Label
		Label *pRotLabel = getRotationCircleLabel();
		if(pRotLabel)
		{	if(!pRotLabel->isVisible())
			{	pRotLabel->setVisible(true);
			}

			// Get property we're dealing with
			CFXTimeProp_Rotation_VGUI *pProp = (CFXTimeProp_Rotation_VGUI*)getPropertyEdit();
			if(pProp)
			{	// Get timed event
				CTimedEventRotation *pTimedRot = ((CTimedEventRotation*)pProp->getEditEvent()->second);
				if(pTimedRot)
				{	// Get Object
					CFXObject3D *pObj = (CFXObject3D*)gViewPort->m_pFXToolPanel->getEvent()->getObjectByIndex(pProp->getObjectID());
					if(pObj)
					{	// Get screen position for object
						vec3_t vecScreen;
						gEngfuncs.pTriAPI->WorldToScreen(pObj->getPosition(),vecScreen);
						Vector2D vecLabPos(XPROJECT(vecScreen.x)-pRotLabel->getWide()/2, YPROJECT(vecScreen.y)-pRotLabel->getTall()/2);
						pRotLabel->setPos(vecLabPos.x,vecLabPos.y);
						Vector2D vecCenter(XPROJECT(vecScreen.x),YPROJECT(vecScreen.y));
						vecScreen.z = 0;

						// get mouse position
						int x,y;
						App::getInstance()->getCursorPos(x,y);
						screenToLocal(x,y);
						Vector2D vecMouse(x,y);

						if(g_MouseCap.getStatus(0))
						{	// Continue dragging
							if(getDragging())
							{	Vector2D vecDeltaMove = vecMouse-getLastMousePosition();
								// Mouse moved
								if(vecDeltaMove.Length()>0)
								{	vec3_t vecViewDir = (pObj->getPosition()-g_CamOrigin).Normalize();
								
									// Decompose view angles
									vec3_t vecForward, vecRight, vecUp;
									AngleVectors( vecViewDir, vecForward, vecRight, vecUp );
									// Yaw/Pitch
									if(getDragInside())
									{	// Get Rotation
										CQuaternion qYaw,qPitch;
										qYaw.FromAxisAndAngle(vecUp,vecDeltaMove.x);
										qPitch.FromAxisAndAngle(vecRight,vecDeltaMove.y);
										qYaw.Multiply(qPitch);

										// add angles and set
										pTimedRot->getRotation()->Multiply(qYaw);
									//	pTimedRot->getRotation()->Multiply(qPitch);
									}
									// Roll
									else
									{	Vector2D vecAngC = (vecMouse-vecCenter);
										Vector2D vecAngO = (getLastMousePosition()-vecCenter);
										float flAngC = atan2(vecAngC.y,vecAngC.x)* (180/M_PI);
										float flAngO = atan2(vecAngO.y,vecAngO.x)* (180/M_PI);
										if(flAngC<0)
											flAngC += 360;
										if(flAngO<0)
											flAngO += 360;
										float flDiff = flAngC-flAngO;
										if(flDiff>360)
											flDiff-=360;
										
										CQuaternion qRot;
										qRot.FromAxisAndAngle(vecForward, flDiff);
										pTimedRot->getRotation()->Multiply(qRot);
									}
								}
							}
							// Start dragging
							else
							{	setDragging(true);
								// see if we're dragging inside
								if((vecMouse-vecCenter).Length() < float(pRotLabel->getWide())/float(2))
								{	setDragInside(true);
								}
							}
						}
						else
						{	if(getDragging())
							{	setDragging(false);
								setDragInside(false);
							}
						}
						// set last mouse pos
						setLastMousePosition(vecMouse);
					}
				}
			}
		}
	}
	// Disable visibility if we're not enabled
	else if(getRotationCircleLabel()->isVisible())
	{	getRotationCircleLabel()->setVisible(false);
	}
}*/

// Mouse Pressed
void CFXToolPanel_VGUI::internalMousePressed(MouseCode code)
{	getPathManager()->mouseClick();
}

// Mouse Released
void CFXToolPanel_VGUI::internalMouseReleased(MouseCode code)
{	getPathManager()->mouseRelease();
}

// Mouse exit ( same as release )
void CFXToolPanel_VGUI::internalCursorExited()
{	getPathManager()->mouseRelease();
}