/***********************************************************************

  Copyright by Telelogic AB 1998

  This Program is owned by Telelogic and is protected by national
  copyright laws and international copyright treaties. Telelogic grants
  you the right to use this Program on one computer or in one local
  computer network at any one time.

  Under this License you may only modify the source code for the purpose
  of adapting it to your environment. You must reproduce and include any
  copyright and trademark notices on all copies of the source code.  You
  may not use, copy, merge, modify or transfer the Program except as
  provided in this License.

  Telelogic does not warrant that the Program will meet your
  requirements or that the operation of the Program will be
  uninterrupted and error free. You are solely responsible that the
  selection of the Program and the modification of the source code will
  achieve your intended results and that the results are actually
  obtained.

************************************************************************/


#ifndef pmtool_h
#define pmtool_h

#include "stlmini.h"

#ifdef __BORLANDC__
#pragma option -w-inl
#include <strstrea.h>
#elif defined _MSC_VER
#ifdef STANDARD_LIBRARY_AVAILABLE
#include <strstream>
#else
#include <strstrea.h>
#endif
#else
#include <strstream.h>
#endif

#define _spMList

#include "post.h"
#include "sdt.h"

bool StringNeedsQuotes (const string &s);
string ExtractQuotedString (istream &is);

inline void InsertQuotedString (const string &s, ostream &os) {
  os << "\"";
  for (unsigned i = 0; i < s.size(); i++) {
    if (s[i] == '"' || s[i] == '\\')
      os << "\\";
    os << s[i];
  }
  os << "\"";
}


class MessagePacker {
public:
  MessagePacker () {}
  void PackReplyStatus (int status = 0)    { os_ << status << " "; }
  void PackInteger (int value)             { os_ << value << " "; }
  void PackBool (bool value)             { os_ << int(value) << " "; }
  void PackString (const string &value)    { InsertQuotedString (value, os_);
  os_<< " ";}
  void PackStringList (const list<string> & strList)    
    { 
      PackInteger (strList.size());
      for (list<string>::const_iterator li=strList.begin();
	   li != strList.end();
	   li++)
	  PackString (*li);
    }
  void PackIntegerList (const list<int> & strList)    
    { 
      PackInteger (strList.size());
      for (list<int>::const_iterator li=strList.begin();
	   li != strList.end();
	   li++)
	  PackInteger (*li);
    }

  string GetMessage() 
    { os_ << ends; char *s = os_.str(); string r = s; delete[] s; return r; }

private:
  ostrstream os_;
};


class MessageUnpacker {
public:
  MessageUnpacker (const string &message)
      :
#if defined __BORLANDC__ || defined _MSC_VER
      is_ ((char *) message.c_str()),
#else
      is_ (message.c_str()),
#endif
      error_ (false)
    {}
  
  void UnpackReplyStatus (bool *success = NULL);
  void UnpackInteger (int *value);
  void UnpackBool (bool *value);
  void UnpackString (string *value);
  void UnpackStringList (list<string> *strList);

  
  bool   GetUnpackStatus() const    { return ! error_; }
  string GetErrorText() const       { return errorString_; }

protected:
  bool GetToken (string *s)
    {
      string temp = ExtractQuotedString (is_);
      if (s) *s = temp;
//      if (is_.fail ()) {
//        error_ = true;
//        return false;
//      }
      return true;
    }
  
private:
  istrstream is_;
  bool error_;
  string errorString_;
};



class PMConnection {
public:
  PMConnection() : open_ (false) {}
  ~PMConnection() { Close(); }

  bool PMConnection::Open (string *status = NULL);
  void PMConnection::Close ();
  
private:
  bool open_;
};



class PMTool {
public:
  PMTool (int toolType, const string &toolName) : 
    toolType_ (toolType), toolName_ (toolName) {}

  bool RPCStart ();
  bool RPCConnect ();
  
  bool RPCSendMessage (int message, const string &data, string *reply);

  int GetToolType() const               { return toolType_; }
  string GetToolName() const            { return toolName_; }
  
  int GetPid() const                    { return pid_; }
  string GetErrorText() const;
  
private:
  int toolType_;
  string toolName_;
  int pid_;
  string reply_;
};


class PMEditorTool : public PMTool {
public:
  PMEditorTool(int type, const string &name) : PMTool (type, name) {}

  bool RPCLoad (const string &filename, int *bufferId = NULL);
  bool RPCLoadCopy (const string &filename, int *bufferId = NULL);
  bool RPCShow (int bufferId, const string &pageName);
};


class OMEditorTool : public PMEditorTool {
public:
  OMEditorTool() : PMEditorTool (SET_OME, "OM Editor") {}
};


class TextEditorTool : public PMEditorTool {
public:
  TextEditorTool() : PMEditorTool (SET_TE, "Text Editor") {}
};


#endif // pmtool_h
