/**
 @file GraphicsData.h

 Dojo Game Engine

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

#include "g3dhelper.h"
#include "dojo/ASFModel.h"
#include "dojo/SimpleModel.h"
#include "dojo/Q3MapModel.h"

namespace dojo {

class Entity;
class PhysicsData;

/**
 A wrapper that pairs various model classes and their pose information.
 1:1 relationship with Entity.  
 */
// Implementation could use inheritance, but then we'd just have to add down-casts
// everywhere in the code that uses it.
class GraphicsData {
private:

    friend Entity;

public:

    enum Type {ASF = 1, ARTICULATED, Q2CHARACTER, Q3MAP, SIMPLE};

    /** Indicates which of the ___model fields is in use. */
    Type                        type;

    ArticulatedModelRef         artmodel;
    ArticulatedModel::Pose      artpose;

    ASFModelRef                 asfmodel;

    SimpleModelRef              simpleModel;

    Q3MapModelRef               q3MapModel;

    // Quake 2 characters have two models; one is the character
    // proper and the other is the weapon.
    MD2ModelRef                 md2model[2];
    GMaterial                   md2material[2];
    MD2Model::Pose              md2pose;

    /** True if the cframe is the identity transformation. */
    bool                        cframeIsIdentity;

    /** Transformation of this object relative to the PhysicsData 
        world space frame.  Allows positioning models away from the 
        center of mass.*/
    CoordinateFrame             cframe;

    GraphicsData(const ArticulatedModelRef& model);

    GraphicsData(const ASFModelRef& model);

    GraphicsData(const MD2ModelRef& model0, const TextureRef& t0, const MD2ModelRef& model1, const TextureRef& t1);

    GraphicsData(const Q3MapModelRef& model);

    ~GraphicsData();

    void drawLabels(RenderDevice* rd, const CoordinateFrame& physicsFrame) const;

    /** Transform this into a posed model.  The local cframe will be applied before the one passed in. */
    virtual void pose(Array<PosedModelRef>& posedModels, const CoordinateFrame& physicsFrame);
};

} // namespace
 
#endif
