/* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2003 Robert Osfield 
 *
 * This library is open source and may be redistributed and/or modified under  
 * the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or 
 * (at your option) any later version.  The full license is in LICENSE file
 * included with this distribution, and on the openscenegraph.org website.
 * 
 * This library 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 
 * OpenSceneGraph Public License for more details.
*/
//C++ header - Open Scene Graph - Copyright (C) 1998-2002 Robert Osfield
//Distributed under the terms of the GNU Library General Public License (LGPL)
//as published by the Free Software Foundation.

/* --------------------------------------------------------------------------
 *
 *    openscenegraph textLib / FTGL wrapper (http://homepages.paradise.net.nz/henryj/code/)
 *
 * --------------------------------------------------------------------------
 *    
 *    prog:    max rheiner;mrn@paus.ch
 *    date:    4/25/2001    (m/d/y)
 *
 * --------------------------------------------------------------------------
 *
 * --------------------------------------------------------------------------
 */


#ifndef OSGTEXT_TEXT
#define OSGTEXT_TEXT 1 

#include <osg/Drawable>
#include <osg/GL>
#include <osg/Vec3>
#include <osg/Vec2>

#include <osgText/Font>
#include <osgText/EncodedText>

#include <string>

namespace osgText {

class OSGTEXT_EXPORT Text : public osg::Drawable
{
    public:

        enum AlignmentType
        {    // from left to right, top to bottom
            LEFT_TOP,
            LEFT_CENTER,
            LEFT_BOTTOM,

            CENTER_TOP,
            CENTER_CENTER,
            CENTER_BOTTOM,

            RIGHT_TOP,
            RIGHT_CENTER,
            RIGHT_BOTTOM,
        };

        enum BoundingBoxType
        {
            GEOMETRY,
            GLYPH,
        };

        enum DrawModeType
        {    // from left to right, top to bottom
            TEXT            =    1<<0,
            BOUNDINGBOX     =    1<<1,
            ALIGNMENT       =    1<<2,
            DEFAULT         =    TEXT,
        };
        
        enum AxisAlignment
        {
            XY_PLANE,
            XZ_PLANE,
            YZ_PLANE
        };

        Text();
        Text(const Text& text,const osg::CopyOp& copyop=osg::CopyOp::SHALLOW_COPY);
        Text(Font* font);

        virtual osg::Object* cloneType() const { return new Text(); }
        virtual osg::Object* clone(const osg::CopyOp& copyop) const { return new Text(*this,copyop); }
        virtual bool isSameKindAs(const osg::Object* obj) const { return dynamic_cast<const Text*>(obj)!=NULL; }
        virtual const char* className() const { return "Text"; }
        virtual const char* libraryName() const { return "osgText"; }        

        void setPosition(const osg::Vec2& pos);
        void setPosition(const osg::Vec3& pos);
        const osg::Vec3& getPosition() const { return _pos; }


        void setColor(const osg::Vec4& color) { _color = color; }
        osg::Vec4& getColor() { return _color; }
        const osg::Vec4& getColor() const { return _color; }


        void setDrawMode(int mode) { _drawMode=mode; }
        int getDrawMode() const { return _drawMode; }

        void setBoundingBox(int mode);
        int getBoundingBox() const { return _boundingBoxType; }

        void setAlignment(int alignment);
        int getAlignment() const { return _alignment; }
        
        void setAxisAlignment(AxisAlignment axis) { _axisAlignment = axis; dirtyDisplayList(); }
        AxisAlignment getAxisAlignment() const { return _axisAlignment; }

        void setFont(Font* font);
        Font* getFont() { return _font.get(); }
        const Font* getFont() const { return _font.get(); }

        void setText(const char* text);
        void setText(const std::string& text);
        const std::string& getText() const { return _text; }

        virtual bool supports(PrimitiveFunctor& pf) const;
        virtual void accept(PrimitiveFunctor& pf) const;

        virtual void drawImplementation(osg::State& state) const;
        virtual void drawBoundingBox(void) const;
        virtual void drawAlignment(void) const;

        const osg::Vec3& getAlignmentPos() const { return _alignmentPos; };

        void setEncodedText(EncodedText* encodedText) { _encodedText = encodedText; }
        const EncodedText* getEncodedText() const { return _encodedText.get(); }

        /// override the compile to set up the alignment etc.
        virtual void compile(osg::State& state) const;

    protected:

        enum FontType
        {
            UNDEF,
            BITMAP,
            PIXMAP,
            OUTLINE,
            POLYGON,
            TEXTURE,
        };

        virtual    ~Text();

        virtual void        setDefaults(void);
        virtual bool        computeBound(void) const;
        virtual void        calcBounds(osg::Vec3* min,osg::Vec3* max) const;
        void                initAlignment(osg::Vec3* min,osg::Vec3* max);
        bool                initAlignment(void);

        osg::ref_ptr<Font>  _font;

        bool                _init;
        bool                _initAlignment;
        std::string         _text;
        int                 _fontType;
        int                 _alignment;
        int                 _drawMode;
        int                 _boundingBoxType;
        AxisAlignment       _axisAlignment;

        osg::ref_ptr<EncodedText>    _encodedText;
        
        osg::Vec3           _pos;        
        osg::Vec3           _alignmentPos;
        osg::Vec4           _color;
};

}

#endif // OSGTEXT_TEXT
