/***************************************************************************
                          phpdebuggubed.cpp
                             -------------------
    begin                : 2004-03-12
    copyright            : (C) 2004 Linus McCabe <linus@mccabe.nu>
 ***************************************************************************/

/****************************************************************************
 *                                                                          *
 *   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.                                    *
 *                                                                          *
 ***************************************************************************/

#ifndef QUANTADEBUGGERGUBED_H
#define QUANTADEBUGGERGUBED_H

#include <kserversocket.h>
#include <kstreamsocket.h>
#include <tqptrlist.h>
#include <kurl.h>
#include <tqdom.h>

#include "debuggerclient.h"

typedef TQValueList<TQString> WatchList;
typedef TQMap<TQString, TQString> StringMap;

class QuantaDebuggerGubed : public DebuggerClient
{
    Q_OBJECT
  

  public:
    QuantaDebuggerGubed(TQObject *parent, const char* name, const TQStringList&);
    ~QuantaDebuggerGubed();

    // Execution states
    enum State
    {
      Pause = 0,
      Trace,
      Run
    };
    // Error codes
    enum Errors
    {
      Warning = 2,
      Notice = 8,
      User_Error = 256,
      User_Warning = 512,
      User_Notice = 1024
    };

    // Protocol version
    static const char protocolversion[];

    // Manager interaction
    const uint supports(DebuggerClientCapabilities::Capabilities);

    // Execution control
    void request();
    void trace();
    void run();
    void skip();
    void stepInto();
    void stepOver();
    void stepOut();
    void pause();
    void kill();
    void setExecutionState(State newstate);

    // Connection
    void startSession();
    void endSession();

    // Return name of debugger
    TQString getName();

    // New file opened in quanta
    void fileOpened(const TQString& file);

    // Settings
    void readConfig(TQDomNode node);
    void showConfig(TQDomNode node);

    // Breakpoints
    void addBreakpoint(DebuggerBreakpoint* breakpoint);
    void removeBreakpoint(DebuggerBreakpoint* breakpoint);
    void showCondition(const StringMap &args);

    // Variables
    void addWatch(const TQString &variable);
    void removeWatch(DebuggerVariable *var);
    void variableSetValue(const DebuggerVariable &variable);

  private:
    KNetwork::KStreamSocket *m_socket;
    KNetwork::TDEServerSocket *m_server;
    TQString m_command, m_buffer;
    long    m_datalen;

    TQString m_serverBasedir;
    TQString m_localBasedir;
    TQString m_serverPort;
    TQString m_serverHost;
    TQString m_startsession;
    TQString m_listenPort;
    bool    m_useproxy;
    State   m_executionState, m_defaultExecutionState;
    long    m_errormask;
    long    m_displaydelay;

    WatchList m_watchlist;

//     bool sendCommand(const TQString&, const TQString&);
    bool sendCommand(const TQString& command, StringMap args);
    bool sendCommand(const TQString& command, const char * firstarg, ...);

    void processCommand(const TQString&);
    void sendWatches();
    void sendBreakpoints();
    void debuggingState(bool enable);
    void connected();

    TQString mapServerPathToLocal(const TQString& serverpath);
    TQString mapLocalPathToServer(const TQString& localpath);
    TQString bpToGubed(DebuggerBreakpoint* breakpoint);

    // Communication helpers
    TQString phpSerialize(StringMap args);
    StringMap parseArgs(const TQString &args);

    // Variables
    DebuggerVariable* parsePHPVariables(const TQString &varstring);
    DebuggerVariable* parsePHPVariables(TQString &str);
    void showWatch(const TQString& data);

    
  public slots:
    // Socket slots
    void slotConnected(const KNetwork::KResolverEntry &);
    void slotConnectionClosed();
    void slotError(int error);
    void slotReadyRead();
    void slotReadyAccept();

  signals:
    void updateStatus(DebuggerUI::DebuggerStatus);
};

#endif
