/* -*-c++-*- header - Open Producer - Copyright (C) 2002 Don Burns
 * Distributed under the terms of the GNU LIBRARY GENERAL PUBLIC LICENSE (LGPL)
 * as published by the Free Software Foundation.
 */
#ifndef PRODUCER_VISUAL_CHOOSER
#define PRODUCER_VISUAL_CHOOSER 1

#include <vector>

#include <Producer/Export>
#include <Producer/Types>
#include <Producer/Referenced>


namespace Producer {

class PR_EXPORT VisualChooser : public Referenced 
{
    public :
        VisualChooser( void );

        enum AttributeName {
            UseGL,
            BufferSize,
            Level,
            RGBA, 
            DoubleBuffer, 
            Stereo, 
            AuxBuffers,
            RedSize,
            GreenSize,
            BlueSize,
            AlphaSize,
            DepthSize,
            StencilSize,
            AccumRedSize,
            AccumGreenSize,
            AccumBlueSize,
            AccumAlphaSize
        };

        //-------------------------------------------------------------------------
        // Explicitely set the visual info pointer.  This will override the use of
        // glXChooseVisual().  Useful for functions requiring a VisualChooser 
        // argument, but not a XVisualInfo.
        void setVisual( VisualInfo *vinfo );

        //-------------------------------------------------------------------------
        // Chooses a minimal set of parameters 
        void setSimpleConfiguration();

        //-------------------------------------------------------------------------
        // Clear the list of parameters
        void clear() ;

        //-------------------------------------------------------------------------
        // Generic method for adding an attribute without a parameter 
        // (e.g DoubleBuffer )
        void addAttribute( AttributeName attribute );

        //-------------------------------------------------------------------------
        // Generic method for adding an attribute with a parameter 
        // (e.g DepthSize, 1 )
        void addAttribute( AttributeName attribute, int parameter );

        //-------------------------------------------------------------------------
        // Generic method for adding an attribute without a parameter 
        // (e.g DoubleBuffer )
        void addExtendedAttribute( unsigned int attribute );

        //-------------------------------------------------------------------------
        // Generic method for adding an extended attribute with a parameter 
        // (e.g DepthSize, 1 )
        void addExtendedAttribute( unsigned int attribute, int parameter );


        //-------------------------------------------------------------------------
        // The following methods set attributes explicitely
        //
        void setBufferSize( unsigned int size );

        void setLevel( int level );
        
        void useRGBA();

        void useDoubleBuffer();

        void useStereo();

        void setAuxBuffers( unsigned int num );

        void setRedSize( unsigned int size );

        void setGreenSize( unsigned int size );

        void setBlueSize( unsigned int size );

        void setAlphaSize( unsigned int size );

        void setDepthSize( unsigned int size );

        void setStencilSize( unsigned int size );

        void setAccumRedSize( unsigned int size );

        void setAccumGreenSize( unsigned int size );

        void setAccumBlueSize( unsigned int size );

        void setAccumAlphaSize( unsigned int size );

        void setVisualID( unsigned int id ); 


        //-------------------------------------------------------------------------
        // Chooses visual based on previously selected attributes and parameters
        //     dpy              = Conection to Xserver as returned by XOpenDisplay()
        //     screen           = XServer screen (Could be DefaultScreen(dpy))
        //     strict_adherence = If true, return NULL visual info if the set of 
        //                        parameters is not matched verbatim.  If set to
        //                        false, choose() will attempt to find a visual that
        //                        matches as much of the attribute list as possible
        //
        //                        Important Note : An attribute is removed from the end
        //                        of the list before each retry, implying that the 
        //                        attribute list should be specified in priority order,
        //                        most important attriutes first.
        //                    

        VisualInfo *choose( Display *dpy, int screen, bool strict_adherence=false);

        unsigned int getVisualID(); 

    protected:
        ~VisualChooser(void);

    private :

        struct VisualAttribute 
        {
                unsigned int  _attribute;
                bool _has_parameter;
                int  _parameter;
                bool _is_extension;

                VisualAttribute( AttributeName attribute, int parameter ) :
                _attribute(attribute),
                _has_parameter(true),
                _parameter(parameter),
                _is_extension(false) {}

                VisualAttribute( AttributeName attribute ) :
                _attribute(attribute),
                _has_parameter(false),
                _parameter(0),
                _is_extension(false) {}

                VisualAttribute( unsigned int attribute, int parameter ) :
                _attribute(attribute),
                _has_parameter(true),
                _parameter(parameter),
                _is_extension(true) {}

                VisualAttribute( unsigned int attribute ) :
                _attribute(attribute),
                _has_parameter(false),
                _parameter(0),
                _is_extension(true) {}

                unsigned int attribute()    { return _attribute; }
                bool hasParameter() { return _has_parameter; }
                int  parameter()    { return _parameter; }
                bool isExtension()  { return _is_extension; }
          };

        int adaptAttribute( VisualAttribute &, VisualInfo *vinfo=NULL);
        std::vector <VisualAttribute> _visual_attributes;
        VisualInfo *_vinfo;
        unsigned int _visual_id;
};

}
#endif
