/*==LICENSE==*

CyanWorlds.com Engine - MMOG client, server and tools
Copyright (C) 2011  Cyan Worlds, Inc.

This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program.  If not, see <http://www.gnu.org/licenses/>.

You can contact Cyan Worlds, Inc. by email legal@cyan.com
 or by snail mail at:
      Cyan Worlds, Inc.
      14617 N Newport Hwy
      Mead, WA   99021

*==LICENSE==*/
//////////////////////////////////////////////////////////////////////////////
//                                                                          //
//  plDrawableGenerator Header                                              //
//                                                                          //
//  Static helper class for creating various kind of drawable primitives.   //
//  Can be very useful for visualization stuff ;)                           //
//                                                                          //
//// Version History /////////////////////////////////////////////////////////
//                                                                          //
//  5.15.2001 mcn - Created.                                                //
//                                                                          //
//////////////////////////////////////////////////////////////////////////////

#ifndef _plDrawableGenerator_h
#define _plDrawableGenerator_h

#include "hsTemplates.h"
#include "hsBounds.h"
#include "hsMatrix44.h"

class hsGMaterial;
class plDrawableSpans;
class plGeometrySpan;
struct hsColorRGBA;


//// Class Definition ////////////////////////////////////////////////////////

class plDrawableGenerator
{
    public:

        // Set the colors for the faux lighting on generated drawables
        static void                 SetFauxLightColors( hsColorRGBA &lite, hsColorRGBA &dark );

        // Refills a drawable previously created with GenerateDrawable with the new data. New data
        // must match previous data in counts.
        hsBool                      RegenerateDrawable( UInt32 vertCount, hsPoint3 *positions, hsVector3 *normals, 
                                                            hsPoint3 *uvws, UInt32 uvwsPerVtx, 
                                                            hsColorRGBA *origColors, hsBool fauxShade, const hsColorRGBA* multColor,
                                                            UInt32 numIndices, UInt16 *indices, 
                                                            hsGMaterial *material, const hsMatrix44 &localToWorld, hsBool blended,
                                                            UInt32 diIndex, plDrawableSpans *destDraw );

        // Generates a drawable based on the vertex/index data given
        // uvws is an array vertCount*uvwsPerVtx long in order [uvw(s) for vtx0, uvw(s) for vtx1, ...], or is nil
        static plDrawableSpans      *GenerateDrawable( UInt32 vertCount, hsPoint3 *positions, hsVector3 *normals, 
                                                        hsPoint3 *uvws, UInt32 uvwsPerVtx, 
                                                        hsColorRGBA *origColors, hsBool fauxShade, const hsColorRGBA* multColor,
                                                        UInt32 numIndices, UInt16 *indices, 
                                                        hsGMaterial *material, const hsMatrix44 &localToWorld, hsBool blended = false,
                                                        hsTArray<UInt32> *retIndex = nil, plDrawableSpans *toAddTo = nil );

        // Generates a spherical drawable
        static plDrawableSpans      *GenerateSphericalDrawable( const hsPoint3& localPos, hsScalar radius, hsGMaterial *material, 
                                                                const hsMatrix44 &localToWorld, hsBool blended = false,
                                                                const hsColorRGBA* multColor = nil,
                                                                hsTArray<UInt32> *retIndex = nil, plDrawableSpans *toAddTo = nil,
                                                                hsScalar qualityScalar = 1.f );

        // Generates a rectangular drawable
        static plDrawableSpans      *GenerateBoxDrawable( hsScalar width, hsScalar height, hsScalar depth, 
                                                            hsGMaterial *material, const hsMatrix44 &localToWorld, hsBool blended = false,
                                                            const hsColorRGBA* multColor = nil,
                                                            hsTArray<UInt32> *retIndex = nil, plDrawableSpans *toAddTo = nil );

        // Generate a rectangular drawable based on a corner and three vectors
        static plDrawableSpans      *GenerateBoxDrawable( const hsPoint3 &corner, const hsVector3 &xVec, const hsVector3 &yVec, const hsVector3 &zVec, 
                                                            hsGMaterial *material, const hsMatrix44 &localToWorld, hsBool blended = false,
                                                            const hsColorRGBA* multColor = nil,
                                                            hsTArray<UInt32> *retIndex = nil, plDrawableSpans *toAddTo = nil );
        // Generates a bounds-based drawable
        static plDrawableSpans      *GenerateBoundsDrawable( hsBounds3Ext *bounds,
                                                            hsGMaterial *material, const hsMatrix44 &localToWorld, hsBool blended = false,
                                                            const hsColorRGBA* multColor = nil,
                                                            hsTArray<UInt32> *retIndex = nil, plDrawableSpans *toAddTo = nil );

        // Generates a conical drawable
        static plDrawableSpans      *GenerateConicalDrawable( hsScalar radius, hsScalar height, hsGMaterial *material, 
                                                            const hsMatrix44 &localToWorld, hsBool blended = false,
                                                            const hsColorRGBA* multColor = nil,
                                                            hsTArray<UInt32> *retIndex = nil, plDrawableSpans *toAddTo = nil );

        // Generates a general conical drawable based on a center and direction
        static plDrawableSpans      *GenerateConicalDrawable( hsPoint3 &apex, hsVector3 &direction, hsScalar radius, hsGMaterial *material, 
                                                            const hsMatrix44 &localToWorld, hsBool blended = false,
                                                            const hsColorRGBA* multColor = nil,
                                                            hsTArray<UInt32> *retIndex = nil, plDrawableSpans *toAddTo = nil );

        // Generates a drawable representing 3 axes
        static plDrawableSpans      *GenerateAxesDrawable( hsGMaterial *material, 
                                                            const hsMatrix44 &localToWorld, hsBool blended = false,
                                                            const hsColorRGBA* multColor = nil,
                                                            hsTArray<UInt32> *retIndex = nil, plDrawableSpans *toAddTo = nil );

        // Generate a planar drawable based on a corner and two vectors
        static plDrawableSpans      *GeneratePlanarDrawable( const hsPoint3 &corner, const hsVector3 &xVec, const hsVector3 &yVec, 
                                                            hsGMaterial *material, const hsMatrix44 &localToWorld, hsBool blended = false,
                                                            const hsColorRGBA* multColor = nil,
                                                            hsTArray<UInt32> *retIndex = nil, plDrawableSpans *toAddTo = nil );

    protected:
        
        // Shade the vertices given based on a quick fake directional light.
        // If origColors is non-nil, it must be an array of length count. Each outColor[i] *= origColor[i].
        // If multColor is non-nil, modulate the output by multColor.
        static void                 IQuickShadeVerts( UInt32 count, hsVector3 *normals, 
                                            hsColorRGBA *colors, 
                                            hsColorRGBA* origColors = nil, 
                                            const hsColorRGBA* multColor = nil );

        // Take the vertex and connectivity info supplied and fill out a geometry span with it.
        // Output span is ready to be added to a Drawable, or refreshed in a Drawable if it's
        // already in the SourceSpans.
        static void                 IFillSpan( UInt32 vertCount, hsPoint3 *positions, hsVector3 *normals, 
                                                                    hsPoint3 *uvws, UInt32 uvwsPerVtx, 
                                                                    hsColorRGBA *origColors, hsBool fauxShade, const hsColorRGBA* multColor,
                                                                    UInt32 numIndices, UInt16 *indices, 
                                                                    hsGMaterial *material, const hsMatrix44 &localToWorld, hsBool blended,
                                                                    plGeometrySpan* span );

        static hsColorRGBA          fLiteColor;
        static hsColorRGBA          fDarkColor;

};

#endif // _plDrawableGenerator_h