Index: /trunk/FACT++/src/DimState.h
===================================================================
--- /trunk/FACT++/src/DimState.h	(revision 14085)
+++ /trunk/FACT++/src/DimState.h	(revision 14086)
@@ -2,5 +2,13 @@
 #define FACT_DimState
 
+#include <set>
+#include <string>
+#include <functional>
+
 #include "State.h"
+#include "EventImp.h"
+#include "WindowLog.h"
+#include "Description.h"
+#include "StateMachineImp.h"
 
 class DimState
@@ -14,5 +22,5 @@
 
 protected:
-    typedef function<void(const EventImp &)> callback;
+    typedef std::function<void(const EventImp &)> callback;
 
     callback fCallback;
@@ -23,5 +31,5 @@
 
         last = cur;
-        cur  = make_pair(evt.GetTime(), disconnected ? kOffline : evt.GetQoS());
+        cur  = std::make_pair(evt.GetTime(), disconnected ? kOffline : evt.GetQoS());
 
         msg = disconnected ? "" : evt.GetString();
@@ -41,7 +49,8 @@
 
 public:
-    DimState(const string &n, const string s="STATE") : server(n),
+    DimState() { std::cout << "DefCon" << std::endl; }
+    DimState(const std::string &n, const std::string s="STATE") : server(n),
         service(n+"/"+s),
-        last(make_pair(Time(), kOffline)), cur(make_pair(Time(), kOffline))
+        last(std::make_pair(Time(), kOffline)), cur(std::make_pair(Time(), kOffline))
     {
     }
@@ -50,15 +59,15 @@
     }
 
-    const string server;
-    const string service;
-
-    pair<Time, int32_t> last;
-    pair<Time, int32_t> cur;
-    string msg;
+    /*const*/ std::string server;
+    /*const*/ std::string service;
+
+    std::pair<Time, int32_t> last;
+    std::pair<Time, int32_t> cur;
+    std::string msg;
 
     virtual void Subscribe(StateMachineImp &imp)
     {
-        imp.Subscribe(service.c_str())
-            (imp.Wrap(bind(&DimState::Handler, this, placeholders::_1)));
+        imp.Subscribe(service)
+            (imp.Wrap(std::bind(&DimState::Handler, this, std::placeholders::_1)));
     }
 
@@ -76,5 +85,5 @@
 };
 
-ostream &operator<<(ostream& out, const DimState &s)
+inline std::ostream &operator<<(std::ostream& out, const DimState &s)
 {
     const State rc = s.description();
@@ -105,17 +114,33 @@
 class DimDescribedState : public DimState
 {
-    vector<State> states;
-
-public:
-    DimDescribedState(const string &n) : DimState(n)
-    {
-    }
+    typedef std::function<void()> callback_desc;
+
+    callback_desc fCallbackStates;
+
+    virtual void CallbackStates()
+    {
+        if (fCallbackStates)
+            fCallbackStates();
+    }
+
+
+public:
+    DimDescribedState(const std::string &n) : DimState(n)
+    {
+    }
+
+    std::vector<State> states;
 
     virtual void Subscribe(StateMachineImp &imp)
     {
-        imp.Subscribe((server+"/STATE_LIST").c_str())
-            (imp.Wrap(bind(&DimDescribedState::HandleDesc, this, placeholders::_1)));
+        imp.Subscribe(server+"/STATE_LIST")
+            (imp.Wrap(std::bind(&DimDescribedState::HandleDesc, this, std::placeholders::_1)));
 
         DimState::Subscribe(imp);
+    }
+
+    void SetCallbackStates(const callback_desc &cb)
+    {
+        fCallbackStates = cb;
     }
 
@@ -126,4 +151,6 @@
             states = State::SplitStates(evt.GetString());
             states.push_back(State(kOffline, "Offline"));
+
+            CallbackStates();
         }
     }
@@ -139,4 +166,53 @@
 };
 
+class DimDescriptions : public DimDescribedState
+{
+    typedef std::function<void()> callback_desc;
+
+    callback_desc fCallbackDescriptions;
+
+    virtual void CallbackDescriptions()
+    {
+        if (fCallbackDescriptions)
+            fCallbackDescriptions();
+    }
+
+public:
+    DimDescriptions(const std::string &n) : DimDescribedState(n)
+    {
+    }
+
+    std::vector<State> states;
+    std::vector<std::vector<Description>> descriptions;
+
+    virtual void Subscribe(StateMachineImp &imp)
+    {
+        imp.Subscribe(server+"/SERVICE_DESC")
+            (imp.Wrap(std::bind(&DimDescriptions::HandleServiceDesc, this, std::placeholders::_1)));
+
+        DimState::Subscribe(imp);
+    }
+
+    void SetCallbackDescriptions(const callback_desc &cb)
+    {
+        fCallbackDescriptions = cb;
+    }
+
+
+    void HandleServiceDesc(const EventImp &evt)
+    {
+        descriptions.clear();
+        if (evt.GetSize()>0)
+        {
+            std::string buf;
+            std::stringstream stream(evt.GetString());
+            while (getline(stream, buf, '\n'))
+                descriptions.push_back(Description::SplitDescription(buf));
+        }
+
+        CallbackDescriptions();
+    }
+};
+
 class DimVersion : public DimState
 {
@@ -155,10 +231,10 @@
     DimVersion() : DimState("DIS_DNS", "VERSION_NUMBER") { }
 
-    string version() const
+    std::string version() const
     {
         if (!online())
             return "Offline";
 
-        ostringstream out;
+        std::ostringstream out;
         out << "V" << state()/100 << 'r' << state()%100;
         return out.str();
@@ -173,5 +249,5 @@
 class DimControl : public DimState
 {
-    map<string, callback> fCallbacks;
+    std::map<std::string, callback> fCallbacks;
 
     void Handler(const EventImp &evt)
@@ -185,20 +261,20 @@
         // Evaluate msg
         const size_t p0 = msg.find_first_of(':');
-        if (p0==string::npos)
+        if (p0==std::string::npos)
             return;
 
         // Evaluate scriptdepth
         const size_t ps = msg.find_first_of('-');
-        if (ps!=string::npos)
+        if (ps!=std::string::npos)
             scriptdepth = atoi(msg.c_str()+ps+1);
 
         // Find filename
         const size_t p1 = msg.find_last_of('[');
-        if (p1==string::npos)
+        if (p1==std::string::npos)
             return;
 
         const size_t p2 = msg.find_first_of(':', p0+1);
 
-        const size_t p3 = p2==string::npos || p2>p1 ? p1-1 : p2;
+        const size_t p3 = p2==std::string::npos || p2>p1 ? p1-1 : p2;
 
         file = msg.substr(p0+2, p3-p0-2);
@@ -220,9 +296,9 @@
     DimControl() : DimState("DIM_CONTROL") { }
 
-    string file;
-    string shortmsg;
+    std::string file;
+    std::string shortmsg;
     int scriptdepth;
 
-    void AddCallback(const string &script, const callback &cb)
+    void AddCallback(const std::string &script, const callback &cb)
     {
         fCallbacks[script] = cb;
@@ -235,3 +311,152 @@
 };
 
+class DimDnsServerList
+{
+protected:
+    typedef std::function<void(const std::string &)> callback_srv;
+    typedef std::function<void(const EventImp &)>    callback_evt;
+
+    callback_srv fCallbackServerAdd;
+    callback_srv fCallbackServerRemove;
+    callback_evt fCallbackServerEvent;
+
+    std::set<std::string> fServerList;
+
+    void HandlerServerImp(const EventImp &evt);
+
+    virtual void CallbackServerAdd(const std::string &str)
+    {
+        if (fCallbackServerAdd)
+            fCallbackServerAdd(str);
+    }
+    virtual void CallbackServerRemove(const std::string &str)
+    {
+        if (fCallbackServerRemove)
+            fCallbackServerRemove(str);
+    }
+    virtual void CallbackServerEvent(const EventImp &evt)
+    {
+        if (fCallbackServerEvent)
+            fCallbackServerEvent(evt);
+    }
+    virtual void HandlerServer(const EventImp &evt)
+    {
+        HandlerServerImp(evt);
+        CallbackServerEvent(evt);
+    }
+
+public:
+    DimDnsServerList() 
+    {
+    }
+    virtual ~DimDnsServerList()
+    {
+    }
+
+    Time  time;
+    std::string msg;
+
+    virtual void Subscribe(StateMachineImp &imp)
+    {
+        imp.Subscribe("DIS_DNS/SERVER_LIST")
+            (imp.Wrap(std::bind(&DimDnsServerList::HandlerServer, this, std::placeholders::_1)));
+    }
+
+    void SetCallbackServerAdd(const callback_srv &cb)
+    {
+        fCallbackServerAdd = cb;
+    }
+
+    void SetCallbackServerRemove(const callback_srv &cb)
+    {
+        fCallbackServerRemove = cb;
+    }
+
+    void SetCallbackServerEvent(const callback_evt &cb)
+    {
+        fCallbackServerEvent = cb;
+    }
+
+    //const Time &time() const { return time; }
+    //const std::string &msg() const { return msg; }
+};
+
+struct Service
+{
+    std::string name;
+    std::string server;
+    std::string service;
+    std::string format;
+    bool   iscmd;
+};
+
+inline bool operator<(const Service& left, const Service& right)
+{
+    return left.name < right.name;
+}
+
+class DimDnsServiceList : public DimDnsServerList
+{
+    StateMachineImp *fStateMachine;
+
+    typedef std::function<void(const Service &)> callback_svc;
+
+    callback_svc fCallbackServiceAdd;
+    //callback_evt fCallbackServiceEvt;
+
+    std::vector<std::string> fServiceList;
+
+    void CallbackServerAdd(const std::string &server)
+    {
+        fStateMachine->Subscribe(server+"/SERVICE_LIST")
+            (fStateMachine->Wrap(std::bind(&DimDnsServiceList::HandlerServiceList, this, std::placeholders::_1)));
+
+        DimDnsServerList::CallbackServerAdd(server);
+    }
+
+    void HandlerServiceListImp(const EventImp &evt);
+
+/*
+    virtual void CallbackServiceEvt(const EventImp &evt)
+    {
+        if (fCallbackServiceEvt)
+            fCallbackServiceEvt(evt);
+    }
+*/
+    virtual void HandlerServiceList(const EventImp &evt)
+    {
+        HandlerServiceListImp(evt);
+        //CallbackServiceEvent(evt);
+    }
+
+
+    virtual void CallbackServiceAdd(const Service &service)
+    {
+        if (fCallbackServiceAdd)
+            fCallbackServiceAdd(service);
+    }
+
+public:
+    DimDnsServiceList() : fStateMachine(0)
+    {
+    }
+
+    void Subscribe(StateMachineImp &imp)
+    {
+        fStateMachine = &imp;
+        DimDnsServerList::Subscribe(imp);
+    }
+
+    void SetCallbackServiceAdd(const callback_svc &cb)
+    {
+        fCallbackServiceAdd = cb;
+    }
+/*
+    void SetCallbackServiceEvt(const callback_svc &cb)
+    {
+        fCallbackServiceEvt = cb;
+    }
+*/
+};
+
 #endif
