/***************************************************************************
                          rdbcontroller.h  -  description
                             -------------------
    begin                : Sun Aug 8 1999
    copyright            : (C) 1999 by John Birch
    email                : jbb@kdevelop.org
	
                          Adapted for ruby debugging
                          --------------------------
	
    begin                : Mon Nov 1 2004
    copyright            : (C) 2004 by Richard Dale
    email                : Richard_Dale@tipitina.demon.co.uk
	
	
 ***************************************************************************/

/***************************************************************************
 *                                                                         *
 *   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 _RDBCONTROLLER_H_
#define _RDBCONTROLLER_H_

#include "dbgcontroller.h"

#include <tqcstring.h>
#include <tqdom.h>
#include <tqobject.h>
#include <tqptrlist.h>
#include <tqstring.h>
#include <tqsocketnotifier.h> 

class TDEProcess;

namespace RDBDebugger
{

class Breakpoint;
class DbgCommand;
class FramestackWidget;
class VarItem;
class VariableTree;
class STTY;

/**
 * A front end implementation to the ruby command line debugger
 * @author jbb
 */

class RDBController : public DbgController
{
    Q_OBJECT
  

public:
    RDBController(VariableTree *varTree, FramestackWidget *frameStack, TQDomDocument &projectDom);
    ~RDBController();

protected:
    void queueCmd(DbgCommand *cmd, bool executeNext=false);

private:
    void parseProgramLocation (char *buf);
    void parseBacktraceList   (char *buf);
    void parseThreadList      (char* buf);
    void parseSwitchThread    (char* buf);
    void parseFrameMove       (char *buf);
    void parseBreakpointSet   (char *buf);
    void parseDisplay         (char *buf, char * expr);
    void parseUpdateDisplay   (char *buf);
    void parseGlobals         (char *buf);
    void parseLocals          (char type, char *buf);
    void parseRequestedData   (char *buf);
    void parseFrameSelected   (char *buf);

    void parse                (char *buf);

    void pauseApp();
    void executeCmd ();
    void destroyCmds();
    void removeInfoRequests();
    void actOnProgramPause(const TQString &msg);
    void programNoApp(const TQString &msg, bool msgBox);

    void setBreakpoint(const TQCString &BPSetCmd, int key);
    void clearBreakpoint(const TQCString &BPClearCmd);
    void modifyBreakpoint(const Breakpoint&);

    void setStateOn(int stateOn)    { state_ |= stateOn; }
    void setStateOff(int stateOff)  { state_ &= ~stateOff; }
    bool stateIsOn(int state)       { return state_  &state; }

public slots:
    void configure();

    void slotStart(	const TQString& shell, const TQString& characterCoding, 
					const TQString& run_directory, const TQString& debuggee_path, 
					const TQString &application, const TQString& run_arguments,
                    bool show_constants, bool trace_into_ruby );
    //void slotStart(const TQString& shell, const TQString &application);

    void slotStopDebugger();

    void slotRun();
    void slotRunUntil(const TQString &filename, int lineNum);
    void slotStepInto();
    void slotStepOver();
    void slotStepOutOff();

    void slotBreakInto();
    void slotBPState( const Breakpoint& );
    void slotClearAllBreakpoints();

    void slotExpandItem(VarItem *parent, const TQCString &userRequest);
    void slotRubyInspect(const TQString &inspectText);
    void slotSelectFrame(int frameNo, int threadNo, const TQString& frameName);
    void slotFetchGlobals(bool fetch);
    void slotAddWatchExpression(const TQString& expr, bool execute);
	void slotRemoveWatchExpression(int displayId);

    void slotUserRDBCmd(const TQString&);

protected slots:
    void slotDbgStdout(TDEProcess *proc, char *buf, int buflen);
    void slotDbgStderr(TDEProcess *proc, char *buf, int buflen);
    void slotDbgWroteStdin(TDEProcess *proc);
    void slotDbgProcessExited(TDEProcess *proc);
	
    void slotAcceptConnection(int masterSocket);
    void slotReadFromSocket(int socket);

signals:
    void acceptPendingBPs     ();
    void unableToSetBPNow     (int BPNo);
    void addWatchExpression     (const TQString&);

private:
    FramestackWidget* frameStack_;
    VariableTree*     varTree_;
    int               currentFrame_;
    int               viewedThread_;

    int               stdoutSizeofBuf_;      // size of the buffer for holding stdout piped
	                                         // from the ruby program
    int               stdoutOutputLen_;      // amount of data in the output buffer
    char*             stdoutOutput_;         // buffer for the output from kprocess
    TQCString          holdingZone_;
    
	int               rdbSizeofBuf_;         // size of the output buffer from rdb
    int               rdbOutputLen_;         // amount of data in the rdb buffer
    char*             rdbOutput_;            // buffer for the output from rdb via the Unix socket
	
	int               masterSocket_;         // The socket to accept connections
	TQSocketNotifier*  acceptNotifier_;
    static TQCString   unixSocketPath_;       // The name of the Unix Domain socket
	int               socket_;               // The socket to read and write to the debuggee
	TQSocketNotifier*  socketNotifier_;

    TQPtrList<DbgCommand> cmdList_;
    DbgCommand*       currentCmd_;
	TQString           currentPrompt_;

    STTY*             tty_;
	
	// Details for starting the ruby debugger process
	TQString          rubyInterpreter_;
	TQString          characterCoding_;
	TQString          runDirectory_;
	TQString          debuggeePath_;
	TQString          application_;
	TQString          runArguments_;
    bool             showConstants_;
    bool             traceIntoRuby_;

    // Some state variables
    int               state_;
    bool              programHasExited_;

    // Configuration values
    TQDomDocument &dom;
    bool    config_forceBPSet_;
    bool    config_dbgTerminal_;
};

}

#endif
