/**
 @file Q3MapModel.h

 Dojo Game Engine

 Copyright 2005, Morgan McGuire
 All rights reserved.
 */
#ifndef DOJO_Q3MAPMODEL_H
#define DOJO_Q3MAPMODEL_H

#include "g3dhelper.h"
#include "dojo/Q3Map/BSPMap.h"

namespace dojo {

typedef ReferenceCountedPointer<class Q3MapModel> Q3MapModelRef;

class Q3MapModel : public ReferenceCountedObject {
private:
    friend class Q3Map;

    class Q3MapPosedModel : public PosedModel {
    private:
        friend class Q3MapModel;
        friend class Q3Map;

        BSPMAP::Map*            map;

    public:

        Q3MapPosedModel(const std::string& dir, const std::string& filename);
        virtual std::string name() const;
        virtual bool 	hasTransparency () const;
        virtual void 	getCoordinateFrame (CoordinateFrame &c) const;
        virtual CoordinateFrame 	coordinateFrame () const;
        virtual const MeshAlg::Geometry & 	objectSpaceGeometry () const;
        virtual void 	getWorldSpaceGeometry (MeshAlg::Geometry &geometry);
        virtual void 	getObjectSpaceFaceNormals (Array< Vector3 > &faceNormals, bool normalize=true);
        virtual void 	getWorldSpaceFaceNormals (Array< Vector3 > &faceNormals, bool normalize=true) const;
        virtual const Array< Vector3 > & 	objectSpaceFaceNormals (bool normalize=true) const;
        virtual const Array< MeshAlg::Face > & 	faces () const;
        virtual const Array< MeshAlg::Edge > & 	edges () const;
        virtual const Array< MeshAlg::Vertex > & 	vertices () const;
        virtual const Array< Vector2 > & 	texCoords () const;
        virtual bool 	hasTexCoords () const;
        virtual const Array< MeshAlg::Face > & 	weldedFaces () const;
        virtual const Array< MeshAlg::Edge > & 	weldedEdges () const;
        virtual const Array< MeshAlg::Vertex > & 	weldedVertices () const;
        virtual const Array< int > & 	triangleIndices () const;
        virtual void 	getObjectSpaceBoundingSphere (Sphere &) const;
        virtual Sphere 	objectSpaceBoundingSphere () const;
        virtual void 	getWorldSpaceBoundingSphere (Sphere &s) const;
        virtual Sphere 	worldSpaceBoundingSphere () const;
        virtual void 	getObjectSpaceBoundingBox (Box &) const;
        virtual Box 	objectSpaceBoundingBox () const;
        virtual void 	getWorldSpaceBoundingBox (Box &box) const;
        virtual Box 	worldSpaceBoundingBox () const;
        virtual void 	render (class RenderDevice *renderDevice) const;
        virtual int 	numBoundaryEdges () const;
        virtual int 	numWeldedBoundaryEdges () const;
        int 	numBrokenEdges () const;
        virtual void 	renderNonShadowed (RenderDevice *rd, const LightingRef &lighting) const;
        virtual void 	renderShadowedLightPass (RenderDevice *rd, const GLight &light) const;
        virtual void 	renderShadowMappedLightPass (RenderDevice *rd, const GLight &light, const Matrix4 &lightMVP, const TextureRef &shadowMap) const;
    };

    typedef ReferenceCountedPointer<class Q3MapPosedModel> Q3MapPosedModelRef;

    Q3MapPosedModelRef          posedModel;

public:

    /** Filename must be a .bsp file */
    static Q3MapModelRef create(const std::string& dir, const std::string& filename);

    void pose(Array<PosedModelRef>& posedModels, const CoordinateFrame& cframe);

    /** Initial dynamic models in the map (this is a Quake thing). */
    const Array<BSPMAP::BSPModel>& dynamicModels() const {
        return posedModel->map->dynamicModels;
    }
};

}

#endif
