

class Msg
{
protected:
	CString		m_sSourceType;
	CString		m_sSourceId;
	CString		m_sAction;
	CMapStringToString m_mapParams;
public:
	Msg(LPCTSTR source = "", LPCTSTR id = "", LPCTSTR action = "")
	{
		m_sSourceType	= source;
		m_sSourceId		= id;
		m_sAction		= action;
	}

	Msg(LPCTSTR source, LPCTSTR id, LPCTSTR action, LPCTSTR params)
	{
		m_sSourceType	= source;
		m_sSourceId		= id;
		m_sAction		= action;

		StringToParams(params);
	}

    virtual ~Msg() {}

	void Create(LPCTSTR source = "", LPCTSTR id = "", LPCTSTR action = "")
	{
		m_sSourceType	= source;
		m_sSourceId		= id;
		m_sAction		= action;
	}

	Msg(Msg& msg)
	{
		operator=(msg);
	}

	Msg& operator=(Msg& msg)
	{
		m_sSourceType	= msg.m_sSourceType;
		m_sSourceId		= msg.m_sSourceId;
		m_sAction		= msg.m_sAction;
		m_mapParams.RemoveAll();
		CString key,val;
		POSITION p = msg.m_mapParams.GetStartPosition();
		while (p)
		{
			msg.m_mapParams.GetNextAssoc(p,key,val);
			m_mapParams.SetAt(key,val);
		}

		return *this;
	}

	CString GetSourceType() { return m_sSourceType; }
	CString GetSourceId()	{ return m_sSourceId; }
	CString GetAction()		{ return m_sAction; }

	void SetSourceType(LPCTSTR s){ m_sSourceType = s; }
	void SetSourceId(LPCTSTR s)	 { m_sSourceId   = s; }
	void SetAction(LPCTSTR s)	 { m_sAction     = s; }

	CString GetParam(LPCTSTR param)
	{
		CString s;
		m_mapParams.Lookup(param, s);
		return s;
	}

	int		GetParamInt   (LPCTSTR param) { return atoi(GetParam(param)); }
	long	GetParamLong  (LPCTSTR param) { return atol(GetParam(param)); }
	double	GetParamDouble(LPCTSTR param) { return atof(GetParam(param)); }

	BOOL Check(LPCTSTR type, LPCTSTR action)
	{ return m_sSourceType==type && m_sAction==action; }

	BOOL Check(LPCTSTR type, LPCTSTR id, LPCTSTR action)
	{ return m_sSourceType==type && m_sSourceId==id && m_sAction==action; }

	BOOL operator==(Msg& msg)
	{
		return MsgToString()==msg.MsgToString();
	}

	BOOL operator!=(Msg& msg)
	{
		return MsgToString()!=msg.MsgToString();
	}

	CString MsgToString()
	{
		CString s;
		s.Format("%s|%s|%s|%s",m_sSourceType,m_sSourceId,m_sAction,ParamsToString());
		return s;
	}

	void StringToMsg(LPCTSTR str)
	{
		CString params;
		AfxExtractSubString(m_sSourceType,  str, 0, '|');
		AfxExtractSubString(m_sSourceId  ,  str, 1, '|');
		AfxExtractSubString(m_sAction    ,  str, 2, '|');
		AfxExtractSubString(params       ,  str, 3, '|');

		StringToParams(params);
	}

	void StringToParams(LPCTSTR params)
	{
		CString s;

		m_mapParams.RemoveAll();

		for (int i=0;AfxExtractSubString(s, params, i, ',');++i)
		{
			int n = s.Find('<');
			m_mapParams.SetAt(s.Left(n), s.Mid(n+1, s.GetLength()-n-2));
		}
	}

	CString ParamsToString()
	{
		CString res;
		POSITION p = m_mapParams.GetStartPosition();
		while (p)
		{
			CString key,val;
			m_mapParams.GetNextAssoc(p,key,val);

			if (!res.IsEmpty())
				 res += CString(",");

			res += key + "<" + val + ">";
		} 
		return res;
	}
};

/////////////////////////////////////////////////////////////////////////////////////////////
CString ActiveXMsg(LPCTSTR str)
{
	Msg msg;
	msg.StringToMsg(str);
	CString s;
	s.Format("CORE||DO_REACT|source_type<%s>,source_id<%s>,action<%s>",
				msg.GetSourceType(),msg.GetSourceId(),msg.GetAction() );
	return s;
}
/////////////////////////////////////////////////////////////////////////////////////////////
