/*
* FX Editor Window Class
* @version 7-11-06
* @author Joseph 'Pcjoe' Florencio
*/

#include "hud.h"
#include "cl_util.h"
#include "const.h"
#include "entity_state.h"
#include "cl_entity.h"
#include "vgui_loadtga.h"
#include "vgui_TeamFortressViewport.h"
#include "vgui_fxeditormisc.h"
#include "vgui_fxeditorwindow.h"
#include "vgui_fxtoolpanel.h"
#include <VGUI_TextImage.h>

/*
* Image Panel Class, Customized for windows label
*/
// Paint
void CImagePanelCustomW::paint()
{	// Paint title label
	if(getWindow() && getWindow()->getTitleLabel())
		getWindow()->getTitleLabel()->doPaint(this);

	// Draw line at bottom (separating label and content)
/*	int wide,tall;
	getSize(wide,tall);
	drawSetColor(255,0,0,0);
	drawOutlinedRect(0,tall,wide,tall);*/

	CImagePanel::paint();
}

/*
* Window Drag Input Signal
*/
void CHandler_WindowDrag::mousePressed(MouseCode code,Panel* panel)
{	// Assume panel's parent is a CManagedWindow
	((CManagedWindow*)panel->getParent())->enableDrag();
	// Dragging also forces a panel to the front
	((CManagedWindow*)panel->getParent())->toFront();

}

void CHandler_WindowDrag::mouseReleased(MouseCode code,Panel* panel)
{	// Assume panel's parent is a CManagedWindow
	((CManagedWindow*)panel->getParent())->disableDrag();
}


/*
* Window Minimize Input Signal
*/
void CHandler_WindowMinimize::mouseReleased(MouseCode code,Panel* panel)
{	// Button is calling this, it's parent is the window label, and ITS parent is the actual window
	CManagedWindow *pWindow = (CManagedWindow*)panel->getParent()->getParent();
	if(pWindow->isMinimized())
		pWindow->maximize();
	else
		pWindow->minimize();
}

/*
* Window Close Input Signal
*/
void CHandler_WindowClose::mouseReleased(MouseCode code,Panel* panel)
{	// Call close function for cleanup, then remove child from parent
	// Button is calling this, it's parent is the window label, and ITS parent is the actual window
	CManagedWindow *pWindow = (CManagedWindow*)panel->getParent()->getParent();
	pWindow->close();
	pWindow->getParent()->removeChild(pWindow);
}

/*
* Managed Window Class
*/
#define X_BTN_OFFSET_RIGHT 8
#define MIN_BTN_OFFSET_RIGHT 4
extern CMouseCapture g_MouseCap;

// Constructor
CManagedWindow::CManagedWindow(int x, int y, int wide, int tall, string title, bool exitEnabled, bool minEnabled) : CTransparentPanel(0,x,y,wide,tall)
{	/*
	* Create panels
	*/
	setTitleLabel( title != "" ? new TextImage(title.c_str()) : NULL );
	setTitleBar( new CImagePanelCustomW("window_titlebar", PANELTILE_HORIZONTAL, 0, 0, 1, 1 ) );
	setExitButton( exitEnabled ? new CFadeImageButton(0,0,0,0,getImageVGUIBTGA("x_btn"),getImageVGUIBTGA("x_mo_btn")) : NULL );
	setMinimizeButton( minEnabled ? new CFadeImageButton(0,0,0,0,getImageVGUIBTGA("min_btn"),getImageVGUIBTGA("min_mo_btn")) : NULL );
	setContentPanel( new CTransparentPanel(222,0,0,1,1) );

	// Reset drag
	disableDrag();

	// Add border
	setBorder( new LineBorder( Color(255,0,0,0) ) );
	
	// Set parent and signals for title bar
	getTitleBar()->setParent(this);
	getTitleBar()->setWindow(this);
	getTitleBar()->addInputSignal( new CHandler_WindowDrag );

	// Exit button
	if(getExitButton())
	{	getExitButton()->setParent(getTitleBar());
		// Add tooltip
		getExitButton()->addInputSignal( new CHandler_TooltipButtonOver("#tooltip_exit") );
		// add exit input signal
		getExitButton()->addInputSignal( new CHandler_WindowClose );
	}

	// Minimize button
	if(getMinimizeButton())
	{	getMinimizeButton()->setParent(getTitleBar());
		// Add tooltip
		getMinimizeButton()->addInputSignal( new CHandler_TooltipButtonOver("#tooltip_minimize") );
		// add minimize input signal
		getMinimizeButton()->addInputSignal( new CHandler_WindowMinimize );
	}

	// Set color for title label text
	if(getTitleLabel())
	{	getTitleLabel()->setColor( Color(255,255,255,0) );
	}

	// Set content panel parent
	getContentPanel()->setParent(this);

	/*
	* Align and resize panels
	*/
	resizeContentToWindow();
}

// Resize to content panel
void CManagedWindow::resizeToContent( void )
{	int wide,tall,wideBar,tallBar;
	// Get sizes of content panel and title bar
	getContentPanel()->getSize(wide,tall);
	getTitleBar()->getSize(wideBar,tallBar);

	// Account for border, and top label
	wide += 2;
	tall += 2 + tallBar;
	
	// Set size
	setSize(wide,tall);

	// resize content to window since main window is already resized accordingly
	resizeContentToWindow();
}

// Resize content panel to fit in window
void CManagedWindow::resizeContentToWindow( void )
{	// Get panel size
	int wide,tall;
	getSize(wide,tall);

	// Take two units off of wide and tall to account for border
	wide-=2;
	tall-=2;
	
	// Resize title bar
	int wideComp,tallComp,tallTitleBar;
	getTitleBar()->getImage()->getSize(wideComp,tallComp);
	getTitleBar()->setSize(wide,tallComp);
	tallTitleBar = tallComp;

	// Reposition exit button
	int iExitStartX = wide;
	if(getExitButton())
	{	getExitButton()->getSize(wideComp,tallComp);
		iExitStartX -= wideComp+X_BTN_OFFSET_RIGHT;
		getExitButton()->setPos(iExitStartX,0);
	}

	// Reposition minimize button
	if(getMinimizeButton())
	{	getMinimizeButton()->getSize(wideComp,tallComp);
		if(getExitButton())
			iExitStartX -= wideComp+MIN_BTN_OFFSET_RIGHT;
		else
			iExitStartX -= wideComp+X_BTN_OFFSET_RIGHT;
		getMinimizeButton()->setPos(iExitStartX,0);
	}

	// Align title to center
	if(getTitleLabel())
	{	// get right bounds
		int iRightBounds = wide;
		if(getExitButton())
			iRightBounds -= wideComp+X_BTN_OFFSET_RIGHT;
		if(getMinimizeButton())
			iRightBounds -= wideComp+MIN_BTN_OFFSET_RIGHT;

		// get size of text
		int textSizeWide, textSizeTall;
		getTitleLabel()->getTextSize(textSizeWide,textSizeTall);
		// Set position to align to middle
		int test = iRightBounds/2-textSizeWide/2;
		getTitleLabel()->setPos(iRightBounds/2-textSizeWide/2,0);
		getTitleLabel()->setSize(textSizeWide,textSizeTall);
	}

	// Set content panel size and position
	getContentPanel()->setPos(0,tallTitleBar);
	getContentPanel()->setSize(wide,tall-tallTitleBar);
}

// HACK HACK: Paint background used as a 'think' function for dragging
void CManagedWindow::paintBackground( void )
{	// Currently being dragged
	if(getDragged())
	{	// No longer holding down mouse button, cut out of dragging
		if(!g_MouseCap.getStatus(0))
		{	disableDrag();
			return;
		}

		int x,y;
		// get current pos
		App::getInstance()->getCursorPos(x,y);
		Vector2D vecCurrent(x,y);
		// get difference
		Vector2D vecDiff = vecCurrent-getDraggedStart();
		// update position with difference
		getPos(x,y);
		setPos(x+vecDiff.x,y+vecDiff.y);
		// Update previous position with current
		setDraggedStart(vecCurrent);

		// Ensure we're still within the bounds of our parent
		keepOnScreen();
	}
}

// Enable Drag
void CManagedWindow::enableDrag( void )
{	int x,y;
	App::getInstance()->getCursorPos(x,y);
	setDraggedStart(Vector2D(x,y));
	setDragged(true);
}

// Disable Drag
void CManagedWindow::disableDrag( void )
{	setDraggedStart(Vector2D(0,0));
	setDragged(false);
}

// Keep on Screen (Push back to on screen if panel lies outside of screen bounds)
void CManagedWindow::keepOnScreen( void )
{	int x,y,wide,tall;
	getPos(x,y);
	getSize(wide,tall);

	int parentWide=ScreenWidth,parentTall=ScreenHeight;

	if(getParent())
		getParent()->getSize(parentWide,parentTall);

	// Keep in bounds of parent
	if(x < 0)
	{	x=0;
		setPos(x,y);
	}
	if(y < 0)
	{	y=0;
		setPos(x,y);
	}
	if((x+wide) > parentWide)
	{	x = parentWide-wide;
		setPos(x,y);
	}
	if((y+tall) > parentTall)
	{	y = parentTall-tall;
		setPos(x,y);
	}
}

// Is Minimized
bool CManagedWindow::isMinimized( void )
{	return !getContentPanel()->isVisible();
}

// Minimize
void CManagedWindow::minimize( void )
{	if(!isMinimized())
	{	int wide,tall,wideWindow,tallWindow;
		getContentPanel()->getSize(wide,tall);
		getSize(wideWindow,tallWindow);
		// Hide content panel and shrink main window
		getContentPanel()->setVisible(false);
		setSize(wideWindow,tallWindow-tall);
	}
}

// Maximize
void CManagedWindow::maximize( void )
{	if(isMinimized())
	{	int wide,tall,wideWindow,tallWindow;
		getContentPanel()->getSize(wide,tall);
		getSize(wideWindow,tallWindow);
		// Show content panel and expand main window
		getContentPanel()->setVisible(true);
		setSize(wideWindow,tallWindow+tall);
	}
}

// To front (pushes the child to the front)
void CManagedWindow::toFront( void )
{	((CFXToolPanel_VGUI*)getParent())->_childDar.removeElement(this);
	((CFXToolPanel_VGUI*)getParent())->_childDar.addElement(this);
}

// Close cleanup
void CManagedWindow::close( void )
{
}