/**
 * Copyright (C) 2002-2003 by Koos Vriezen <koos.vriezen@gmail.com>
 *
 *  This library is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU Library General Public
 *  License version 2 as published by the Free Software Foundation.
 *
 *  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 GNU
 *  Library General Public License for more details.
 *
 *  You should have received a copy of the GNU Library General Public License
 *  along with this library; see the file COPYING.LIB.  If not, write to
 *  the Free Software Foundation, Inc., 51 Franklin Steet, Fifth Floor,
 *  Boston, MA 02110-1301, USA.
 **/

#ifndef KMPLAYERPARTBASE_H
#define KMPLAYERPARTBASE_H

#include <config.h>

#include "kmplayer_def.h"

#include <tqobject.h>
#include <tqguardedptr.h>
#include <tqstringlist.h>
#include <tqmap.h>

#include <dcopobject.h>
#include <tdemediaplayer/player.h>
#include <kurl.h>

#include "kmplayerview.h"
#include "kmplayersource.h"


class TDEAboutData;
class TDEInstance;
class TDEActionCollection;
class KBookmarkMenu;
class TDEConfig;
class TQIODevice;
class TQTextStream;
class TQListViewItem;

namespace TDEIO {
    class Job;
}

namespace KMPlayer {

class PartBase;
class Process;
class MPlayer;
class BookmarkOwner;
class BookmarkManager;
class MEncoder;
class MPlayerDumpstream;
class FFMpeg;
class Xine;
class Settings;

/*
 * Source from URLs
 */
class KMPLAYER_EXPORT URLSource : public Source {
    TQ_OBJECT
//     
public:
    URLSource (PartBase * player, const KURL & url = KURL ());
    virtual ~URLSource ();

    virtual void dimensions (int & w, int & h);
    virtual bool hasLength ();
    virtual TQString prettyName ();
    virtual void reset ();
    virtual void setURL (const KURL & url);
public slots:
    virtual void init ();
    virtual void activate ();
    virtual void deactivate ();
    virtual void playCurrent ();
    virtual void forward ();
    virtual void backward ();
    virtual void jump (NodePtr e);
    void play ();
private slots:
    void kioData (TDEIO::Job *, const TQByteArray &);
    void kioMimetype (TDEIO::Job *, const TQString &);
    void kioResult (TDEIO::Job *);
protected:
    virtual bool requestPlayURL (NodePtr mrl);
    virtual bool resolveURL (NodePtr mrl);
private:
    void read (NodePtr mrl, TQTextStream &);
    void stopResolving ();
    struct ResolveInfo {
        ResolveInfo (NodePtr mrl, TDEIO::Job * j, SharedPtr <ResolveInfo> & n)
            : resolving_mrl (mrl), job (j), progress (0), next (n) {}
        NodePtrW resolving_mrl;
        TDEIO::Job * job;
        TQByteArray data;
        int progress;
        SharedPtr <ResolveInfo> next;
    };
    SharedPtr <ResolveInfo> m_resolve_info;
    bool activated; // 'solve' an singleShot race w/ cmdline url's
};

/*
 * KDE's KMediaPlayer::Player implementation and base for KMPlayerPart
 */
class KMPLAYER_EXPORT PartBase : public KMediaPlayer::Player {
    TQ_OBJECT
//     
    K_DCOP
public:
    typedef TQMap <TQString, Process *> ProcessMap;
    PartBase (TQWidget * parent,  const char * wname,TQObject * objectParent, const char * name, TDEConfig *);
    ~PartBase ();
    void init (TDEActionCollection * = 0L);
    virtual KMediaPlayer::View* view ();
    static TDEAboutData* createAboutData ();

    Settings * settings () const { return m_settings; }
    void keepMovieAspect (bool);
    KURL url () const { return m_sources ["urlsource"]->url (); }
    void setURL (const KURL & url) { m_sources ["urlsource"]->setURL (url); }

    /* Changes the backend process */
    void setProcess (const char *);
    bool setProcess (Mrl *mrl);
    void setRecorder (const char *);

    /* Changes the source,
     * calls init() and reschedules an activate() on the source
     * */
    void setSource (Source * source);
    void connectPanel (ControlPanel * panel);
    void connectPlaylist (PlayListView * playlist);
    void connectInfoPanel (InfoWindow * infopanel);
    void connectSource (Source * old_source, Source * source);
    Process * process () const { return m_process; }
    Process * recorder () const { return m_recorder; }
    Source * source () const { return m_source; }
    TQMap <TQString, Process *> & players () { return m_players; }
    TQMap <TQString, Process *> & recorders () { return m_recorders; }
    TQMap <TQString, Source *> & sources () { return m_sources; }
    TDEConfig * config () const { return m_config; }
    bool mayResize () const { return !m_noresize; }
    void updatePlayerMenu (ControlPanel *);
    void updateInfo (const TQString & msg);
    void updateStatus (const TQString & msg);
#ifdef HAVE_DBUS
    void setServiceName (const TQString & srv) { m_service = srv; }
    TQString serviceName () const { return m_service; }
#endif

    // these are called from Process
    void changeURL (const TQString & url);
    void updateTree (bool full=true, bool force=false);
    void setLanguages (const TQStringList & alang, const TQStringList & slang);
public slots:
    virtual bool openURL (const KURL & url);
    virtual bool openURL (const KURL::List & urls);
    virtual bool closeURL ();
    virtual void pause (void);
    virtual void play (void);
    virtual void stop (void);
    void record ();
    virtual void seek (unsigned long msec);
    void adjustVolume (int incdec);
    bool playing () const;
    void showConfigDialog ();
    void showPlayListWindow ();
    void slotPlayerMenu (int);
    void back ();
    void forward ();
    void addBookMark (const TQString & title, const TQString & url);
    void volumeChanged (int);
    void increaseVolume ();
    void decreaseVolume ();
    void setPosition (int position, int length);
    virtual void setLoaded (int percentage);
public:
    virtual bool isSeekable (void) const;
    virtual unsigned long position (void) const;
    virtual bool hasLength (void) const;
    virtual unsigned long length (void) const;
k_dcop:
    void toggleFullScreen ();
    bool isPlaying ();
    bool isPaused ();
signals:
    void sourceChanged (KMPlayer::Source * old, KMPlayer::Source * nw);
    void sourceDimensionChanged ();
    void loading (int percentage);
    void urlAdded (const TQString & url);
    void urlChanged (const TQString & url);
    void processChanged (const char *);
    void treeChanged (int id, NodePtr root, NodePtr, bool select, bool open);
    void treeUpdated ();
    void infoUpdated (const TQString & msg);
    void statusUpdated (const TQString & msg);
    void languagesUpdated(const TQStringList & alang, const TQStringList & slang);
    void audioIsSelected (int id);
    void subtitleIsSelected (int id);
    void positioned (int pos, int length);
    void toggleMinimalMode ();
protected:
    bool openFile();
    virtual void timerEvent (TQTimerEvent *);
protected slots:
    void posSliderPressed ();
    void posSliderReleased ();
    void positionValueChanged (int val);
    void contrastValueChanged (int val);
    void brightnessValueChanged (int val);
    void hueValueChanged (int val);
    void saturationValueChanged (int val);
    void sourceHasChangedAspects ();
    void fullScreen ();
    void minimalMode ();
    void playListItemClicked (TQListViewItem *);
    void playListItemExecuted (TQListViewItem *);
    virtual void playingStarted ();
    virtual void playingStopped ();
    void recordingStarted ();
    void recordingStopped ();
    void settingsChanged ();
    void audioSelected (int);
    void subtitleSelected (int);
protected:
    TDEConfig * m_config;
    TQGuardedPtr <View> m_view;
    TQMap <TQString, TQString> temp_backends;
    Settings * m_settings;
    Process * m_process;
    Process * m_recorder;
    Source * m_source;
    ProcessMap m_players;
    ProcessMap m_recorders;
    TQMap <TQString, Source *> m_sources;
    BookmarkManager * m_bookmark_manager;
    BookmarkOwner * m_bookmark_owner;
    KBookmarkMenu * m_bookmark_menu;
#ifdef HAVE_DBUS
    TQString m_service;
#endif
    int m_record_timer;
    int m_update_tree_timer;
    bool m_noresize : 1;
    bool m_auto_controls : 1;
    bool m_use_slave : 1;
    bool m_bPosSliderPressed : 1;
    bool m_in_update_tree : 1;
    bool m_update_tree_full : 1;
};

class KMPLAYER_NO_EXPORT DataCache : public TQObject {
    TQ_OBJECT
//     
    typedef TQMap <TQString, TQByteArray> DataMap;
    typedef TQMap <TQString, bool> PreserveMap;
    DataMap cache_map;
    PreserveMap preserve_map;
public:
    DataCache () {}
    ~DataCache () {}
    void add (const TQString &, const TQByteArray &);
    bool get (const TQString &, TQByteArray &);
    bool preserve (const TQString &);
    bool unpreserve (const TQString &);
    bool isPreserved (const TQString &);
signals:
    void preserveRemoved (const TQString &); // ready or canceled
};

class KMPLAYER_NO_EXPORT RemoteObjectPrivate : public TQObject {
    TQ_OBJECT
//     
public:
    RemoteObjectPrivate (RemoteObject * r);
    ~RemoteObjectPrivate ();
    bool download (const TQString &);
    void clear ();
    TDEIO::Job * job;
    TQString url;
    TQByteArray data;
    TQString mime;
private slots:
    void slotResult (TDEIO::Job*);
    void slotData (TDEIO::Job*, const TQByteArray& qb);
    void slotMimetype (TDEIO::Job * job, const TQString & mimestr);
    void cachePreserveRemoved (const TQString &);
private:
    RemoteObject * remote_object;
    bool preserve_wait;
};

} // namespace

#endif
