//-
// ==========================================================================
// Copyright 2012 Autodesk, Inc. All rights reserved.
//
// Use of this software is subject to the terms of the Autodesk
// license agreement provided at the time of installation or download,
// or which otherwise accompanies this software in either electronic
// or hard copy form.
// ==========================================================================
//+

///////////////////////////////////////////////////////////////////////////////
//
// apiMeshSubSceneOverride.h
//
// Handles vertex data preparation for drawing the user defined shape in
// Viewport 2.0.
//
////////////////////////////////////////////////////////////////////////////////

#include <maya/MPxSubSceneOverride.h>
#include <map>

namespace MHWRender {
	class MVertexBuffer;
	class MIndexBuffer;
	class MShaderInstance;
}

class apiMesh;
class apiMeshGeom;

class apiMeshSubSceneOverride : public MHWRender::MPxSubSceneOverride
{
public:
	static MPxSubSceneOverride* Creator(const MObject& obj)
	{
		return new apiMeshSubSceneOverride(obj);
	}

	virtual ~apiMeshSubSceneOverride();

	virtual MHWRender::DrawAPI supportedDrawAPIs() const;

	virtual bool requiresUpdate(
		const MHWRender::MSubSceneContainer& container,
		const MHWRender::MFrameContext& frameContext) const;
	virtual void update(
		MHWRender::MSubSceneContainer& container,
		const MHWRender::MFrameContext& frameContext);
	virtual bool furtherUpdateRequired(
		const MHWRender::MFrameContext& frameContext);

private:
	apiMeshSubSceneOverride(const MObject& obj);

	void manageRenderItems(
		MHWRender::MSubSceneContainer& container,
		const MHWRender::MFrameContext& frameContext,
		bool updateGeometry);
	void rebuildGeometryBuffers();
	void deleteBuffers();

	MObject fObject;
	apiMesh* fMesh;

    struct InstanceInfo
    {
        MMatrix fTransform;
        bool fIsSelected;

        InstanceInfo() : fIsSelected(false) {}
        InstanceInfo(const MMatrix& matrix, bool selected) : fTransform(matrix), fIsSelected(selected) {}
    };
    typedef std::map<unsigned int, InstanceInfo> InstanceInfoMap;
	InstanceInfoMap fInstanceInfoCache;

	MHWRender::MShaderInstance* fWireShader;
	MHWRender::MShaderInstance* fThickWireShader;
	MHWRender::MShaderInstance* fSelectShader;
	MHWRender::MShaderInstance* fThickSelectShader;
	MHWRender::MShaderInstance* fShadedShader;
	MHWRender::MVertexBuffer* fPositionBuffer;
	MHWRender::MVertexBuffer* fNormalBuffer;
	MHWRender::MVertexBuffer* fBoxPositionBuffer;
	MHWRender::MIndexBuffer* fWireIndexBuffer;
	MHWRender::MIndexBuffer* fBoxIndexBuffer;
	MHWRender::MIndexBuffer* fShadedIndexBuffer;

    float fThickLineWidth;
    unsigned int fNumInstances;
    bool fIsInstanceMode;

	// Variables to control sample queue of updates to
	// allow for line width to increase incrementally without
	// user control.
	bool fUseQueuedLineUpdate;
	float fQueuedLineWidth;
	bool fQueueUpdate;
};

