//
// C++ Interface: doctreeviewimpl
//
// Description: 
//
//
// Author: Robert Vogl <voglrobe@lapislazuli>, (C) 2004
//
// Copyright: See COPYING file that comes with this distribution
//
//
#ifndef DOCTREEVIEWIMPL_H
#define DOCTREEVIEWIMPL_H

// Qt includes
#include <qstring.h>
#include <qlistview.h>
#include <qdom.h>

// KDE includes
#include <kurl.h>
// #include <kpopupmenu.h>
 
// App specific includes
#include "DocTreeView.h"

// forward declarations
class ParaSaxParser;
// class ContextMenuHandler;

/**
This abstract class is the interface to access the items of the TreeView.
@author Robert Vogl
*/
class ListViewInterface : public QListViewItem
{
public:
    ListViewInterface(ListViewInterface *parent=0, QString label=QString::null);
    ListViewInterface(QListView *lv=0, QString label=QString::null);

    // ~ListViewItemInterface();
    
    /**
     * \returns The header of the item in RTF format. Supposed to be shown to
     * the user if KSayIt is not in edit mode.
     */
    virtual QString getRTFHeader() const = 0;

    /**
     * \returns The body text of the item in RTF format. Supposed to be shown to
     * the user if KSayIt is not in edit mode.
     */
    virtual QString getRTFData() const = 0;

    /**
     * \returns The header of the item that is deliverd to the TTS system.
     */
    virtual QString getHeader() const = 0;

    /**
     * \returns The body text of the item that is delivered to the TTS system.
     */
    virtual QString getData() const = 0;

    /**
     * \returns The raw data of the item including all DocBook tags. Supposed to
     * be shown to the user if KSayIt is in edit mode.
     */
    virtual QString getRawData() const = 0;

    /**
     * Stores the given string to the item and updates the corresponding DOM node.
     * \param data The new data stored to the DOM node. Unless otherwise noted
     * embedded XML tags are not allowed.
     */
    virtual void setData(const QString &data) = 0;
};


//
// Classes for Roberts elements
//
/**
 Represents the root item of the document, therefore it expects
 a \p QListView object as parent.\n
 Structural item only (no references to a DOM node).
 @author Robert Vogl
 */
class RobDocument : public ListViewInterface
{
public:
    /**
     * Constructor
     * \param lv The ListView parent.
     * \param label The label is shown in column 0 of the TreeView and is also
     * used as bookmark title.
     */
    RobDocument(QListView *lv=0, QString label=QString::null);
    ~RobDocument();

    QString getRTFHeader() const;
    QString getHeader() const;
    QString getRTFData() const;
    QString getData() const;
    QString getRawData() const;
    void setData(const QString &data);
};


//
// Classes for Docbook elements
//
/**
 Represents the DocBook \p Overview element of the document.\n
 Structural item only (no references to a DOM node).
 @author Robert Vogl
 */
class Overview : public ListViewInterface
{
public:
    Overview(ListViewInterface *parent=0, QString label=QString::null);
    ~Overview();

    QString getRTFHeader() const;
    QString getHeader() const;
    QString getRTFData() const;
    QString getData() const;
    QString getRawData() const;
    void setData(const QString &data);
};


/**
 Represents the DocBook \p Date element of the document.\n
 @author Robert Vogl
 */
class Date : public ListViewInterface
{
public:
    Date(ListViewInterface *parent=0, QString label=QString::null);
    ~Date();

    /**
     * References the given node to this TreeView item.
     * \param node A reference to the corresponding DOM node.
     */
    void setNode(QDomNode node);
    QString getRTFHeader() const;
    QString getHeader() const;
    QString getRTFData() const;
    QString getData() const;
    QString getRawData() const;
    void setData(const QString &data);

private:
    // Pointer to the associated Data
    QDomNode m_node;
};


/**
 Represents the DocBook \p ReleasInfo element of the document.\n
 @author Robert Vogl
 */
class ReleaseInfo : public ListViewInterface
{
public:
    ReleaseInfo(ListViewInterface *parent=0, QString label=QString::null);
    ~ReleaseInfo();

    /**
     * References the given node to this TreeView item.
     *  \param node A reference to the corresponding DOM node.
     */
    void setNode(QDomNode node);
    QString getRTFHeader() const;
    QString getHeader() const;
    QString getRTFData() const;
    QString getData() const;
    QString getRawData() const;
    void setData(const QString &data);

private:
    // Pointer to the associated Data
    QDomNode m_node;
};


/**
 Represents the DocBook \p AuthorGroup element of the document.\n
 Structural item only (no references to a DOM node).
 @author Robert Vogl
 */
class AuthorGroup : public ListViewInterface
{
public:
    AuthorGroup(ListViewInterface *parent=0, QString label=QString::null);
    ~AuthorGroup();
    
    QString getRTFHeader() const;     
    QString getHeader() const;    
    QString getRTFData() const;
    QString getData() const;
    QString getRawData() const;
    void setData(const QString &data);   
};


/**
 Represents the DocBook \p Author element and its Subelements
 \p Firstname and \p Surname of the document.\n
 @author Robert Vogl
 */
class Author : public ListViewInterface
{
public:
    Author(ListViewInterface *parent=0, QString label=QString::null);
    ~Author();

    /**
     * References the given nodes to this TreeView item.
     * \param node1 = Firstname
     * \param node2 = Surname
     */
    void setNode(QDomNode node1, QDomNode node2);
    QString getRTFHeader() const;
    QString getHeader() const;
    QString getRTFData() const;

    /**
     * \returns Firstname + Space + Surname
     */
    QString getRawData() const;

    /**
     * \returns Firstname + Space + Surname
     */
    QString getData() const;

    /**
     * Expects firstname and surname sperated by one or more space characters
     * and updates the corresponding DOM elements.
     * \param A string in the form Firstname + Space + Surname
     */
    void setData(const QString &data);

private:
    // Pointer to the associated Data
    QDomNode m_node1;
    QDomNode m_node2;
};


/**
 Represents the DocBook \p KeywordSet element of the document.\n
 Structural item only (no references to a DOM node).
 @author Robert Vogl
 */
class KeywordSet : public ListViewInterface
{
public:
    KeywordSet(ListViewInterface *parent=0, QString label=QString::null);
    ~KeywordSet();

    QString getRTFHeader() const;
    QString getHeader() const;
    QString getRTFData() const;
    QString getData() const;
    QString getRawData() const;
    void setData(const QString &data);
};


/**
 Represents the DocBook \p Keyword element of the document.\n
 @author Robert Vogl
 */
class Keyword : public ListViewInterface
{
public:
    Keyword(ListViewInterface *parent=0, QString label=QString::null);
    ~Keyword();

    /**
     * References the given node to this TreeView item.
     * \param node A reference to the corresponding DOM node.
     */
    void setNode(QDomNode node);
    QString getRTFHeader() const;
    QString getHeader() const;    
    QString getRTFData() const;
    QString getData() const;
    QString getRawData() const;
    void setData(const QString &data);   

private:    
    // Pointer to the associated Data
    QDomNode m_node;
};


/**
 Represents the DocBook \p Abstract element of the document.\n
 Structural item only (no references to a DOM node).
 @author Robert Vogl
 */
class Abstract : public ListViewInterface
{
public:
    Abstract(ListViewInterface *parent=0, QString label=QString::null);
    ~Abstract();
    
    QString getRTFHeader() const;     
    QString getHeader() const;    
    QString getRTFData() const;
    QString getData() const;
    QString getRawData() const;
    void setData(const QString &data);   
};


/**
 Represents a DocBook Paragraph item of the document.\n
 @author Robert Vogl
 */
class Para : public ListViewInterface
{
public:
    Para(ListViewInterface *parent=0, QString label=QString::null);
    ~Para();
    
    /** References the given node to this TreeView item.
     *  \param node A reference to the corresponding DOM node.
     */
    void setNode(QDomNode node);
    QString getRTFHeader() const;     
    QString getHeader() const;    
    QString getRTFData() const;
    QString getData() const;
    QString getRawData() const;

    /**
     * Embedded XML elements are allowed.
     * Checks if any embedded tags are consistent. If not, the data
     * will be stored as \p CDATA.
     * \param data The new content of a DocBook paragraph without
     * opening and closing \p \<para\> ...\p \</para\> tags.\n
     */
    void setData(const QString &data);

private:    
    // Pointer to the associated Data
    QDomNode m_node;
};


/**
 Represents the DocBook \p Chapter element of the document.\n
 Structural item only (no references to a DOM node).
 @author Robert Vogl
 */
class Chapter : public ListViewInterface
{
public:
    Chapter(ListViewInterface *parent=0, QString label=QString::null);
    ~Chapter();
    
    QString getRTFHeader() const;     
    QString getHeader() const;    
    QString getRTFData() const;
    QString getData() const;
    QString getRawData() const;
    void setData(const QString &data);   
};


/**
 Represents the DocBook \p Sec1 element of the document.\n
 Structural item only (no references to a DOM node).
 @author Robert Vogl
 */
class Sect1 : public ListViewInterface
{
public:
    Sect1(ListViewInterface *parent=0, QString label=QString::null);
    ~Sect1();

    QString getRTFHeader() const;
    QString getHeader() const;
    QString getRTFData() const;
    QString getData() const;
    QString getRawData() const;
    void setData(const QString &data);
};


/**
 Represents the DocBook \p Sec2 element of the document.\n
 Structural item only (no references to a DOM node).
 @author Robert Vogl
 */
class Sect2 : public ListViewInterface
{
public:
    Sect2(ListViewInterface *parent=0, QString label=QString::null);
    ~Sect2();

    QString getRTFHeader() const;
    QString getHeader() const;
    QString getRTFData() const;
    QString getData() const;
    QString getRawData() const;
    void setData(const QString &data);   
};


/**
 Represents the DocBook \p Sec3 element of the document.\n
 Structural item only (no references to a DOM node).
 @author Robert Vogl
 */
class Sect3 : public ListViewInterface
{
public:
    Sect3(ListViewInterface *parent=0, QString label=QString::null);
    ~Sect3();
    
    QString getRTFHeader() const;     
    QString getHeader() const;    
    QString getRTFData() const;
    QString getData() const;
    QString getRawData() const;
    void setData(const QString &data);   
};


/**
 Represents the DocBook \p Sec4 element of the document.\n
 Structural item only (no references to a DOM node).
 @author Robert Vogl
 */
class Sect4 : public ListViewInterface
{
public:
    Sect4(ListViewInterface *parent=0, QString label=QString::null);
    ~Sect4();
    
    QString getRTFHeader() const;     
    QString getHeader() const;    
    QString getRTFData() const;
    QString getData() const;
    QString getRawData() const;
    void setData(const QString &data);   
};


/**
 Represents the DocBook \p Sec5 element of the document.\n
 Structural item only (no references to a DOM node).
 @author Robert Vogl
 */
class Sect5 : public ListViewInterface
{
public:
    Sect5(ListViewInterface *parent=0, QString label=QString::null);
    ~Sect5();
    
    QString getRTFHeader() const;     
    QString getHeader() const;    
    QString getRTFData() const;
    QString getData() const;
    QString getRawData() const;
    void setData(const QString &data);   
};





/**
This class implements the TreeView object.\n
It takes a XML/DocBook file, parses it and builds up a hierarchical
\p QListView structure corresponding to the structure of the document.
The objective of this class is to maintain the document and provide
all required methods to access or manipulate its content.
@author Robert Vogl
*/
class DocTreeViewImpl : public DocTreeView
{
public:
    DocTreeViewImpl(QWidget* parent=0, const char* name=0, WFlags fl=0);

    ~DocTreeViewImpl();

    /**
     * Tries to open and parse the given file. If the file is not identified as a
     * valid XML/DocBook file, it will be packed as a \p CDATA block into a \p para element
     * of a simple DocBook'ish XML file.
     * \param url The URL of the file.
     */
    void openFile(const KURL &url);

    /**
     * Saves the document to a XML file.
     */
    void saveFile();

    /**
     * Saves the document to a XML file and allows the user to define a name.
     */
    void saveFileAs();

    /**
     * Cleans up the interal document data structures.
     */
    void clear();

    /**
     * Creates an empty XML document that conatins one editable DocBook \p Paragraph.
     * Usually called after clean() and initial startup.
     */
    void createEmptyDocument();

    /**
     * Stores the given text in the current node.
     * \param text The new content of the current DOM node.
     */
    void setNodeContent(QString &text);

    /**
     * Starting from the current selected node it travels recursively
     * through all childs and collects the content of all corresponding
     * DOM nodes. After sending the text to the TTS system the speech synthesis
     * process will be started.
     */
    void sayActiveNodeAndChilds();

    /**
     * Signals a stop-talking-request from the user.
     */
    void stop();

    /**
     * Controls the Edit Mode.
     * \param mode If true, Edit Mode ON,\n if false, Edit Mode OFF.
     */
    void setEditMode(bool mode);
    
    /**
     * Sets the item active designated by the ID.
     * \param ID The ID (column 3) of the TreeView item.
     * \returns true, if the operation was successfull,\n
     * false, if the item was not found.
     */
    bool selectItemByID(const QString &ID);

protected slots:
    /**
     * Reimplemented from base class.
     * Called whenever the active node has been changed.\n
     * Makes the former selected item persistent (maybe it has
     * been changed).\n
     * Displays the content of the selected Node either in RTF or
     * plain text format (depending on the Edit Mode flag, childs
     * present or not).\n
     * Informs the BookmarkManager about the new item.
     *
     * \param item The new active item of the TreeView.
     */
    void slotItemClicked(QListViewItem *item);
    
    /**
     * Reimplemented from base class.
     * Called by a RMB click on an treeView item.
     * \param item The item nder the mouse pointer.
     * \param pos Not used.
     * \param col Not used.
     */
    // void slotContextMenuReq(QListViewItem *item, const QPoint &pos, int col);
    
    /**
     * Reimplemented from QWidget class.
     */
    // void contextMenuEvent(QContextMenuEvent *e);
    
    
private: // Methods
    // a selection of DocBook elements
    void parseBook(const QDomElement &element, ListViewInterface *item);
    void parseBookInfo(const QDomElement &element, ListViewInterface *item);
    void parseAuthorGroup(const QDomElement &element, ListViewInterface *item);
    void parseAuthor(const QDomElement &element, ListViewInterface *item);
    void parseKeywordSet(const QDomElement &element, ListViewInterface *item);
    void parseAbstract(const QDomElement &element, ListViewInterface *item);
    void parseChapter(const QDomElement &element, ListViewInterface *item);
    void parseSect1(const QDomElement &element, ListViewInterface *item);
    void parseSect2(const QDomElement &element, ListViewInterface *item);
    void parseSect3(const QDomElement &element, ListViewInterface *item);
    void parseSect4(const QDomElement &element, ListViewInterface *item);
    void parseSect5(const QDomElement &element, ListViewInterface *item);
    void parsePara(const QDomElement &element, ListViewInterface *item);

    // helpers
    void recursiveTextCollector(ListViewInterface* item, QTextStream &msg, bool header=true);
    void recursiveSayNodes(ListViewInterface* item);
    void makeCurrentNodePersistent();    

        
private: // Attributes
    // ContextMenuHandler *m_contextmenuhandler;
    // KPopupMenu *m_contextmenu; 
    QDomDocument m_domTree;
    ListViewInterface *m_rootItem;
    ListViewInterface *m_currentItem;
    QString m_changedContent;
    int m_idCounter;
    bool m_stopped;
    KURL m_url;
    ParaSaxParser *m_parasaxparser;
    bool m_editMode;
};





#endif
