#ifndef DEBUGDOCUMENT_H
#define DEBUGDOCUMENT_H

#include <QHash>
#include <QObject>
#include <QVector>
#include <QStringList>

#include "misc/shared.h"

namespace KJS {
    class Interpreter;
}

namespace KTextEditor {
    class Document;
    class View;
    class Editor;
}

namespace KJSDebugger {

class DebugDocument : public QObject, public khtml::Shared<DebugDocument>
{
    Q_OBJECT
public:
    typedef SharedPtr<DebugDocument> Ptr;

    DebugDocument(KJS::Interpreter* interp, const QString& url, 
                  int sourceId, int baseLine, const QString &source);
    ~DebugDocument();

    QString name() const;
    QString url() const;
    int     sid() const;

    KTextEditor::Document* viewerDocument();
    KTextEditor::View*     viewerView();

    // Marks the document as being discarded for reload, so that new data should be set here.
    void markReload();
    bool isMarkedReload() const;
    
    void reloaded(int sourceId, const QString &source);

    void setBreakpoint(int lineNumber);
    void removeBreakpoint(int lineNumber);
    bool hasBreakpoint(int lineNumber);
    
    // We keep track of whether documents have functions, since we can't discard
    // eval contexts that do
    bool hasFunctions();
    void setHasFunctions();
    
    KJS::Interpreter* interpreter(); 
    
    int baseLine() const;
    int length()   const;

signals:
    void documentDestroyed(KJSDebugger::DebugDocument*);
private:
    QString m_url;
    QString m_name;
    KJS::Interpreter* m_interpreter;
    
    bool m_hasFunctions;

    // This is set to true when we are rebuilding the document.
    // in that case, the UI might get undesired mark add/remove events,
    // and update the breakpoint set accordingly --- such as removing all of them
    // on clear. 
    bool m_rebuilding;

    bool m_reload;
    
    int m_firstLine;
    int m_sourceId;
    QStringList m_sourceLines;
    QString     m_md5; // empty if invalid/not computed.

    void rebuildViewerDocument();
    void setupViewerDocument();

    // We store breakpoints differently for scopes with URL
    // and without it. Those that have it are stored globally,
    // so that breakpoints persist across multiple visits of the
    // document. For eval scopes, we store them based on the MD5
    // of the source code.
    static QHash<QString, QVector<int> >* s_perUrlBreakPoints;
    static QHash<QString, QVector<int> >* s_perHashBreakPoints;

    QVector<int>& breakpoints();

    KTextEditor::Document* m_kteDoc;
    KTextEditor::View*     m_kteView;
    static KTextEditor::Editor* s_kate;
    static KTextEditor::Editor* kate();
};

}


#endif
