Implemented FriendItemsHandler::dropOutOfGroupFriends()
[situare] / src / map / frienditemshandler.cpp
1 /*
2     Situare - A location system for Facebook
3     Copyright (C) 2010  Ixonos Plc. Authors:
4
5         Sami Rämö - sami.ramo@ixonos.com
6
7     Situare is free software; you can redistribute it and/or
8     modify it under the terms of the GNU General Public License
9     version 2 as published by the Free Software Foundation.
10
11     Situare is distributed in the hope that it will be useful,
12     but WITHOUT ANY WARRANTY; without even the implied warranty of
13     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14     GNU General Public License for more details.
15
16     You should have received a copy of the GNU General Public License
17     along with Situare; if not, write to the Free Software
18     Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301,
19     USA.
20 */
21
22
23 #include <QDebug>
24
25 #include "friendgroupitem.h"
26 #include "friendlocationitem.h"
27 #include "mapengine.h"
28 #include "mapscene.h"
29 #include "user/user.h"
30
31 #include "frienditemshandler.h"
32
33 FriendItemsHandler::FriendItemsHandler(MapScene *mapScene, QObject *parent)
34     : QObject(parent),
35       m_mapScene(mapScene)
36 {
37 }
38
39 FriendItemsHandler::~FriendItemsHandler()
40 {
41     qDeleteAll(m_friendItems.begin(),m_friendItems.end());
42     m_friendItems.clear();
43 }
44
45 void FriendItemsHandler::checkFriendsForCollisions()
46 {
47     qWarning() << __PRETTY_FUNCTION__;
48
49 //    foreach(FriendGroupItem *item, m_friendGroupItems) {
50 //        m_friendGroupItems.removeAll(item);
51 //        m_mapScene->removeItem(item);
52 //    }
53
54     int lastItem = m_friendItems.size() - 1;
55     for (int checking = 0; checking <= lastItem; checking++) {
56         QRect beginItemRect = m_friendItems.at(checking)->sceneTransformedBoundingRect(m_zoomLevel);
57
58         // don't check items which are already part of a group (and thus unvisible)
59         if (m_friendItems.at(checking)->isPartOfGroup())
60             continue;
61
62         // check all other items
63         for (int another = 0; another <= lastItem; another++)
64         {
65             // don't check against itself
66             if (checking == another)
67                 continue;
68
69             // don't check against items which are already part of a group (and thus unvisible)
70             if (m_friendItems.at(another)->isPartOfGroup())
71                 continue;
72
73             // does items collide
74             QRect iterItemRect = m_friendItems.at(another)->sceneTransformedBoundingRect(m_zoomLevel);
75             if (beginItemRect.intersects(iterItemRect)) {
76                 qWarning() << __PRETTY_FUNCTION__ << "collision found" << checking << another;
77                 FriendGroupItem *group = new FriendGroupItem();
78                 m_friendGroupItems.append(group);
79                 group->setPos(m_friendItems.at(checking)->pos());
80                 group->joinFriend(m_friendItems.at(checking));
81                 group->joinFriend(m_friendItems.at(another));
82                 m_mapScene->addItem(group);
83                 break;
84             }
85         }
86     }
87 }
88
89 void FriendItemsHandler::checkGroupsForCollisions()
90 {
91
92 }
93
94 void FriendItemsHandler::cleanOldFriendData(const QList<User *> &friendsList)
95 {
96     bool friendGone = true;
97
98     for (int i=0; i<m_friendItems.count(); i++) {
99
100         for (int j=0; j<friendsList.count(); j++) {
101
102             if (m_friendItems.at(i)->userId() == friendsList.at(j)->userId())
103                 friendGone = false;
104         }
105
106         if (friendGone) {
107             m_mapScene->removeItem(m_friendItems.at(i));
108             m_friendItems.removeAt(i);
109         }
110
111         friendGone = true;
112     }
113 }
114
115 void FriendItemsHandler::dropOutOfGroupFriends()
116 {
117     // loop through all group items and drop friends which doesn't collide anymore
118     foreach (FriendGroupItem *group, m_friendGroupItems)
119         group->dropFriends(m_zoomLevel);
120 }
121
122 void FriendItemsHandler::receiveFriendLocations(QList<User *> &friendsList)
123 {
124     qWarning() << __PRETTY_FUNCTION__;
125
126     static int receiveFriendsLocationsCounter = 0;
127
128     if (receiveFriendsLocationsCounter == 0) {
129         receiveFriendsLocationsCounter++;
130         updateFriendItemList(friendsList);
131     }
132
133     else {
134         /// @todo VILLE: New friends are never added to list & scene
135         receiveFriendsLocationsCounter++;
136         updateFriendLocationsAndImages(friendsList);
137         cleanOldFriendData(friendsList);
138     }
139 }
140
141 void FriendItemsHandler::refactorFriendItems(int zoomLevel)
142 {
143     m_zoomLevel = zoomLevel;
144
145     dropOutOfGroupFriends();
146     checkGroupsForCollisions();
147     checkFriendsForCollisions();
148 }
149
150 void FriendItemsHandler::updateFriendItemList(const QList<User *> &friendsList)
151 {
152     qDebug() << __PRETTY_FUNCTION__;
153
154     qDeleteAll(m_friendItems.begin(),m_friendItems.end());
155     m_friendItems.clear();
156
157
158     for (int i=0; i<friendsList.count(); i++) {
159         FriendLocationItem *friendLocation
160                 = new FriendLocationItem(friendsList.at(i)->profileImage(),
161                                          friendsList.at(i)->coordinates(),0);
162
163         friendLocation->setUserId(friendsList.at(i)->userId());
164         m_friendItems.append(friendLocation);
165         m_mapScene->addItem(friendLocation);
166
167         //refactorFriendItems(m_zoomLevel);
168     }
169 }
170
171 void FriendItemsHandler::updateFriendLocationsAndImages(const QList<User *> &friendsList)
172 {
173     for (int i=0; i<friendsList.count(); i++) {
174
175         for (int j=0; j<m_friendItems.count(); j++) {
176
177             if (m_friendItems.at(j)->userId() == friendsList.at(i)->userId()) {
178
179                 if (m_friendItems.at(j)->position()
180                     != MapEngine::convertLatLonToSceneCoordinate(friendsList.at(i)->coordinates()))
181                     m_friendItems.at(j)->setPosition(friendsList.at(i)->coordinates());
182
183                 if (m_friendItems.at(j)->profileImageUrl()
184                     != friendsList.at(i)->profileImageUrl()) {
185                     m_friendItems.at(j)->setPixmap(friendsList.at(i)->profileImage());
186                 }
187             }
188         }
189     }
190 }
191
192