From 9ccedec3844df80241c65dc6fb24d97efc2f41fc Mon Sep 17 00:00:00 2001
From: Catalin Badea <catalin.badea392@gmail.com>
Date: Fri, 20 Jul 2012 15:22:40 +0300
Subject: continous scroll between dates.


diff --git a/Swift/Controllers/HistoryController.cpp b/Swift/Controllers/HistoryController.cpp
index 51891f6..deda25b 100644
--- a/Swift/Controllers/HistoryController.cpp
+++ b/Swift/Controllers/HistoryController.cpp
@@ -25,8 +25,16 @@ void HistoryController::addMessage(const std::string& message, const JID& fromJI
 	onNewMessage(historyMessage);
 }
 
-std::vector<HistoryMessage> HistoryController::getMessages(const JID& selfJID, const JID& contactJID, HistoryMessage::Type type, const boost::gregorian::date& date) const {
-	return localHistory_->getMessages(selfJID, contactJID, type, date);
+std::vector<HistoryMessage> HistoryController::getMessagesFromDate(const JID& selfJID, const JID& contactJID, HistoryMessage::Type type, const boost::gregorian::date& date) const {
+	return localHistory_->getMessagesFromDate(selfJID, contactJID, type, date);
+}
+
+std::vector<HistoryMessage> HistoryController::getMessagesFromPreviousDate(const JID& selfJID, const JID& contactJID, HistoryMessage::Type type, const boost::gregorian::date& date) const {
+	return localHistory_->getMessagesFromPreviousDate(selfJID, contactJID, type, date);
+}
+
+std::vector<HistoryMessage> HistoryController::getMessagesFromNextDate(const JID& selfJID, const JID& contactJID, HistoryMessage::Type type, const boost::gregorian::date& date) const {
+	return localHistory_->getMessagesFromNextDate(selfJID, contactJID, type, date);
 }
 
 ContactsMap HistoryController::getContacts(const JID& selfJID, HistoryMessage::Type type, const std::string& keyword) const {
diff --git a/Swift/Controllers/HistoryController.h b/Swift/Controllers/HistoryController.h
index 53260a1..00ad752 100644
--- a/Swift/Controllers/HistoryController.h
+++ b/Swift/Controllers/HistoryController.h
@@ -23,7 +23,9 @@ namespace Swift {
 			~HistoryController();
 
 			void addMessage(const std::string& message, const JID& fromJID, const JID& toJID, HistoryMessage::Type type, const boost::posix_time::ptime& timeStamp);
-			std::vector<HistoryMessage> getMessages(const JID& selfJID, const JID& contactJID, HistoryMessage::Type type, const boost::gregorian::date& date) const;
+			std::vector<HistoryMessage> getMessagesFromDate(const JID& selfJID, const JID& contactJID, HistoryMessage::Type type, const boost::gregorian::date& date) const;
+			std::vector<HistoryMessage> getMessagesFromPreviousDate(const JID& selfJID, const JID& contactJID, HistoryMessage::Type type, const boost::gregorian::date& date) const;
+			std::vector<HistoryMessage> getMessagesFromNextDate(const JID& selfJID, const JID& contactJID, HistoryMessage::Type type, const boost::gregorian::date& date) const;
 			ContactsMap getContacts(const JID& selfJID, HistoryMessage::Type type, const std::string& keyword = std::string()) const;
 
 			boost::signal<void (const HistoryMessage&)> onNewMessage;
diff --git a/Swift/Controllers/HistoryViewController.cpp b/Swift/Controllers/HistoryViewController.cpp
index b7b71cd..8efdc99 100644
--- a/Swift/Controllers/HistoryViewController.cpp
+++ b/Swift/Controllers/HistoryViewController.cpp
@@ -31,7 +31,7 @@ HistoryViewController::HistoryViewController(
 			historyWindowFactory_(historyWindowFactory),
 			historyWindow_(NULL),
 			selectedItem_(NULL),
-			currentDate_(boost::gregorian::not_a_date_time) {
+			currentResultDate_(boost::gregorian::not_a_date_time) {
 	uiEventStream_->onUIEvent.connect(boost::bind(&HistoryViewController::handleUIEvent, this, _1));
 	historyController_->onNewMessage.connect(boost::bind(&HistoryViewController::handleNewMessage, this, _1));
 
@@ -44,6 +44,8 @@ HistoryViewController::~HistoryViewController() {
 	if (historyWindow_) {
 		historyWindow_->onSelectedContactChanged.disconnect(boost::bind(&HistoryViewController::handleSelectedContactChanged, this, _1));
 		historyWindow_->onReturnPressed.disconnect(boost::bind(&HistoryViewController::handleReturnPressed, this, _1));
+		historyWindow_->onScrollReachedTop.disconnect(boost::bind(&HistoryViewController::handleScrollReachedTop, this, _1));
+		historyWindow_->onScrollReachedBottom.disconnect(boost::bind(&HistoryViewController::handleScrollReachedBottom, this, _1));
 		delete historyWindow_;
 	}
 	delete roster_;
@@ -57,6 +59,8 @@ void HistoryViewController::handleUIEvent(boost::shared_ptr<UIEvent> rawEvent) {
 			historyWindow_ = historyWindowFactory_->createHistoryWindow(uiEventStream_);
 			historyWindow_->onSelectedContactChanged.connect(boost::bind(&HistoryViewController::handleSelectedContactChanged, this, _1));
 			historyWindow_->onReturnPressed.connect(boost::bind(&HistoryViewController::handleReturnPressed, this, _1));
+			historyWindow_->onScrollReachedTop.connect(boost::bind(&HistoryViewController::handleScrollReachedTop, this, _1));
+			historyWindow_->onScrollReachedBottom.connect(boost::bind(&HistoryViewController::handleScrollReachedBottom, this, _1));
 
 			historyWindow_->setRosterModel(roster_);
 		}
@@ -84,20 +88,23 @@ void HistoryViewController::handleSelectedContactChanged(RosterItem* newContact)
 
 	std::vector<HistoryMessage> messages;
 	if (roomPrivateContacts_.count(contactJID)) {
-		currentDate_ = *roomPrivateContacts_[contactJID].rbegin();
-		messages = historyController_->getMessages(selfJID_, contactJID, HistoryMessage::PrivateMessage, currentDate_);
+		currentResultDate_ = *roomPrivateContacts_[contactJID].rbegin();
+		messages = historyController_->getMessagesFromDate(selfJID_, contactJID, HistoryMessage::PrivateMessage, currentResultDate_);
+		currentItemType_ = HistoryMessage::PrivateMessage;
 	}
 	else if (contacts_.count(contactJID)) {
-		currentDate_ = *contacts_[contactJID].rbegin();
-		messages = historyController_->getMessages(selfJID_, contactJID, HistoryMessage::Chat, currentDate_);
+		currentResultDate_ = *contacts_[contactJID].rbegin();
+		messages = historyController_->getMessagesFromDate(selfJID_, contactJID, HistoryMessage::Chat, currentResultDate_);
+		currentItemType_ = HistoryMessage::Chat;
 	}
 	else {
-		currentDate_ = *rooms_[contactJID].rbegin();
-		messages = historyController_->getMessages(selfJID_, contactJID, HistoryMessage::Groupchat, currentDate_);
+		currentResultDate_ = *rooms_[contactJID].rbegin();
+		messages = historyController_->getMessagesFromDate(selfJID_, contactJID, HistoryMessage::Groupchat, currentResultDate_);
+		currentItemType_ = HistoryMessage::Groupchat;
 	}
 
 	foreach (const HistoryMessage& message, messages) {
-		addNewMessage(message);
+		addNewMessage(message, false);
 	}
 }
 
@@ -114,7 +121,7 @@ void HistoryViewController::handleNewMessage(const HistoryMessage& message) {
 
 	// check current conversation
 	if (selectedItem_ && selectedItem_->getJID() == displayJID) {
-		addNewMessage(message);
+		addNewMessage(message, false);
 	}
 	// add new contact
 	else if (message.getType() == HistoryMessage::Groupchat && !rooms_.count(displayJID)) {
@@ -133,10 +140,10 @@ void HistoryViewController::handleNewMessage(const HistoryMessage& message) {
 	}
 }
 
-void HistoryViewController::addNewMessage(const HistoryMessage& message) {
+void HistoryViewController::addNewMessage(const HistoryMessage& message, bool addAtTheTop) {
 	bool senderIsSelf = message.getFromJID().toBare() == selfJID_;
 	std::string avatarPath = avatarManager_->getAvatarPath(message.getFromJID()).string();
-	historyWindow_->addMessage(message.getMessage(), nickResolver_->jidToNick(message.getFromJID()), senderIsSelf, avatarPath, message.getTime());
+	historyWindow_->addMessage(message.getMessage(), nickResolver_->jidToNick(message.getFromJID()), senderIsSelf, avatarPath, message.getTime(), addAtTheTop);
 }
 
 void HistoryViewController::handleReturnPressed(const std::string& keyword) {
@@ -146,7 +153,6 @@ void HistoryViewController::handleReturnPressed(const std::string& keyword) {
 	roomPrivateContacts_.clear();
 	selectedItem_ = NULL;
 	historyWindow_->resetConversationView();
-	// TODO set date
 
 	// MUCs
 	rooms_ = historyController_->getContacts(selfJID_, HistoryMessage::Groupchat, keyword);
@@ -170,4 +176,20 @@ void HistoryViewController::handleReturnPressed(const std::string& keyword) {
 	}
 }
 
+void HistoryViewController::handleScrollReachedTop(const boost::gregorian::date& date) {
+	std::vector<HistoryMessage> messages = historyController_->getMessagesFromPreviousDate(selfJID_, selectedItem_->getJID(), currentItemType_, date);
+
+	reverse_foreach (const HistoryMessage& message, messages) {
+		addNewMessage(message, true);
+	}
+}
+
+void HistoryViewController::handleScrollReachedBottom(const boost::gregorian::date& date) {
+	std::vector<HistoryMessage> messages = historyController_->getMessagesFromNextDate(selfJID_, selectedItem_->getJID(), currentItemType_, date);
+
+	foreach (const HistoryMessage& message, messages) {
+		addNewMessage(message, true);
+	}
+}
+
 }
diff --git a/Swift/Controllers/HistoryViewController.h b/Swift/Controllers/HistoryViewController.h
index cddcfb8..5c4dc96 100644
--- a/Swift/Controllers/HistoryViewController.h
+++ b/Swift/Controllers/HistoryViewController.h
@@ -35,8 +35,10 @@ namespace Swift {
 			void handleUIEvent(boost::shared_ptr<UIEvent> event);
 			void handleSelectedContactChanged(RosterItem* item);
 			void handleNewMessage(const HistoryMessage& message);
-			void addNewMessage(const HistoryMessage& message);
+			void addNewMessage(const HistoryMessage& message, bool addAtTheTop);
 			void handleReturnPressed(const std::string& keyword);
+			void handleScrollReachedTop(const boost::gregorian::date& date);
+			void handleScrollReachedBottom(const boost::gregorian::date& date);
 
 		private:
 			JID selfJID_;
@@ -52,6 +54,7 @@ namespace Swift {
 			ContactsMap rooms_;
 			ContactsMap roomPrivateContacts_;
 			ContactRosterItem* selectedItem_;
-			boost::gregorian::date currentDate_;
+			HistoryMessage::Type currentItemType_;
+			boost::gregorian::date currentResultDate_;
 	};
 }
diff --git a/Swift/Controllers/UIInterfaces/HistoryWindow.h b/Swift/Controllers/UIInterfaces/HistoryWindow.h
index d38d6df..effff27 100644
--- a/Swift/Controllers/UIInterfaces/HistoryWindow.h
+++ b/Swift/Controllers/UIInterfaces/HistoryWindow.h
@@ -15,10 +15,12 @@ namespace Swift {
 
 			virtual void activate() = 0;
 			virtual void setRosterModel(Roster*) = 0;
-			virtual void addMessage(const std::string &message, const std::string &senderName, bool senderIsSelf, const std::string& avatarPath, const boost::posix_time::ptime& time) = 0;
+			virtual void addMessage(const std::string &message, const std::string &senderName, bool senderIsSelf, const std::string& avatarPath, const boost::posix_time::ptime& time, bool addAtTheTop) = 0;
 			virtual void resetConversationView() = 0;
 
 			boost::signal<void (RosterItem*)> onSelectedContactChanged;
 			boost::signal<void (const std::string&)> onReturnPressed;
+			boost::signal<void (const boost::gregorian::date&)> onScrollReachedTop;
+			boost::signal<void (const boost::gregorian::date&)> onScrollReachedBottom;
 	};
 }
diff --git a/Swift/QtUI/QtHistoryWindow.cpp b/Swift/QtUI/QtHistoryWindow.cpp
index ed91551..feec059 100644
--- a/Swift/QtUI/QtHistoryWindow.cpp
+++ b/Swift/QtUI/QtHistoryWindow.cpp
@@ -23,6 +23,7 @@
 #include <QLineEdit>
 
 #include <boost/smart_ptr/make_shared.hpp>
+#include <boost/date_time/gregorian/gregorian.hpp>
 
 namespace Swift {
 
@@ -92,7 +93,7 @@ void QtHistoryWindow::setRosterModel(Roster* model) {
 	conversationRoster_->setRosterModel(model);
 }
 
-void QtHistoryWindow::addMessage(const std::string &message, const std::string &senderName, bool senderIsSelf, const std::string& avatarPath, const boost::posix_time::ptime& time) {
+void QtHistoryWindow::addMessage(const std::string &message, const std::string &senderName, bool senderIsSelf, const std::string& avatarPath, const boost::posix_time::ptime& time, bool addAtTheTop) {
 	QString scaledAvatarPath = QtScaledAvatarCache(32).getScaledAvatarPath(avatarPath.c_str());
 
 	QString messageHTML(P2QSTRING(message));
@@ -104,7 +105,12 @@ void QtHistoryWindow::addMessage(const std::string &message, const std::string &
 
 	QString qAvatarPath =  scaledAvatarPath.isEmpty() ? "qrc:/icons/avatar.png" : QUrl::fromLocalFile(scaledAvatarPath).toEncoded();
 
-	conversation_->addMessageBottom(boost::shared_ptr<ChatSnippet>(new MessageSnippet(messageHTML, Qt::escape(P2QSTRING(senderName)), qTime, qAvatarPath, senderIsSelf, false, theme_, P2QSTRING(id))));
+	if (addAtTheTop) {
+		conversation_->addMessageTop(boost::shared_ptr<ChatSnippet>(new MessageSnippet(messageHTML, Qt::escape(P2QSTRING(senderName)), qTime, qAvatarPath, senderIsSelf, false, theme_, P2QSTRING(id))));
+	}
+	else {
+		conversation_->addMessageBottom(boost::shared_ptr<ChatSnippet>(new MessageSnippet(messageHTML, Qt::escape(P2QSTRING(senderName)), qTime, qAvatarPath, senderIsSelf, false, theme_, P2QSTRING(id))));
+	}
 
 	// keep track of the days viewable in the chatView
 	if (!dates_.count(date)) {
@@ -135,16 +141,21 @@ void QtHistoryWindow::handleScrollRequested(int pos) {
 		}
 	}
 
-	if (currentDate_ != currentDate) {
-		currentDate_ = currentDate;
-		ui_.calendarWidget_->setSelectedDate(currentDate_);
+	if (ui_.calendarWidget_->selectedDate() != currentDate) {
+		ui_.calendarWidget_->setSelectedDate(currentDate);
 	}
 }
 
 void QtHistoryWindow::handleScrollReachedTop() {
+	int year, month, day;
+	ui_.calendarWidget_->selectedDate().getDate(&year, &month, &day);
+	onScrollReachedTop(boost::gregorian::date(year, month, day));
 }
 
 void QtHistoryWindow::handleScrollReachedBottom() {
+	int year, month, day;
+	ui_.calendarWidget_->selectedDate().getDate(&year, &month, &day);
+	onScrollReachedBottom(boost::gregorian::date(year, month, day));
 }
 
 void QtHistoryWindow::handleReturnPressed() {
diff --git a/Swift/QtUI/QtHistoryWindow.h b/Swift/QtUI/QtHistoryWindow.h
index 9a887bf..97b9866 100644
--- a/Swift/QtUI/QtHistoryWindow.h
+++ b/Swift/QtUI/QtHistoryWindow.h
@@ -23,7 +23,7 @@ namespace Swift {
 			~QtHistoryWindow();
 			void activate();
 			void setRosterModel(Roster*);
-			void addMessage(const std::string &message, const std::string &senderName, bool senderIsSelf, const std::string& avatarPath, const boost::posix_time::ptime& time);
+			void addMessage(const std::string &message, const std::string &senderName, bool senderIsSelf, const std::string& avatarPath, const boost::posix_time::ptime& time, bool addAtTheTop);
 			void resetConversationView();
 
 			void closeEvent(QCloseEvent* event);
@@ -44,7 +44,6 @@ namespace Swift {
 			QtChatView* conversation_;
 			QtTreeWidget* conversationRoster_;
 			std::set<QDate> dates_;
-			QDate currentDate_;
 			int idCounter_;
 	};
 }
diff --git a/Swiften/Base/foreach.h b/Swiften/Base/foreach.h
index 87f6147..3ad506d 100644
--- a/Swiften/Base/foreach.h
+++ b/Swiften/Base/foreach.h
@@ -10,3 +10,4 @@
 
 #undef foreach
 #define foreach BOOST_FOREACH
+#define reverse_foreach BOOST_REVERSE_FOREACH
diff --git a/Swiften/History/HistoryManager.h b/Swiften/History/HistoryManager.h
index 908d35c..6b32206 100644
--- a/Swiften/History/HistoryManager.h
+++ b/Swiften/History/HistoryManager.h
@@ -22,7 +22,9 @@ namespace Swift {
 
 			virtual void addMessage(const HistoryMessage& message) = 0;
 
-			virtual std::vector<HistoryMessage> getMessages(const JID& selfJID, const JID& contactJID, HistoryMessage::Type type, const boost::gregorian::date& date) const = 0;
+			virtual std::vector<HistoryMessage> getMessagesFromDate(const JID& selfJID, const JID& contactJID, HistoryMessage::Type type, const boost::gregorian::date& date) const = 0;
+			virtual std::vector<HistoryMessage> getMessagesFromNextDate(const JID& selfJID, const JID& contactJID, HistoryMessage::Type type, const boost::gregorian::date& date) const = 0;
+			virtual std::vector<HistoryMessage> getMessagesFromPreviousDate(const JID& selfJID, const JID& contactJID, HistoryMessage::Type type, const boost::gregorian::date& date) const = 0;
 			virtual ContactsMap getContacts(const JID& selfJID, HistoryMessage::Type type, const std::string& keyword) const = 0;
 	};
 }
diff --git a/Swiften/History/SQLiteHistoryManager.cpp b/Swiften/History/SQLiteHistoryManager.cpp
index 7cddf43..57fce2f 100644
--- a/Swiften/History/SQLiteHistoryManager.cpp
+++ b/Swiften/History/SQLiteHistoryManager.cpp
@@ -9,7 +9,7 @@
 
 #include <sqlite3.h>
 #include <Swiften/History/SQLiteHistoryManager.h>
-#include <boost/date_time/gregorian/gregorian_types.hpp>
+#include <boost/date_time/gregorian/gregorian.hpp>
 
 inline std::string getEscapedString(const std::string& s) {
 	std::string result(s);
@@ -67,7 +67,7 @@ void SQLiteHistoryManager::addMessage(const HistoryMessage& message) {
 	}
 }
 
-std::vector<HistoryMessage> SQLiteHistoryManager::getMessages(const JID& selfJID, const JID& contactJID, HistoryMessage::Type type, const boost::gregorian::date& date) const {
+std::vector<HistoryMessage> SQLiteHistoryManager::getMessagesFromDate(const JID& selfJID, const JID& contactJID, HistoryMessage::Type type, const boost::gregorian::date& date) const {
 	sqlite3_stmt* selectStatement;
 
 	boost::optional<int> selfID = getIDFromJID(selfJID.toBare());
@@ -267,4 +267,72 @@ ContactsMap SQLiteHistoryManager::getContacts(const JID& selfJID, HistoryMessage
 	return result;
 }
 
+boost::gregorian::date SQLiteHistoryManager::getNextDateWithLogs(const JID& selfJID, const JID& contactJID, HistoryMessage::Type type, const boost::gregorian::date& date, bool reverseOrder) const {
+	sqlite3_stmt* selectStatement;
+	boost::optional<int> selfID = getIDFromJID(selfJID.toBare());
+	boost::optional<int> contactID = getIDFromJID(contactJID.toBare());
+
+	if (!selfID || !contactID) {
+		// JIDs missing from the database
+		return boost::gregorian::date(boost::gregorian::not_a_date_time);
+	}
+
+	std::string selectQuery = "SELECT time FROM messages WHERE (type=" + boost::lexical_cast<std::string>(type);
+	if (contactJID.isBare()) {
+		// match only bare jid
+		selectQuery += " AND ((fromBare=" + boost::lexical_cast<std::string>(*selfID) + " AND toBare=" +
+				boost::lexical_cast<std::string>(*contactID) + ") OR (fromBare=" +
+				boost::lexical_cast<std::string>(*contactID) + " AND toBare=" + boost::lexical_cast<std::string>(*selfID) + ")))";
+	}
+	else {
+		// match resource too
+		selectQuery += " AND ((fromBare=" + boost::lexical_cast<std::string>(*selfID) + " AND (toBare=" +
+				boost::lexical_cast<std::string>(*contactID) +" AND toResource='" +
+				getEscapedString(contactJID.getResource()) + "')) OR ((fromBare=" +
+				boost::lexical_cast<std::string>(*contactID) + " AND fromResource='" +
+				getEscapedString(contactJID.getResource()) + "') AND toBare=" +
+				boost::lexical_cast<std::string>(*selfID) + ")))";
+	}
+
+	int timeStamp = (boost::posix_time::ptime(date) - boost::posix_time::ptime(boost::gregorian::date(1970, 1, 1))).total_seconds() + (reverseOrder ? 0 : 86400);
+
+	selectQuery += " AND time" + (reverseOrder ? std::string("<") : std::string(">")) + boost::lexical_cast<std::string>(timeStamp);
+	selectQuery += " ORDER BY time " + (reverseOrder ? std::string("DESC") : std::string("ASC")) + " LIMIT 1";
+
+	int r = sqlite3_prepare(db_, selectQuery.c_str(), selectQuery.size(), &selectStatement, NULL);
+	if (r != SQLITE_OK) {
+		std::cout << "Error: " << sqlite3_errmsg(db_) << std::endl;
+	}
+
+	r = sqlite3_step(selectStatement);
+	if (r == SQLITE_ROW) {
+		int secondsSinceEpoch(sqlite3_column_int(selectStatement, 0));
+		boost::posix_time::ptime time(boost::gregorian::date(1970, 1, 1), boost::posix_time::seconds(secondsSinceEpoch));
+		std::cout << "next day is: " << time.date() << "\n";
+		return time.date();
+	}
+
+	return boost::gregorian::date(boost::gregorian::not_a_date_time);
+}
+
+std::vector<HistoryMessage> SQLiteHistoryManager::getMessagesFromNextDate(const JID& selfJID, const JID& contactJID, HistoryMessage::Type type, const boost::gregorian::date& date) const {
+	boost::gregorian::date nextDate = getNextDateWithLogs(selfJID, contactJID, type, date, false);
+
+	if (nextDate.is_not_a_date()) {
+		return std::vector<HistoryMessage>();
+	}
+
+	return getMessagesFromDate(selfJID, contactJID, type, nextDate);
+}
+
+std::vector<HistoryMessage> SQLiteHistoryManager::getMessagesFromPreviousDate(const JID& selfJID, const JID& contactJID, HistoryMessage::Type type, const boost::gregorian::date& date) const {
+	boost::gregorian::date previousDate = getNextDateWithLogs(selfJID, contactJID, type, date, true);
+
+	if (previousDate.is_not_a_date()) {
+		return std::vector<HistoryMessage>();
+	}
+
+	return getMessagesFromDate(selfJID, contactJID, type, previousDate);
+}
+
 }
diff --git a/Swiften/History/SQLiteHistoryManager.h b/Swiften/History/SQLiteHistoryManager.h
index 638d73f..8b08e6b 100644
--- a/Swiften/History/SQLiteHistoryManager.h
+++ b/Swiften/History/SQLiteHistoryManager.h
@@ -20,9 +20,12 @@ namespace Swift {
 
 			void addMessage(const HistoryMessage& message);
 			ContactsMap getContacts(const JID& selfJID, HistoryMessage::Type type, const std::string& keyword) const;
-			std::vector<HistoryMessage> getMessages(const JID& selfJID, const JID& contactJID, HistoryMessage::Type type, const boost::gregorian::date& date) const;
+			std::vector<HistoryMessage> getMessagesFromDate(const JID& selfJID, const JID& contactJID, HistoryMessage::Type type, const boost::gregorian::date& date) const;
+			std::vector<HistoryMessage> getMessagesFromNextDate(const JID& selfJID, const JID& contactJID, HistoryMessage::Type type, const boost::gregorian::date& date) const;
+			std::vector<HistoryMessage> getMessagesFromPreviousDate(const JID& selfJID, const JID& contactJID, HistoryMessage::Type type, const boost::gregorian::date& date) const;
 
 		private:
+			boost::gregorian::date getNextDateWithLogs(const JID& selfJID, const JID& contactJID, HistoryMessage::Type type, const boost::gregorian::date& date, bool reverseOrder) const;
 			int getIDForJID(const JID&);
 			int addJID(const JID&);
 
-- 
cgit v0.10.2-6-g49f6