///////////////////////////////////////////////////////////////////////////////
/// @file dePortal.hpp
///
/// @brief Portal culling routines
///
/// @author Assassin
///
/// This file is the intellectual property of Novus Delta, LLC.. Usage of the
/// contents of this file is subject to the Destiny3D Member License which
/// can be found at http://www.destiny3d.com.  Any other usage is prohibited.
///
/// This file is distributed "AS IS" without warranty of any kind.  Novus
/// Delta, LLC. does not guarantee the fitness of the contents of this file
/// for any particular purpose.
///
/// Copyright (C) 2001-2003 Novus Delta, LLC. All Rights Reserved.
///
/// <hr>
///                                 Change History
/// <hr>
///
/// @date Jan 2002
/// @author Assassin
/// @remarks Creation
///
///////////////////////////////////////////////////////////////////////////////

#ifndef DEPORTAL_HPP
#define DEPORTAL_HPP

#include "deGlobalTypes.hpp"
#include "deWorld.hpp"
#include "deScene.hpp"

#define DEPORTAL_API DESCENE_API

class IdePortal;
class IdeSceneRoom;
class IdeVertexBuffer;
class IdeFileSystem;
class IdePlaneFrustum;
struct deTransformInfo;

// factory functions
/// Create an instance of IdePortal.
DEPORTAL_API IdePortal * IdePortal_CreatePortal();
/// Create an instance of IdePortal, given certain geometry.
DEPORTAL_API IdePortal * IdePortal_CreatePortalWithVerts(deVec3d Vertices[], int Num);

/// portals are used to connect IdeSceneRoom instances that would otherwise be unconnected.
/// Related functions: IdePortal_CreatePortal, IdePortal_CreatePortalWithVerts.
//class IdePortal
DE3D_INTERFACE_(IdePortal)
{
protected:
	~IdePortal() {}
public:
	/// deletes the object
	virtual int Release() = 0;

	/// Retrieve a pointer to the portal's vertex buffer
	virtual IdeVertexBuffer * GetVBuffer() = 0;
	/// Tell whether or not the portal is a T-portal (has normal and transformation)
	virtual deBoolean IsTPortal() const = 0;
	/// Disable any T-portal behavior this portal might have.
	virtual void SetTPortal(deBoolean TPortal) = 0;

	/// Clip the view frustum of a camera to the screen projection of the portal
//	virtual void ClipFrustum(deTransformInfo * CamPos, const deFrustum &in, deFrustum &out) = 0;
	virtual deBoolean ClipFrustum(const deTransformInfo & CamPos, const IdePlaneFrustum* in, IdePlaneFrustum* out) = 0;
	/// Test whether the input view frustum potentially contains any part of the portal
	virtual deBoolean IntersectsFrustum(const deTransformInfo & CamPos, const IdePlaneFrustum* f) const = 0;

	/// Set the vertices of the portal. For a T-portal, these vertices must be planar
	/// @param Vertices an array of vertices to set the internal vertices to
	/// @param Num the number of vertices in the array
	virtual void SetVertices(deVec3d Vertices[], long Num) = 0;
	/// Retrieve the internally held vertices
	/// @return pointer to the internal vertex array
	/// @param Num a reference to a long int to be filled with the number of vertices
	virtual deVec3d* GetVertices(long &Num) const = 0;
	
	/// Retrieve the world ID of the Scene Room on the "other side" of the portal
	virtual deWorldID	GetLinkWorldID() const = 0;
	/// Retrieve the object ID of the Scene Room on the "other side" of the portal
	virtual deObjectID	GetLinkObjectID() const = 0;
	/// Set the world ID of the Scene Room on the "other side" of the portal
	virtual void		SetLinkWorldID(deWorldID WorldID) = 0;
	/// Set the object ID of the Scene Room on the "other side" of the portal
	virtual void		SetLinkObjectID(deObjectID ObjectID) = 0;
	/// Feed in a Scene Room to have the world and object ID's matched up for you
	virtual deBoolean	LinkTo(IdeSceneRoom* SceneRoom) = 0;
	
	/// Set the "face" normal of the portal
	virtual void SetNormal(const deVec3d & v) = 0;
	/// Retrieve the "face" normal of the portal
	virtual void GetNormal(deVec3d & v) const = 0;

	virtual deBoolean IsPlanar() = 0;

	/// Set the world transformation of the portal's position
	virtual void SetPosition(const deTransformInfo & Matrix) = 0;
	/// Retrieve the world transformation of the portal's position
	virtual void GetPosition(deTransformInfo & Matrix) const = 0;
	/// Set the portal's transformation matrix. This matrix is used to get a concatenated
	/// world matrix for objects on the "other side" of the portal
	virtual void SetTransform(const deTransformInfo & Matrix) = 0;
	/// Retrieve the portal's transformation matrix.
	virtual void GetTransform(deTransformInfo & Matrix) const = 0;
	/// Concatenate the portal's world transformation with another transform
	/// @param Matrix a matrix containing a current world transform, to be concatenated with
	///               the portal's world transformation
	virtual void ConcatTransform(deTransformInfo & Matrix) = 0; // const
};

#endif
