//========= Copyright © 1996-2001, Valve LLC, All rights reserved. ============
//
// Purpose: 
//
// $NoKeywords: $
//=============================================================================

#ifndef MAPATOM_H
#define MAPATOM_H
#pragma once

#include "worldcraft_mathlib.h"


class Box3D;
class CRender2D;
class CRender3D;


enum SelectionState_t
{
	SELECT_NONE = 0,			// unselected
	SELECT_NORMAL,				// selected
	SELECT_MORPH,				// selected for vertex manipulation
	SELECT_MULTI_PARTIAL,		// partial selection in a multiselect
	SELECT_MODIFY,				// being modified by a tool
};

//
// Notification codes for NotifyDependents.
//
enum Notify_Dependent_t
{
	Notify_Changed = 0,		// The notifying object has changed.
	Notify_Removed,			// The notifying object is being removed from the world.
	Notify_Undo,
	Notify_Transform,
	Notify_Flipped,
	Notify_Rebuild
};

class CMapAtom
{
	public:

		//-----------------------------------------------------------------------------
		// Purpose: Debugging hook.
		//-----------------------------------------------------------------------------
		virtual void Debug(void) {}

		//-----------------------------------------------------------------------------
		// Purpose: Returns whether this object is selected.
		//-----------------------------------------------------------------------------
		virtual bool IsSelected(void) const
		{
			return(m_eSelectionState != SELECT_NONE);
		}

		//-----------------------------------------------------------------------------
		// Purpose: Returns the current selection state of this object.
		//-----------------------------------------------------------------------------
		virtual SelectionState_t GetSelectionState(void) const
		{
			return(m_eSelectionState);
		}

		//-----------------------------------------------------------------------------
		// Purpose: Sets the current selection state of this object.
		//-----------------------------------------------------------------------------
		virtual SelectionState_t SetSelectionState(SelectionState_t eSelectionState)
		{
			SelectionState_t ePrevState = m_eSelectionState;
			m_eSelectionState = eSelectionState;
			return ePrevState;
		}
		
		//-----------------------------------------------------------------------------
		// Purpose: Sets the render color of this object.
		//-----------------------------------------------------------------------------
		virtual void SetRenderColor(unsigned char red, unsigned char green, unsigned char blue)
		{
			r = red;
			g = green;
			b = blue;
		}
		
		//-----------------------------------------------------------------------------
		// Purpose: Sets the render color of this object.
		//-----------------------------------------------------------------------------
		virtual void SetRenderColor(color32 rgbColor)
		{
			r = rgbColor.r;
			g = rgbColor.g;
			b = rgbColor.b;
		}

		//-----------------------------------------------------------------------------
		// Purpose: Returns the render color of this object.
		//-----------------------------------------------------------------------------
		virtual void GetRenderColor(unsigned char &red, unsigned char &green, unsigned char &blue)
		{
			red = r;
			green = g;
			blue = b;
		}
		
		//-----------------------------------------------------------------------------
		// Purpose: Returns the render color of this object.
		//-----------------------------------------------------------------------------
		virtual color32 GetRenderColor(void)
		{
			color32 rgbColor;
			rgbColor.r = r;
			rgbColor.g = g;
			rgbColor.b = b;
			rgbColor.a = 0;

			return rgbColor;
		}
		
		//-----------------------------------------------------------------------------
		// Purpose: Sets this object's parent.
		// Input  : pParent - 
		//-----------------------------------------------------------------------------
		virtual void SetParent(CMapAtom *pParent)
		{
			m_pParent = pParent;
		}

		//-----------------------------------------------------------------------------
		// Purpose: Returns the parent of this CMapAtom.
		// Output : Parent pointer, NULL if this object has no parent.
		//-----------------------------------------------------------------------------
		virtual CMapAtom *GetParent(void) const
		{
			return(m_pParent);
		}

		//-----------------------------------------------------------------------------
		// Purpose: Preloads any rendering info (textures, etc.). Called once per object
		//			from the renderer's Initialize function.
		// Input  : pRender - Pointer to the 3D rendering interface.
		//			bNewContext - True if the renderer pointed to by pRender is a new
		//				rendering context, false if not.
		//-----------------------------------------------------------------------------
		virtual bool RenderPreload(CRender3D *pRender, bool bNewContext)
		{
			return(true);
		}

		//-----------------------------------------------------------------------------
		// Purpose: Renders this object into the 3D view.
		// Input  : pRender - Pointer to the 3D rendering interface.
		//-----------------------------------------------------------------------------
		virtual void Render3D(CRender3D *pRender)
		{
		}

		//-----------------------------------------------------------------------------
		// Purpose: Renders this object into the 3D view.
		// Input  : pRender - Pointer to the 3D rendering interface.
		//-----------------------------------------------------------------------------
		virtual void Render2D(CRender2D *pRender)
		{
		}

		//-----------------------------------------------------------------------------
		// Purpose: Returns a coordinate frame to render in
		// Input  : matrix - 
		// Output : returns true if a new matrix is returned, false if the new matrix is bad
		//-----------------------------------------------------------------------------
		virtual bool GetTransformMatrix( matrix4_t& matrix )
		{
			// try and get our parents transform matrix
			CMapAtom *p = GetParent();
			if ( p )
			{
				return p->GetTransformMatrix( matrix );
			}

			return false;
		}

		//-----------------------------------------------------------------------------
		// Transformation functions.
		//-----------------------------------------------------------------------------
		void Transform(Box3D *t)
		{
			DoTransform(t);
			PostUpdate(Notify_Transform);
		}

		void TransMove(const Vector &Delta)
		{
			DoTransMove(Delta);
			PostUpdate(Notify_Transform);
		}

		void TransRotate(const Vector *pRefPoint, const QAngle &Angles)
		{
			DoTransRotate(pRefPoint, Angles);
			PostUpdate(Notify_Transform);
		}

		void TransScale(const Vector &RefPoint, const Vector &Scale)
		{
			DoTransScale(RefPoint, Scale);
			PostUpdate(Notify_Transform);
		}

		void TransFlip(const Vector &RefPoint)
		{
			DoTransFlip(RefPoint);
			PostUpdate(Notify_Flipped);
		}

		//-----------------------------------------------------------------------------
		// Must be called after modifying the object for bounds recalculation and
		// dependency updates.
		//-----------------------------------------------------------------------------
		virtual void PostUpdate(Notify_Dependent_t eNotifyType) {}

		//-----------------------------------------------------------------------------
		// Override this for helpers. This indicates whether a helper provides a visual
		// representation for the entity that it belongs to. Entities with no
		// visual elements are given a default box so they can be seen.
		//-----------------------------------------------------------------------------
		virtual bool IsVisualElement(void) { return(false);	}

		//-----------------------------------------------------------------------------
		// Override this to tell the renderer to render you last. This is useful for
		// alpha blended elements such as sprites.
		//-----------------------------------------------------------------------------
		virtual bool ShouldRenderLast(void)
		{
			return(false);
		}

	protected:

		CMapAtom(void)
		{
			m_eSelectionState = SELECT_NONE;
			m_pParent = NULL;
		}

		//-----------------------------------------------------------------------------
		// DoTransform functions. Virtual, called by base Transfom functions.
		//-----------------------------------------------------------------------------
		virtual void DoTransform(Box3D *t) {}
		virtual void DoTransMove(const Vector &Delta) {}
		virtual void DoTransRotate(const Vector *pRefPoint, const QAngle &Angles) {}
		virtual void DoTransScale(const Vector &RefPoint, const Vector &Scale) {}
		virtual void DoTransFlip(const Vector &RefPoint) {}

		CMapAtom *m_pParent;				// This object's parent.
		SelectionState_t m_eSelectionState;	// The current selection state of this object.

		unsigned char r;					// Red color component.
		unsigned char g;					// Green color component.
		unsigned char b;					// Blue color component.
}; 


#endif // MAPATOM_H
