// Maintainer: Max Howell <max.howell@methylblue.com>, (C) 2004
// Copyright:  See COPYING file that comes with this distribution

#ifndef ANALYZERBASE_H
#define ANALYZERBASE_H


#include <config.h>  //HAVE_TQGLWIDGET

#ifdef __FreeBSD__
#include <sys/types.h>
#endif

#include "fht.h"     //stack allocated and convenience
#include <tqpixmap.h> //stack allocated and convenience
#include <tqtimer.h>  //stack allocated
#include <tqwidget.h> //baseclass
#include <vector>    //included for convenience

//#ifdef HAVE_TQGLWIDGET
#include <tqgl.h>     //baseclass
#ifdef TQ_WS_MACX
#include <OpenGL/gl.h>   //included for convenience
#include <OpenGL/glu.h>  //included for convenience
#else
#include <GL/gl.h>   //included for convenience
#include <GL/glu.h>  //included for convenience
#endif
//#else
////this is a workaround for compile problems due to moc
//#define TQGLWidget TQWidget
//#endif

class TQEvent;
class TQPaintEvent;
class TQResizeEvent;


namespace Analyzer {

typedef std::vector<float> Scope;

template<class W> class Base : public W
{
public:
    uint timeout() const { return m_timeout; }

protected:
    Base( TQWidget*, uint, uint = 7 );
    ~Base() { delete m_fht; }

    void drawFrame();
    int  resizeExponent( int );
    int  resizeForBands( int );
    virtual void transform( Scope& );
    virtual void analyze( const Scope& ) = 0;
    virtual void paused();
    virtual void demo();

    void changeTimeout( uint newTimeout )
    {
        m_timer.changeInterval( newTimeout );
        m_timeout = newTimeout;
    }

private:
    bool event( TQEvent* );

protected:
    TQTimer m_timer;
    uint   m_timeout;
    FHT    *m_fht;
};


class Base2D : public Base<TQWidget>
{
TQ_OBJECT
  
public:
    const TQPixmap *background() const { return &m_background; }
    const TQPixmap *canvas()     const { return &m_canvas; }

private slots:
    void draw() { drawFrame(); bitBlt( this, 0, 0, canvas() ); }

protected:
    Base2D( TQWidget*, uint timeout, uint scopeSize = 7 );

    virtual void init() {}

    TQPixmap *background() { return &m_background; }
    TQPixmap     *canvas() { return &m_canvas; }
    void    eraseCanvas() { bitBlt( canvas(), 0, 0, background() ); }

    void paintEvent( TQPaintEvent* ) { if( !m_canvas.isNull() ) bitBlt( this, 0, 0, canvas() ); }
    void resizeEvent( TQResizeEvent* );
    void paletteChange( const class TQPalette& );

    void polish();

private:
    TQPixmap m_background;
    TQPixmap m_canvas;
};



//This mess is because moc generates an entry for this class despite the #if block
//1. the TQ_OBJECT macro must be exposed
//2. we have to define the class
//3. we have to declare a ctor (to satisfy the inheritance)
//4. the slot must also by visible (!)
//TODO find out how to stop moc generating a metaobject for this class
class Base3D : public Base<TQGLWidget>
{
  TQ_OBJECT
  
#ifdef HAVE_TQGLWIDGET
protected:
    Base3D( TQWidget*, uint, uint = 7 );
private slots:
    void draw() { drawFrame(); }
#else
protected:
    Base3D( TQWidget *w, uint i1, uint i2 ) : Base<TQGLWidget>( w, i1, i2 ) {}
private slots:
    void draw() {}
#endif
};


class Factory
{
    //Currently this is a rather small class, its only purpose
    //to ensure that making changes to analyzers will not require
    //rebuilding the world!

    //eventually it would be better to make analyzers pluggable
    //but I can't be arsed, nor can I see much reason to do so
    //yet!
public:
    static TQWidget* createAnalyzer( TQWidget* );
    static TQWidget* createPlaylistAnalyzer( TQWidget *);
};


void interpolate( const Scope&, Scope& );
void initSin( Scope&, const uint = 6000 );

} //END namespace Analyzer

using Analyzer::Scope;

#endif
