/* 
   Copyright (c) 2002 Malte Starostik <malte@kde.org>

   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 2 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; see the file COPYING.  If not, write to
   the Free Software Foundation, Inc., 51 Franklin Steet, Fifth Floor,
   Boston, MA 02110-1301, USA.
*/

#ifndef KDETV_TELEX_PLUGIN_H
#define KDETV_TELEX_PLUGIN_H

#include <qguardedptr.h>
#include <qvaluevector.h>

#include <kurl.h>
#include <kxmlguiclient.h>

#include <kdetvmiscplugin.h>
#include "telexiface.h"

class VbiManager;

struct vbi_page;

namespace Telex
{
    class Display;
    class Page
    {
    public:
        Page( int number = 0, int sub = -1, int pno = -1 )
            : m_number( number ), m_sub( sub ), m_pno( pno ) {}

        int number() const { return m_number; }
        bool hasSub() const { return m_sub != -1; }
        int sub() const { return m_sub; }
        int pno() const { return m_pno; }

        bool operator ==( const Page& ) const;
        bool operator !=( const Page& rhs ) const
            { return !( *this == rhs ); }

    private:
        int m_number;
        int m_sub;
        int m_pno;
    };

    class Link
    {
    public:
        Link() : m_type( Null ) {}
        Link( const Page& page )
            : m_type( TTX ), m_page( page ) {}
        Link( const KURL& url )
            : m_type( URL ), m_url( url ) {}

        operator const void* () const
            { return m_type > Null ? this : 0; }
        bool operator ==( const Link& ) const;
        bool operator !=( const Link& rhs ) const
            { return !( *this == rhs ); }

        enum Type { Null, TTX, URL };
        Type type() const { return m_type; }
        const Page& page() const { return m_page; }
        const KURL& url() const { return m_url; }

    private:
        Type m_type;
        Page m_page;
        KURL m_url;
    };

    class Plugin : public KdetvMiscPlugin, virtual public KXMLGUIClient, virtual public TelexIface
    {
        Q_OBJECT
    public:
        Plugin( Kdetv *ktv, QWidget* parent );
        virtual ~Plugin();

        virtual bool filterNumberKey( int );

        /** Install toolbar button to (un)hide teletext */
        virtual void installGUIElements(KXMLGUIFactory * guiFactory,
                KActionCollection *actionCollection);

        virtual void removeGUIElements(KXMLGUIFactory * guiFactory,
                KActionCollection *actionCollection);

	VbiManager* vbiManager() const { return m_vbimgr; }
        const Page& page() const { return m_page; }

    public slots:
        void showDisplay(bool);
        void toggleShow();
        void toggleTransparent();
        void toggleReveal();

        // navigate through the pages
        void navigate(int page);
        void nextPage();
        void previousPage();

    private slots:
        void channelChanged();
        void navigate( const Link& );
        void ttxPageEvent(int, int, int, bool, bool, bool);
        void vbiDecoderRunning(bool running);

    private:
	VbiManager* m_vbimgr;
        QGuardedPtr< Display > m_display;
        KToggleAction* m_showAction;
        KToggleAction* m_transparentAction;
        KToggleAction* m_revealAction;

        Page m_page;
        int m_pageInput;
    };

    class Display : public QWidget
    {
        Q_OBJECT
    public:
        Display( QWidget*, Plugin* );
        virtual ~Display();

        virtual bool eventFilter( QObject*, QEvent* );

        bool isTransparent() const { return m_transparent; }
        bool isRevealed() const { return m_reveal; }

    public slots:
        void setTransparent( bool );
        void setReveal( bool );
        void setHeader( const Page& );
        void setPage( const Page& );

    protected:
        virtual void updateMask();
        virtual bool event( QEvent* e );
        virtual void resizeEvent( QResizeEvent* );
        virtual void paintEvent( QPaintEvent* );
        virtual void mouseMoveEvent( QMouseEvent* );
        virtual void mousePressEvent( QMouseEvent* );

    signals:
        void navigate( const Link& );

    private:
        bool fetch( const Page&, bool );
        void updateScale();

        Plugin* m_plugin;
        bool m_transparent;
        bool m_reveal;
        Page m_page;
        int m_columns;
        int m_rows;
        QValueVector< Link > m_links;
        QPixmap m_pixmap;
        QPixmap m_scaled;
    };
}

#endif

// vim: ts=4 sw=4 et
