summaryrefslogtreecommitdiff
path: root/plugins/HistoryStats/src/contact.h
diff options
context:
space:
mode:
Diffstat (limited to 'plugins/HistoryStats/src/contact.h')
-rw-r--r--plugins/HistoryStats/src/contact.h226
1 files changed, 226 insertions, 0 deletions
diff --git a/plugins/HistoryStats/src/contact.h b/plugins/HistoryStats/src/contact.h
new file mode 100644
index 0000000000..a4031269de
--- /dev/null
+++ b/plugins/HistoryStats/src/contact.h
@@ -0,0 +1,226 @@
+#if !defined(HISTORYSTATS_GUARD_CONTACT_H)
+#define HISTORYSTATS_GUARD_CONTACT_H
+
+#include "_globals.h"
+#include "_consts.h"
+
+#include <string>
+#include <map>
+#include <vector>
+#include <ctime>
+
+#include "inout.h"
+#include "settings.h"
+#include "message.h"
+#include "statistic.h"
+
+/*
+ * Contact
+ */
+
+class Contact
+ : private pattern::NotCopyable<Contact>
+{
+private:
+ ext::string m_Nick;
+ ext::string m_Protocol;
+ ext::string m_Group;
+ InOut m_Bytes;
+ InOut m_Messages;
+ InOut m_Chats;
+ bool m_bChatDurValid;
+ DWORD m_ChatDurMin;
+ DWORD m_ChatDurMax;
+ DWORD m_ChatDurSum;
+ bool m_bFirstLastTimeValid;
+ DWORD m_FirstTime;
+ DWORD m_LastTime;
+ InOut m_Files;
+ InOut m_Urls;
+ int m_NumContacts;
+ int m_NumSubcontacts;
+
+ std::vector<void*> m_Slots;
+ Statistic* m_pStatistic;
+
+private:
+ void updateTime(DWORD msgTime);
+ void updateChatDur(DWORD timeDelta);
+ double getAvg(int nTotal) const;
+
+public:
+ explicit Contact(Statistic* pStatistic, int nSlots, const ext::string& nick, const ext::string& protocol, const ext::string& group, int nContacts, int nSubcontacts);
+
+ // basic contact info
+ const ext::string& getNick() const { return m_Nick; }
+ const ext::string& getProtocol() const { return m_Protocol; }
+ const ext::string& getGroup() const { return m_Group; }
+
+ // characters/messages/bytes (absolute)
+ int getOutBytes() const { return m_Bytes.out; }
+ int getInBytes() const { return m_Bytes.in; }
+ int getTotalBytes() const { return m_Bytes.total(); }
+ int getOutMessages() const { return m_Messages.out; }
+ int getInMessages() const { return m_Messages.in; }
+ int getTotalMessages() const { return m_Messages.total(); }
+ int getOutChats() const { return m_Chats.out; }
+ int getInChats() const { return m_Chats.in; }
+ int getTotalChats() const { return m_Chats.total(); }
+
+ // characters/messages/bytes (average)
+ double getOutBytesAvg() const { return getAvg(m_Bytes.out); }
+ double getInBytesAvg() const { return getAvg(m_Bytes.in); }
+ double getTotalBytesAvg() const { return getAvg(m_Bytes.total()); }
+ double getOutMessagesAvg() const { return getAvg(m_Messages.out); }
+ double getInMessagesAvg() const { return getAvg(m_Messages.in); }
+ double getTotalMessagesAvg() const { return getAvg(m_Messages.total()); }
+ double getOutChatsAvg() const { return getAvg(m_Chats.out); }
+ double getInChatsAvg() const { return getAvg(m_Chats.in); }
+ double getTotalChatsAvg() const { return getAvg(m_Chats.total()); }
+
+ // chat duration
+ bool isChatDurValid() const { return m_bChatDurValid; }
+ DWORD getChatDurMin() const { return m_ChatDurMin; }
+ DWORD getChatDurAvg() const { return getTotalChats() ? m_ChatDurSum / getTotalChats() : 0; }
+ DWORD getChatDurMax() const { return m_ChatDurMax; }
+ int getChatDurMinForSort() const { return m_bChatDurValid ? getChatDurMin() : -1; }
+ int getChatDurAvgForSort() const { return m_bChatDurValid ? getChatDurAvg() : -1; }
+ int getChatDurMaxForSort() const { return m_bChatDurValid ? getChatDurMax() : -1; }
+ DWORD getChatDurSum() const { return m_ChatDurSum; }
+
+ // first/last time
+ bool isFirstLastTimeValid() const { return m_bFirstLastTimeValid; }
+ DWORD getFirstTime() const { return m_FirstTime; }
+ DWORD getLastTime() const { return m_LastTime; }
+
+ // files and URLs
+ int getOutUrls() const { return m_Urls.out; }
+ int getInUrls() const { return m_Urls.in; }
+ int getTotalUrls() const { return m_Urls.total(); }
+ int getOutFiles() const { return m_Files.out; }
+ int getInFiles() const { return m_Files.in; }
+ int getTotalFiles() const { return m_Files.total(); }
+
+ // (sub)contact counts
+ int getNumContacts() const { return m_NumContacts; }
+ int getNumSubcontacts() const { return m_NumSubcontacts; }
+
+ // stuff for reading history
+ void beginMessages() { }
+ void endMessages() { }
+ void addMessage(Message& msg);
+ void addChat(bool bOutgoing, DWORD localTimestampStarted, DWORD duration);
+ void addEvent(WORD eventType, bool bOutgoing);
+ void merge(const Contact& other);
+
+ // slot stuff
+ int countSlot() const { return m_Slots.size(); }
+ const void* getSlot(int index) const { return m_Slots[index]; }
+ void* getSlot(int index) { return m_Slots[index]; }
+ void setSlot(int index, void* pData) { m_Slots[index] = pData; }
+};
+
+/*
+ * ContactCompareBase
+ */
+
+class ContactCompareBase
+{
+protected:
+ bool m_bAsc;
+
+public:
+ virtual bool cmp(const Contact& first, const Contact& second) { return m_bAsc; }
+ void setDir(bool bAsc) { m_bAsc = bAsc; }
+ explicit ContactCompareBase() : m_bAsc(true) { }
+};
+
+/*
+ * ContactCompare<T_>
+ */
+
+template<typename T_>
+class ContactCompare
+ : public ContactCompareBase
+{
+private:
+ T_ (Contact::*m_getData)() const;
+ ContactCompareBase* m_pNextCmp;
+
+public:
+ virtual bool cmp(const Contact& first, const Contact& second)
+ {
+ T_ firstVal = (first.*m_getData)();
+ T_ secondVal = (second.*m_getData)();
+
+ if (firstVal == secondVal)
+ {
+ return m_pNextCmp->cmp(first, second);
+ }
+ else
+ {
+ return (m_bAsc ? (firstVal < secondVal) : (firstVal > secondVal));
+ }
+ }
+
+public:
+ explicit ContactCompare(ContactCompareBase* pNextCmp, T_ (Contact::*getData)() const)
+ : m_pNextCmp(pNextCmp)
+ {
+ m_getData = getData;
+ }
+};
+
+/*
+ * ContactCompareStr
+ */
+
+class ContactCompareStr
+ : public ContactCompareBase
+{
+private:
+ const ext::string& (Contact::*m_getData)() const;
+ ContactCompareBase* m_pNextCmp;
+
+public:
+ virtual bool cmp(const Contact& first, const Contact& second)
+ {
+ const ext::string& firstVal = (first.*m_getData)();
+ const ext::string& secondVal = (second.*m_getData)();
+
+ // int cmpRes = ext::strfunc::icmp(firstVal.c_str(), secondVal.c_str());
+ int cmpRes = ext::strfunc::icoll(firstVal.c_str(), secondVal.c_str());
+
+ if (cmpRes == 0)
+ {
+ return m_pNextCmp->cmp(first, second);
+ }
+ else
+ {
+ return (m_bAsc ? (cmpRes < 0) : (cmpRes > 0));
+ }
+ }
+
+public:
+ explicit ContactCompareStr(ContactCompareBase* pNextCmp, const ext::string& (Contact::*getData)() const)
+ : m_pNextCmp(pNextCmp)
+ {
+ m_getData = getData;
+ }
+};
+
+/*
+ * ContactCompareOp
+ */
+
+class ContactCompareOp
+{
+private:
+ ContactCompareBase* m_pCmp;
+
+public:
+ bool operator ()(const Contact* first, const Contact* second) { return m_pCmp->cmp(*first, *second); }
+ explicit ContactCompareOp(ContactCompareBase* pCmp) : m_pCmp(pCmp) { }
+};
+
+#endif // HISTORYSTATS_GUARD_CONTACT_H \ No newline at end of file