/**
 @file Q3MapModel.cpp

 Dojo Game Engine

 Copyright 2005, Morgan McGuire
 All rights reserved.
 */
#include "dojo/Q3MapModel.h"
#include "dojo/World.h"

namespace dojo {

Q3MapModelRef Q3MapModel::create(const std::string& dir, const std::string& filename) {
    Q3MapModelRef m = new Q3MapModel();
    m->posedModel = new Q3MapPosedModel(dir, filename);
    return m;
}


void Q3MapModel::pose(Array<PosedModelRef>& posedModels, const CoordinateFrame& cframe) {
    // TODO: factor cframe in?
    posedModels.append(posedModel);
}

//////////////////////////////////////////////////////////////////////

Q3MapModel::Q3MapPosedModel::Q3MapPosedModel(const std::string& dir, const std::string& filename) {
    map = new BSPMAP::Map();
    bool ret = map->load(dir, filename);
    debugAssert(ret);
    if (! ret) {
        delete map;
        map = NULL;
    }        
}


std::string Q3MapModel::Q3MapPosedModel::name() const {
    return "Q3 BSP Map";
}


bool Q3MapModel::Q3MapPosedModel::hasTransparency () const {
    // TODO: break map into many pieces, one with no transparency
    return false;
}


void Q3MapModel::Q3MapPosedModel::getCoordinateFrame(CoordinateFrame &c) const {
    debugAssert(false);
    // TODO
    static CoordinateFrame cf;
    c = cf;
}


CoordinateFrame Q3MapModel::Q3MapPosedModel::coordinateFrame() const {
    debugAssert(false);
    // TODO
    static CoordinateFrame cf;
    return cf;
}


const MeshAlg::Geometry& Q3MapModel::Q3MapPosedModel::objectSpaceGeometry() const {
    debugAssert(false);
    // TODO
    static MeshAlg::Geometry g;
    return g;
}


void Q3MapModel::Q3MapPosedModel::getWorldSpaceGeometry (MeshAlg::Geometry &geometry) {
    debugAssert(false);
    // TODO
    static MeshAlg::Geometry g;
    geometry = g;
}


void Q3MapModel::Q3MapPosedModel::getObjectSpaceFaceNormals(Array< Vector3 > &faceNormals, bool normalize) {
    debugAssert(false);
    // TODO
}


void Q3MapModel::Q3MapPosedModel::getWorldSpaceFaceNormals (Array< Vector3 > &faceNormals, bool normalize) const {
    debugAssert(false);
}


const Array< Vector3 > & 	Q3MapModel::Q3MapPosedModel::objectSpaceFaceNormals (bool normalize) const {
    static Array<Vector3> v;
    debugAssert(false);
    return v;
}

const Array< MeshAlg::Face > & 	Q3MapModel::Q3MapPosedModel::faces () const {
    debugAssert(false);
    static Array<MeshAlg::Face> v;
    return v;
}

const Array< MeshAlg::Edge > & 	Q3MapModel::Q3MapPosedModel::edges () const {
    debugAssert(false);
    static Array<MeshAlg::Edge> v;
    return v;
}

const Array< MeshAlg::Vertex > & 	Q3MapModel::Q3MapPosedModel::vertices () const {
    debugAssert(false);
    static Array<MeshAlg::Vertex> v;
    return v;
}


const Array< Vector2 > & 	Q3MapModel::Q3MapPosedModel::texCoords () const {
    debugAssert(false);
    static Array<Vector2> v;
    return v;
}


bool Q3MapModel::Q3MapPosedModel::hasTexCoords () const {
    debugAssert(false);
    return false;
}


const Array< MeshAlg::Face > & 	Q3MapModel::Q3MapPosedModel::weldedFaces () const {
    debugAssert(false);
    static Array<MeshAlg::Face> v;
    return v;
}


const Array< MeshAlg::Edge > & 	Q3MapModel::Q3MapPosedModel::weldedEdges () const {
    debugAssert(false);
    static Array<MeshAlg::Edge> v;
    return v;
}


const Array< MeshAlg::Vertex > & 	Q3MapModel::Q3MapPosedModel::weldedVertices () const {
    debugAssert(false);
    static Array<MeshAlg::Vertex> v;
    return v;
}


const Array< int > & 	Q3MapModel::Q3MapPosedModel::triangleIndices () const {
    debugAssert(false);
    static Array<int> i;
    return i;
}


void Q3MapModel::Q3MapPosedModel::getObjectSpaceBoundingSphere (Sphere &) const {
    debugAssert(false);
}


Sphere Q3MapModel::Q3MapPosedModel::objectSpaceBoundingSphere () const {
    debugAssert(false);
    return Sphere();
}


void Q3MapModel::Q3MapPosedModel::getWorldSpaceBoundingSphere(Sphere& s) const {
    s = Sphere(Vector3::zero(), inf());
}


Sphere Q3MapModel::Q3MapPosedModel::worldSpaceBoundingSphere() const {
    return Sphere(Vector3::zero(), inf());
}


void Q3MapModel::Q3MapPosedModel::getObjectSpaceBoundingBox(Box& b) const {
    debugAssert(false);
}


Box	Q3MapModel::Q3MapPosedModel::objectSpaceBoundingBox () const {
    debugAssert(false);
    return Box();
}


void Q3MapModel::Q3MapPosedModel::getWorldSpaceBoundingBox (Box &box) const {
    debugAssert(false);
}


Box Q3MapModel::Q3MapPosedModel::worldSpaceBoundingBox () const {
    debugAssert(false);
    return Box();
}


void Q3MapModel::Q3MapPosedModel::render(class RenderDevice* renderDevice) const {
    if (map != 0) {
        const GCamera* camera = World::world()->activeCamera;
        map->render(renderDevice, *camera);
    }
}


int Q3MapModel::Q3MapPosedModel::numBoundaryEdges () const {
    debugAssert(false);
    return 0;
}


int Q3MapModel::Q3MapPosedModel::numWeldedBoundaryEdges () const {
    debugAssert(false);
    return 0;
}


int Q3MapModel::Q3MapPosedModel::numBrokenEdges () const {
    debugAssert(false);
    return 0;
}


void Q3MapModel::Q3MapPosedModel::renderNonShadowed(RenderDevice *rd, const LightingRef &lighting) const {
    if (map != NULL) {
        const GCamera* camera = World::world()->activeCamera;
        map->render(rd, *camera);
    }
}


void Q3MapModel::Q3MapPosedModel::renderShadowedLightPass (RenderDevice *rd, const GLight &light) const {
    // Do nothing; we don't receive lights
    return;
}


void Q3MapModel::Q3MapPosedModel::renderShadowMappedLightPass (RenderDevice *rd, const GLight &light, const Matrix4 &lightMVP, const TextureRef &shadowMap) const {
    // Do nothing; we don't receive lights
    return;
}

} // dojo

