
/*
   Class for processing messages from/to Inspector+.
   ReWritten by Vyatcheslav V. Bratishev (slava@iss.ru)
   for using with STL library
   History:
   26.09.2003 - add GetListParams function,fixed split_params
   04.08.2003 - add 'ParamsToString' method
   17.07.2003 - bug fixed, now allow ',' in parameters value
   17.06.2003 - add operator = (string str) for Msg,Event,React
   12.06.2003 - add operator == for Msg class;
   23.05.2003
*/


#ifndef _MSG_XXX_MSG_
#define _MSG_XXX_MSG_

#include <windows.h>
#include <stdio.h>
#include <math.h>

#include <map>
#include <deque>
#include <string>
#include <utility>

using namespace std;

typedef map<string,string> map_params;

class Msg
{
 protected:
    map_params::iterator i;
    string temp_msg;
    deque<string> temp_lst;
    void split(string text, string separators, deque<string> & words) ;
    void split_params(string s,map_params &p);

 public:
    Msg();
    Msg(LPCTSTR source , LPCTSTR id, LPCTSTR action)
    {
      objtype   = source;
      objid     = id;
      objaction = action;
    }
    virtual ~Msg() {};
	
	void GetListParamInt(string name,deque<int> &values)
        {
	UINT size = GetParamInt(name + ".count");
	for(UINT i = 0;i<size;i++)	values.push_back(GetArrayParamInt(name,i));


        }
	void GetListParam(string name,deque<string> &values)
        {
          	UINT size = GetParamInt(name + ".count");
	for(UINT i = 0;i<size;i++)	values.push_back(GetArrayParam(name,i));

        }

    string objtype;
    string objid;
    string objaction;
    // string maps
    map_params params;
    //========================================================================
    string GetParam(string str);
    int GetParamInt(string str);
    long GetParamLong  (LPCTSTR param) { return atol(GetParam(param).c_str()); }
    double GetParamDouble(LPCTSTR param) { return atof(GetParam(param).c_str()); }
    string GetArrayParam(string param,int index);
    int GetArrayParamInt(string param,int index);
    double GetArrayParamDouble(string param,int index);

    void SetArrayParam(string param,int index,string value);
    void SetParamInt(string param_name,int val);
    void SetParamDouble(string param_name,double val);
    void SetParam(string param_name,string value);
    //========================================================================
    virtual void StringToMsg(string str);
    virtual const char* MsgToString();
    virtual const char* ParamsToString();

    Msg& operator= (Msg& msg)
    {
       objtype = msg.objtype;
       objid = msg.objid;
       objaction = msg.objaction;
       params = msg.params;
       return *this;
   }

   Msg& operator= (string str);

   bool operator ==(Msg& msg) const
   {
       if (objtype == msg.objtype && objid == msg.objid &&
           objaction == msg.objaction && params == msg.params)
           return TRUE;
       return FALSE;
   }

   BOOL IsParamExist(LPCTSTR name)
   {
     if (params.find(name) == params.end()) return false;
     return true;
   }

   string IntToStr(DWORD value);

   void Set(LPCTSTR source = "",
            LPCTSTR id = "",
            LPCTSTR action = "",
            bool clear_params = true)
   {
    objtype   = source;
    objid     = id;
    objaction = action;
    if (clear_params) params.clear();
   }
};
//=============================================================================
//  Using for delete objects in Inspector+ tree
class DeleteReact: public Msg
{
 public:
 DeleteReact(LPCTSTR source,LPCTSTR id)
 {
    objtype   = source;
    objid     = id;
 }
 DeleteReact& operator= (DeleteReact& msg)
 {
       objtype = msg.objtype;
       objid = msg.objid;
       return *this;
 }
 virtual ~DeleteReact() {}
 virtual const char* MsgToString();
};
//=============================================================================
class React : public Msg
{
 public:
 React(string source,string id,string action);
 React(LPCTSTR source = "", LPCTSTR id = "", LPCTSTR action = "")
 {
    objtype   = source;
    objid     = id;
    objaction = action;
 }
 virtual ~React() {};

 React& operator= (React& msg)
 {
       objtype = msg.objtype;
       objid = msg.objid;
       objaction = msg.objaction;
       params = msg.params;
       return *this;
 }
 virtual const char* MsgToString();
 React& operator= (string str);
};
//=============================================================================
class Event : public Msg
{
 public:
 Event(string source,string id,string action);
 Event(LPCTSTR source = "", LPCTSTR id = "", LPCTSTR action = "")
 {
    objtype   = source;
    objid     = id;
    objaction = action;
 }
 virtual ~Event() {};
 Event& operator= (Event& msg)
 {
       objtype = msg.objtype;
       objid = msg.objid;
       objaction = msg.objaction;
       params = msg.params;
       return *this;
 }
 Event& operator= (string str);
};
//=============================================================================

#endif