Tizen C++ Coding Rules
[platform/core/location/maps-plugin-here.git] / src / here_place.cpp
1 /*
2  * Copyright (c) 2014 Samsung Electronics Co., Ltd All Rights Reserved
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16
17 #include "here_place.h"
18
19 HERE_PLUGIN_BEGIN_NAMESPACE
20
21 HerePlace::HerePlace(void *pCbFunc, void *pUserData, int nReqId)
22 {
23         m_pDiscoveryQuery = NULL;
24         m_pPlaceDetailsQuery = NULL;
25
26         m_pCbFunc = pCbFunc;
27         m_pUserData = pUserData;
28         m_nReqId = nReqId;
29
30         m_nReplyCnt = 0;
31         m_nReplyIdx = 0;
32         m_bReplyFlushed = false;
33         m_szSortBy = NULL;
34         m_bPlaceDetails = false;
35         m_bPlaceDetailsInternal = false;
36         m_bReplyWithList = false;
37         m_eDistanceUnit = MAPS_DISTANCE_UNIT_M;
38 }
39
40 HerePlace::~HerePlace()
41 {
42         if (m_pDiscoveryQuery) {
43                 delete m_pDiscoveryQuery;
44                 m_pDiscoveryQuery = NULL;
45         }
46
47         if (m_pPlaceDetailsQuery) {
48                 delete m_pPlaceDetailsQuery;
49                 m_pPlaceDetailsQuery = NULL;
50         }
51
52         while (!m_PlaceList.empty()) {
53                 maps_place_destroy(m_PlaceList.front());
54                 m_PlaceList.pop_front();
55         }
56 }
57
58 here_error_e HerePlace::PrepareDiscoveryQuery()
59 {
60         if (m_pDiscoveryQuery)
61                 return HERE_ERROR_PERMISSION_DENIED;
62
63          m_pDiscoveryQuery = new (std::nothrow) DiscoveryQuery();
64
65         if (!m_pDiscoveryQuery)
66                 return HERE_ERROR_OUT_OF_MEMORY;
67         else
68                 return HERE_ERROR_NONE;
69 }
70
71 here_error_e HerePlace::PrepareDiscoveryPreference(maps_preference_h hPref)
72 {
73         if (!m_pDiscoveryQuery)
74                 return HERE_ERROR_OUT_OF_MEMORY;
75
76         if (!hPref)
77                 return HERE_ERROR_NONE;
78
79
80         int ret;
81         char *szLanguage = NULL;
82         ret = maps_preference_get_language(hPref, &szLanguage);
83         if (ret == MAPS_ERROR_NONE && szLanguage && *szLanguage)
84                 m_pDiscoveryQuery->SetLanguage(szLanguage);
85         g_free(szLanguage);
86
87         int nMaxResults;
88         ret = maps_preference_get_max_results(hPref, &nMaxResults);
89         if (ret == MAPS_ERROR_NONE)
90                 m_pDiscoveryQuery->SetMaxResults((size_t)nMaxResults);
91
92         maps_distance_unit_e eUnit;
93         ret = maps_preference_get_distance_unit(hPref, &eUnit);
94         if (ret == MAPS_ERROR_NONE)
95                 m_eDistanceUnit = eUnit;
96
97         char *szSortBy;
98         ret = maps_preference_get(hPref, MAPS_PLACE_FILTER_SORT_BY, &szSortBy);
99         if (ret == MAPS_ERROR_NONE)
100                 m_szSortBy = szSortBy;
101
102         return HERE_ERROR_NONE;
103 }
104
105 here_error_e HerePlace::PrepareDiscoveryFilter(maps_place_filter_h hFilter)
106 {
107         if (!m_pDiscoveryQuery)
108                 return HERE_ERROR_OUT_OF_MEMORY;
109
110         if (!hFilter)
111                 return HERE_ERROR_INVALID_PARAMETER;
112
113         int ret;
114         maps_place_category_h mapsCate = NULL;
115         if (maps_place_filter_get_category(hFilter, &mapsCate) == MAPS_ERROR_NONE) {
116                 CategoryList hereCateList;
117                 Category hereCate;
118                 char *szId = NULL, *szName = NULL, *szUrl = NULL;
119
120                 ret = maps_place_category_get_name(mapsCate, &szName);
121                 if (ret == MAPS_ERROR_NONE && szName && *szName)
122                         hereCate.SetTitle(szName);
123                 g_free(szName);
124
125                 ret = maps_place_category_get_url(mapsCate, &szUrl);
126                 if (ret == MAPS_ERROR_NONE && szUrl && *szUrl)
127                         hereCate.SetHref(szUrl);
128                 g_free(szUrl);
129
130                 ret = maps_place_category_get_id(mapsCate, &szId);
131                 if (ret == MAPS_ERROR_NONE && szId && *szId) {
132                         hereCate.SetCategoryId(CategoryId(szId));
133                 } else if (hereCate.GetTitle().size() > 0) {
134                         hereCate.SetCategoryId(CategoryId(hereCate.GetTitle()));
135                         hereCate.SetTitle("");
136                 }
137                 g_free(szId);
138
139                 hereCateList.push_back(hereCate);
140                 m_pDiscoveryQuery->SetCategoriesFilter(hereCateList);
141                 maps_place_category_destroy(mapsCate);
142         }
143
144         char *szName = NULL;
145         ret = maps_place_filter_get_place_name(hFilter, &szName);
146         if (ret == MAPS_ERROR_NONE && szName && *szName)
147                 m_pDiscoveryQuery->SetSearchText(szName);
148         g_free(szName);
149
150         char *szKeyword = NULL;
151         ret = maps_place_filter_get_keyword(hFilter, &szKeyword);
152         if (ret == MAPS_ERROR_NONE && szKeyword && *szKeyword) {
153                 String szSearchText = m_pDiscoveryQuery->GetSearchText();
154                 if (szSearchText.size() > 0) szSearchText += " ";
155                 szSearchText += szKeyword;
156                 m_pDiscoveryQuery->SetSearchText(szSearchText);
157         }
158         g_free(szKeyword);
159
160         char *szAddress = NULL;
161         ret = maps_place_filter_get_place_address(hFilter, &szAddress);
162         if (ret == MAPS_ERROR_NONE && szAddress && *szAddress) {
163                 String szSearchText = szAddress;
164                 if (m_pDiscoveryQuery->GetSearchText().size() > 0)
165                         szSearchText += " " + m_pDiscoveryQuery->GetSearchText();
166                 m_pDiscoveryQuery->SetSearchText(szSearchText);
167         }
168         g_free(szAddress);
169
170         return HERE_ERROR_NONE;
171 }
172
173 here_error_e HerePlace::StartDiscoveryPlace(maps_coordinates_h hCoord, int nDistance)
174 {
175         if (!hCoord || nDistance < 0)
176                 return HERE_ERROR_INVALID_PARAMETER;
177
178         int meters = (int)(HereUtils::ConvertDistance(nDistance, m_eDistanceUnit, MAPS_DISTANCE_UNIT_M) + 0.5);
179         maps_area_h area = NULL;
180         maps_area_create_circle(hCoord, meters, &area);
181         here_error_e error = StartDiscoveryPlace(area);
182         maps_area_destroy(area);
183         return error;
184 }
185
186 here_error_e HerePlace::StartDiscoveryPlace(maps_area_h hArea, const char *szAddr)
187 {
188         if (!hArea)
189                 return HERE_ERROR_INVALID_PARAMETER;
190
191         if (!m_pDiscoveryQuery)
192                 return HERE_ERROR_OUT_OF_MEMORY;
193
194
195         typedef enum {
196                 PLACE_CMD_TEXT,
197                 PLACE_CMD_CENTER,
198                 PLACE_CMD_AREA,
199         } PlaceCmdType;
200
201         PlaceCmdType cmdType;
202         maps_area_s *pArea = (maps_area_s*)hArea;
203         GeoCoordinates geoCoord;
204         GeoBoundingArea *geoArea = NULL;
205         GeoBoundingBox geoBox;
206         GeoBoundingCircle geoCircle;
207
208         /* Merge search text with other search text being in preference */
209         String szSearchText = (szAddr ? szAddr : "");
210         if (m_pDiscoveryQuery->GetSearchText().size() > 0) {
211                 if (szSearchText.size() > 0) szSearchText += " ";
212                 szSearchText += m_pDiscoveryQuery->GetSearchText();
213         }
214         m_pDiscoveryQuery->SetSearchText(szSearchText);
215
216         /* Decide command type */
217         if (!szSearchText.empty()) {
218                 cmdType = PLACE_CMD_TEXT;
219         } else if (pArea->type == MAPS_AREA_CIRCLE && pArea->circle.radius == 0) {
220                 cmdType = PLACE_CMD_CENTER;
221         } else {
222                 cmdType = PLACE_CMD_AREA;
223         }
224
225         /* Get proximity with area */
226         if (cmdType == PLACE_CMD_TEXT || cmdType == PLACE_CMD_CENTER) {
227                 if (pArea->type == MAPS_AREA_RECTANGLE) {
228                         double dLat1 = pArea->rect.top_left.latitude;
229                         double dLng1 = pArea->rect.top_left.longitude;
230                         double dLat2 = pArea->rect.bottom_right.latitude;
231                         double dLng2 = pArea->rect.bottom_right.longitude;
232                         double dLat = (dLat1 + dLat2) / 2;
233                         double dLng = (dLng1 + dLng2) / 2;
234
235                         geoCoord.SetLatitude(dLat);
236                         geoCoord.SetLongitude(dLng);
237                 } else if (pArea->type == MAPS_AREA_CIRCLE) {
238                         double dLat = pArea->circle.center.latitude;
239                         double dLng = pArea->circle.center.longitude;
240
241                         geoCoord.SetLatitude(dLat);
242                         geoCoord.SetLongitude(dLng);
243                 } else {
244                         return HERE_ERROR_INVALID_PARAMETER;
245                 }
246         } else if (cmdType == PLACE_CMD_AREA) {
247                 if (pArea->type == MAPS_AREA_RECTANGLE) {
248                         HereUtils::Convert(hArea, geoBox);
249                         geoArea = &geoBox;
250                 } else if (pArea->type == MAPS_AREA_CIRCLE) {
251                         HereUtils::Convert(hArea, geoCircle);
252                         geoArea = &geoCircle;
253                 } else {
254                         return HERE_ERROR_INVALID_PARAMETER;
255                 }
256         }
257
258         /* Set properties */
259         if (cmdType == PLACE_CMD_TEXT) {
260                 m_pDiscoveryQuery->SetType(DiscoveryQuery::QT_SEARCH);
261                 m_pDiscoveryQuery->SetProximity(geoCoord);
262         } else if (cmdType == PLACE_CMD_CENTER) {
263                 m_pDiscoveryQuery->SetType(DiscoveryQuery::QT_EXPLORE);
264                 m_pDiscoveryQuery->SetProximity(geoCoord);
265         } else {
266                 m_pDiscoveryQuery->SetType(DiscoveryQuery::QT_EXPLORE);
267                 if (geoArea)
268                         m_pDiscoveryQuery->SetArea(*geoArea);
269         }
270
271         /* Execute query */
272         m_nRestReqId = m_pDiscoveryQuery->Execute(*this, NULL);
273
274         return (m_nRestReqId > 0 ? HERE_ERROR_NONE : HERE_ERROR_INVALID_OPERATION);
275 }
276
277 here_error_e HerePlace::StartDiscoveryPlaceList(maps_area_h hArea)
278 {
279         m_bReplyWithList = true;
280         return StartDiscoveryPlace(hArea);
281 }
282
283 here_error_e HerePlace::PreparePlaceDetailsQuery()
284 {
285         if (m_pPlaceDetailsQuery)
286                 return HERE_ERROR_PERMISSION_DENIED;
287
288         m_pPlaceDetailsQuery = new (std::nothrow) PlaceDetailsQuery();
289
290         if (!m_pPlaceDetailsQuery)
291                 return HERE_ERROR_OUT_OF_MEMORY;
292         else
293                 return HERE_ERROR_NONE;
294 }
295
296 here_error_e HerePlace::PreparePlaceDetailsPreference(maps_preference_h hPref)
297 {
298         if (!m_pPlaceDetailsQuery)
299                 return HERE_ERROR_OUT_OF_MEMORY;
300
301         if (!hPref)
302                 return HERE_ERROR_NONE;
303
304         int ret;
305         char *szLanguage = NULL;
306         ret = maps_preference_get_language(hPref, &szLanguage);
307         if (ret == MAPS_ERROR_NONE && szLanguage && *szLanguage)
308                 m_pPlaceDetailsQuery->SetLanguage(szLanguage);
309         g_free(szLanguage);
310
311         maps_distance_unit_e eUnit;
312         ret = maps_preference_get_distance_unit(hPref, &eUnit);
313         if (ret == MAPS_ERROR_NONE)
314                 m_eDistanceUnit = eUnit;
315
316         return HERE_ERROR_NONE;
317 }
318
319 here_error_e HerePlace::StartPlaceDetails(const char *szUrl)
320 {
321         if (!m_pPlaceDetailsQuery)
322                 return HERE_ERROR_OUT_OF_MEMORY;
323
324         if (!szUrl || (szUrl && strlen(szUrl) <= 0))
325                 return HERE_ERROR_INVALID_PARAMETER;
326
327         m_bPlaceDetails = true;
328
329         m_nRestReqId = m_pPlaceDetailsQuery->Execute(*this, NULL, szUrl);
330
331         return (m_nRestReqId > 0 ? HERE_ERROR_NONE : HERE_ERROR_INVALID_OPERATION);
332 }
333
334 here_error_e HerePlace::StartPlaceDetailsInternal(const char *szUrl)
335 {
336         if (!szUrl || (szUrl && strlen(szUrl) <= 0))
337                 return HERE_ERROR_INVALID_PARAMETER;
338
339         std::unique_ptr<PlaceDetailsQuery> pPlaceDetailsQuery (new (std::nothrow)PlaceDetailsQuery());
340
341         m_bPlaceDetailsInternal = true;
342         bool bExcuted = (int)(pPlaceDetailsQuery->Execute(*this, NULL, szUrl) > 0);
343
344         return (bExcuted ? HERE_ERROR_NONE : HERE_ERROR_INVALID_OPERATION);
345 }
346
347 void HerePlace::OnDiscoverReply(const DiscoveryReply &Reply)
348 {
349         maps_place_h mapsPlace;
350         PlaceItemList herePlaceList = Reply.GetPlaceItems();
351         PlaceItemList::iterator herePlaceIt;
352         SearchItemList hereSearchList = Reply.GetSearchItems();
353         SearchItemList::iterator hereSearchIt;
354         LinkObject hereLinkObj;
355         GeoCoordinates hereCoord;
356         maps_coordinates_h mapsCoord;
357         Category hereCate;
358         maps_place_category_h mapsCate;
359         maps_place_rating_h mapsRating;
360         int error = MAPS_ERROR_UNKNOWN, sub_error;
361         bool is_valid, isPending;
362
363         if (m_bCanceled || !m_pCbFunc) {
364                 delete this;
365                 return;
366         }
367
368         m_nReplyIdx = 0;
369         m_nReplyCnt = herePlaceList.size() + hereSearchList.size();
370
371         for (herePlaceIt = herePlaceList.begin();
372                 herePlaceIt != herePlaceList.end();
373                 herePlaceIt++) {
374                 if ((error = maps_place_create(&mapsPlace)) == MAPS_ERROR_NONE) {
375                         isPending = false;
376
377                         /* title, uri, id */
378                         hereLinkObj = herePlaceIt->GetLinkObject();
379
380                         if (!hereLinkObj.GetTitle().empty())
381                                 maps_place_set_name(mapsPlace, (char*)hereLinkObj.GetTitle().c_str());
382
383                         if (!hereLinkObj.GetHref().empty())
384                                 maps_place_set_uri(mapsPlace, (char*)hereLinkObj.GetHref().c_str());
385
386                         if (!hereLinkObj.GetId().empty())
387                                 maps_place_set_id(mapsPlace, (char*)hereLinkObj.GetId().c_str());
388
389                         /* icon */
390                         /* type */
391
392                         /* position */
393                         hereCoord = herePlaceIt->GetPosition();
394                         if (maps_coordinates_create(hereCoord.GetLatitude(), hereCoord.GetLongitude(),
395                                 &mapsCoord) == MAPS_ERROR_NONE) {
396                                 maps_place_set_location(mapsPlace, mapsCoord);
397                                 maps_coordinates_destroy(mapsCoord);
398                         }
399
400                         /* rating (optional) */
401                         if (maps_place_rating_create(&mapsRating) == MAPS_ERROR_NONE) {
402                                 maps_place_rating_set_average(mapsRating, herePlaceIt->GetAverageRating());
403                                 maps_place_set_rating(mapsPlace, mapsRating);
404                                 maps_place_rating_destroy(mapsRating);
405                         }
406
407                         /* category (optional) */
408                         hereCate = herePlaceIt->GetCategory();
409
410                         maps_item_list_h mapsCateList;
411                         if (maps_item_list_create(&mapsCateList) == MAPS_ERROR_NONE) {
412                                 if (maps_place_category_create(&mapsCate) == MAPS_ERROR_NONE) {
413                                         is_valid = false;
414
415                                         if (!hereCate.GetCategoryId().ToString().empty()) {
416                                                 sub_error = maps_place_category_set_id(mapsCate,
417                                                                 (char*)hereCate.GetCategoryId().ToString().c_str());
418                                                 is_valid |= (sub_error == MAPS_ERROR_NONE);
419                                         }
420
421                                         if (!hereCate.GetTitle().empty()) {
422                                                 sub_error = maps_place_category_set_name(mapsCate,
423                                                                 (char*)hereCate.GetTitle().c_str());
424                                                 is_valid |= (sub_error == MAPS_ERROR_NONE);
425                                         }
426
427                                         if (!hereCate.GetHref().empty()) {
428                                                 sub_error = maps_place_category_set_url(mapsCate,
429                                                                 (char*)hereCate.GetHref().c_str());
430                                                 is_valid |= (sub_error == MAPS_ERROR_NONE);
431                                         }
432
433                                         if (is_valid) {
434                                                 maps_item_list_append(mapsCateList, mapsCate, maps_place_category_clone);
435                                                 maps_place_set_categories(mapsPlace, mapsCateList);
436                                                 maps_item_list_remove_all(mapsCateList, maps_place_category_destroy);
437                                         }
438                                         maps_place_category_destroy(mapsCate);
439                                 }
440                                 maps_item_list_destroy(mapsCateList);
441                         }
442
443                         /* distance */
444                         maps_place_set_distance(mapsPlace,
445                                 HereUtils::ConvertDistance((int)herePlaceIt->GetDistance(), m_eDistanceUnit) + 0.5);
446
447                         /* sponser */
448                         /* herePlaceList.GetIsSponsored() */
449
450                         /* vicinity */
451
452                         /* If needed PlaceDetails information, postpone to send a reply */
453                         if(__sending_place_details_query_automatically && !m_bReplyWithList) {
454                                 hereLinkObj = herePlaceIt->GetLinkObject();
455                                 if (!hereLinkObj.GetHref().empty() && !hereLinkObj.GetId().empty()) {
456                                         if (StartPlaceDetailsInternal(hereLinkObj.GetHref().c_str()) == HERE_ERROR_NONE) {
457                                                 m_PlaceList.push_back(mapsPlace);
458                                                 isPending = true;
459                                                 MAPS_LOGD("Add maps_place_h to the pending list. id=%s", hereLinkObj.GetId().data());
460                                         }
461                                 }
462                         }
463
464                         if (!isPending) {
465                                 m_nReplyIdx++;
466                                 m_PlaceList.push_back(mapsPlace);
467                         }
468                 } else {
469                         m_nReplyCnt--;
470                 }
471         }
472
473         for (hereSearchIt = hereSearchList.begin();
474                 hereSearchIt != hereSearchList.end();
475                 hereSearchIt++) {
476                 error = maps_place_create(&mapsPlace);
477
478                 if(error == MAPS_ERROR_NONE) {
479                         is_valid = false;
480
481                         // title, uri, szId
482                         hereLinkObj = hereSearchIt->GetLinkObject();
483
484                         if (!hereLinkObj.GetTitle().empty()) {
485                                 sub_error = maps_place_set_name(mapsPlace,
486                                                 (char*)hereLinkObj.GetTitle().c_str());
487                                 is_valid |= (sub_error == MAPS_ERROR_NONE);
488                         }
489
490                         if (!hereLinkObj.GetHref().empty()) {
491                                 sub_error = maps_place_set_uri(mapsPlace,
492                                                 (char*)hereLinkObj.GetHref().c_str());
493                                 is_valid |= (sub_error == MAPS_ERROR_NONE);
494                         }
495
496                         if (!hereLinkObj.GetId().empty()) {
497                                 sub_error = maps_place_set_id(mapsPlace,
498                                                 (char*)hereLinkObj.GetId().c_str());
499                                 is_valid |= (sub_error == MAPS_ERROR_NONE);
500                         }
501                         /* icon */
502                         /* type */
503
504                         if (!is_valid) {
505                                 m_nReplyCnt--;
506                                 error = MAPS_ERROR_NOT_FOUND;
507                                 maps_place_destroy(mapsPlace);
508                                 mapsPlace = NULL;
509                         } else {
510                                 m_PlaceList.push_back(mapsPlace);
511                                 m_nReplyIdx++;
512                         }
513                 } else {
514                         m_nReplyCnt--;
515                 }
516         }
517
518
519         if (!m_bReplyFlushed && (m_nReplyCnt == 0 || m_nReplyIdx == m_nReplyCnt)) {
520                 if (m_nReplyCnt == 0)
521                         error = MAPS_ERROR_NOT_FOUND;
522
523                 __flushReplies(error);
524                 delete this;
525         }
526 }
527
528 void HerePlace::OnDiscoverFailure(const DiscoveryReply& Reply)
529 {
530         if (!m_bReplyFlushed) {
531                 m_nReplyIdx = 0;
532                 m_nReplyCnt = 0;
533                 __flushReplies((maps_error_e)GetErrorCode(Reply));
534                 delete this;
535         }
536 }
537
538 void HerePlace::OnPlaceDetailsReply(const PlaceDetailsReply &Reply)
539 {
540         if (m_nReplyCnt == 0) {
541                 if (m_bCanceled || !m_pCbFunc) {
542                         delete this;
543                         return;
544                 }
545                 m_nReplyCnt = 1;
546         }
547
548         PlaceDetails herePlace = Reply.GetPlaceDetails();
549         maps_place_h mapsPlace = NULL;
550         int error = MAPS_ERROR_NONE, sub_error;
551         bool is_valid, isPending = false;
552         char *placeId;
553         int placeIdLen;
554
555         /* Finding maps_place_h which is already pending since DiscoverReply */
556         PlaceList::iterator it;
557         for (it = m_PlaceList.begin(); it != m_PlaceList.end(); it++) {
558                 if (maps_place_get_id(*it, &placeId) == MAPS_ERROR_NONE) {
559                         placeIdLen = strlen(placeId);
560                         if(!herePlace.GetPlaceId().compare(0, placeIdLen, placeId)) {
561                                 mapsPlace = *it;
562                                 isPending = true;
563                                 MAPS_LOGD("Found maps_place_h in the pending list. id=%s", placeId);
564                                 g_free(placeId);
565                                 break;
566                         }
567                 }
568                 g_free(placeId);
569         }
570
571         /* If not found, create new handle */
572         if (!mapsPlace)
573                 error = maps_place_create(&mapsPlace);
574
575         if (error == MAPS_ERROR_NONE) {
576                 is_valid = false;
577
578                 /* name */
579                 if (!herePlace.GetName().empty()) {
580                         sub_error = maps_place_set_name(mapsPlace, (char*)herePlace.GetName().c_str());
581                         is_valid |= (sub_error == MAPS_ERROR_NONE);
582                 }
583
584                 /* id */
585                 if (!herePlace.GetPlaceId().empty()) {
586                         sub_error = maps_place_set_id(mapsPlace, (char*)herePlace.GetPlaceId().c_str());
587                         is_valid |= (sub_error == MAPS_ERROR_NONE);
588                 }
589
590                 /* view */
591                 if (!herePlace.GetView().empty()) {
592                         sub_error = maps_place_set_uri(mapsPlace, (char*)herePlace.GetView().c_str());
593                         is_valid |= (sub_error == MAPS_ERROR_NONE);
594                 }
595
596                 if (is_valid) {
597                         /* icon */
598                         /* maps not supported // herePlace.GetIconPath(); */
599
600                         /* location */
601                         ProcessPlaceLocation(herePlace, mapsPlace);
602
603                         ProcessPlaceContact(herePlace, mapsPlace);
604
605                         ProcessPlaceCategory(herePlace, mapsPlace);
606
607                         /* tags */
608                         /* maps & here not supported */
609
610                         ProcessPlaceImage(herePlace, mapsPlace);
611
612                         ProcessPlaceDetails(herePlace, mapsPlace);
613
614                         ProcessPlaceReviews(herePlace, mapsPlace);
615
616                         ProcessPlaceRatings(herePlace, mapsPlace);
617
618                         ProcessPlaceRated(herePlace, mapsPlace);
619
620                         if (!isPending)
621                                 m_PlaceList.push_back(mapsPlace);
622
623                         m_nReplyIdx++;
624                 } else {
625                         m_nReplyCnt--;
626                         error = MAPS_ERROR_NOT_FOUND;
627                         maps_place_destroy(mapsPlace);
628                         mapsPlace = NULL;
629                 }
630         } else {
631                 m_nReplyCnt--;
632         }
633
634         if (!m_bReplyFlushed && (m_nReplyCnt == 0 || m_nReplyIdx == m_nReplyCnt)) {
635                 if (m_nReplyCnt == 0)
636                         error = MAPS_ERROR_NOT_FOUND;
637
638                 __flushReplies(error);
639                 delete this;
640         }
641 }
642
643 void HerePlace::OnPlaceDetailsFailure(const PlaceDetailsReply& Reply)
644 {
645         if (!m_bPlaceDetailsInternal) {
646                 if (!m_bReplyFlushed) {
647                         m_nReplyIdx = 0;
648                         m_nReplyCnt = 0;
649                         __flushReplies(GetErrorCode(Reply));
650                         delete this;
651                 }
652         } else {
653                 m_nReplyIdx++;
654                 MAPS_LOGD("Internal error during updating detailed information for the place. (%d/%d)", m_nReplyIdx, m_nReplyCnt);
655                 if (!m_bReplyFlushed && (m_nReplyIdx == m_nReplyCnt))
656                 {
657                         __flushReplies(MAPS_ERROR_NONE);
658                         delete this;
659                 }
660         }
661 }
662
663 void HerePlace::ProcessPlaceLocation(PlaceDetails herePlace, maps_place_h mapsPlace)
664 {
665         GeoLocation hereLocation = herePlace.GetLocation();
666
667         /* position */
668         GeoCoordinates hereCoord = hereLocation.GetDisplayPosition();
669         maps_coordinates_h mapsCoord;
670
671         if (maps_coordinates_create(hereCoord.GetLatitude(),
672                 hereCoord.GetLongitude(), &mapsCoord) == MAPS_ERROR_NONE) {
673                 maps_place_set_location(mapsPlace, mapsCoord);
674                 maps_coordinates_destroy(mapsCoord);
675         }
676
677         /* address */
678         Address hereAddr = hereLocation.GetAddress();
679         maps_address_h mapsAddr;
680         int error;
681         bool is_valid;
682
683         if (maps_address_create(&mapsAddr) == MAPS_ERROR_NONE) {
684                 is_valid = false;
685
686                 if (!hereAddr.GetHouseNumber().empty()) {
687                         error = maps_address_set_building_number(mapsAddr,
688                                         hereAddr.GetHouseNumber().c_str());
689                         is_valid |= (error == MAPS_ERROR_NONE);
690                 }
691
692                 if (!hereAddr.GetStreet().empty()) {
693                         error = maps_address_set_street(mapsAddr, hereAddr.GetStreet().c_str());
694                         is_valid |= (error == MAPS_ERROR_NONE);
695                 }
696
697                 if (!hereAddr.GetDistrict().empty()) {
698                         error = maps_address_set_district(mapsAddr, hereAddr.GetDistrict().c_str());
699                         is_valid |= (error == MAPS_ERROR_NONE);
700                 }
701
702                 if (!hereAddr.GetCity().empty()) {
703                         error = maps_address_set_city(mapsAddr, hereAddr.GetCity().c_str());
704                         is_valid |= (error == MAPS_ERROR_NONE);
705                 }
706
707                 if (!hereAddr.GetState().empty()) {
708                         error = maps_address_set_state(mapsAddr, hereAddr.GetState().c_str());
709                         is_valid |= (error == MAPS_ERROR_NONE);
710                 }
711
712                 if (!hereAddr.GetCountry().empty()) {
713                         error = maps_address_set_country(mapsAddr, hereAddr.GetCountry().c_str());
714                         is_valid |= (error == MAPS_ERROR_NONE);
715                 }
716
717                 if (!hereAddr.GetCountryCode().empty()) {
718                         error = maps_address_set_country_code(mapsAddr, hereAddr.GetCountryCode().c_str());
719                         is_valid |= (error == MAPS_ERROR_NONE);
720                 }
721
722                 if (!hereAddr.GetCounty().empty()) {
723                         error = maps_address_set_county(mapsAddr, hereAddr.GetCounty().c_str());
724                         is_valid |= (error == MAPS_ERROR_NONE);
725                 }
726
727                 if (!hereAddr.GetPostalCode().empty()) {
728                         error = maps_address_set_postal_code(mapsAddr, hereAddr.GetPostalCode().c_str());
729                         is_valid |= (error == MAPS_ERROR_NONE);
730                 }
731
732                 if (!hereAddr.GetLabel().empty()) {
733                         error = maps_address_set_freetext(mapsAddr, hereAddr.GetLabel().c_str());
734                         is_valid |= (error == MAPS_ERROR_NONE);
735                 }
736
737                 if (is_valid)
738                         maps_place_set_address(mapsPlace, mapsAddr);
739
740                 maps_address_destroy(mapsAddr);
741         }
742 }
743
744
745 void HerePlace::ProcessPlaceContact(PlaceDetails herePlace, maps_place_h mapsPlace)
746 {
747         /* contact */
748         ContactDetailsList hereContList = herePlace.GetContactDetails();
749         ContactDetailsList::iterator hereCont;
750         maps_item_list_h mapsContList;
751         maps_place_contact_h mapsCont;
752         int error;
753         bool is_valid;
754
755         if (hereContList.empty()) return;
756
757         if (maps_item_list_create(&mapsContList) != MAPS_ERROR_NONE) return;
758
759         for (hereCont = hereContList.begin(); hereCont != hereContList.end(); hereCont++) {
760                 if (maps_place_contact_create(&mapsCont) != MAPS_ERROR_NONE) continue;
761
762                 is_valid = false;
763
764                 if (!hereCont->GetLabel().empty()) {
765                         error = maps_place_contact_set_label(mapsCont,
766                                 (char*)hereCont->GetLabel().c_str());
767                         is_valid |= (error == MAPS_ERROR_NONE);
768                 }
769
770                 if (!hereCont->GetValue().empty()) {
771                         error = maps_place_contact_set_value(mapsCont,
772                                 (char*)hereCont->GetValue().c_str());
773                         is_valid |= (error == MAPS_ERROR_NONE);
774                 }
775
776                 if (!hereCont->GetContactType().empty()) {
777                         error = maps_place_contact_set_type(mapsCont,
778                                 (char*)hereCont->GetContactType().c_str());
779                         is_valid |= (error == MAPS_ERROR_NONE);
780                 }
781
782                 if (is_valid)
783                         maps_item_list_append(mapsContList, mapsCont,
784                                 maps_place_contact_clone);
785
786                 maps_place_contact_destroy(mapsCont);
787         }
788
789         if (maps_item_list_items(mapsContList)) {
790                 maps_place_set_contacts(mapsPlace, mapsContList);
791                 maps_item_list_remove_all(mapsContList, maps_place_contact_destroy);
792         }
793         maps_item_list_destroy(mapsContList);
794 }
795
796 void HerePlace::ProcessPlaceCategory(PlaceDetails herePlace, maps_place_h mapsPlace)
797 {
798         CategoryList hereCateList = herePlace.GetCategories();
799         CategoryList::iterator hereCate;
800         maps_item_list_h mapsCateList;
801         maps_place_category_h mapsCate;
802         int error;
803         bool is_valid = false;
804
805         if (hereCateList.empty()) return;
806
807         if (maps_item_list_create(&mapsCateList) != MAPS_ERROR_NONE) return;
808
809         // maps-service supports only one category
810         hereCate = hereCateList.begin();
811         if (maps_place_category_create(&mapsCate) == MAPS_ERROR_NONE)
812         {
813                 if (!hereCate->GetCategoryId().ToString().empty()) {
814                         error = maps_place_category_set_id(mapsCate,
815                                 hereCate->GetCategoryId().ToString().c_str());
816                         is_valid |= (error == MAPS_ERROR_NONE);
817                 }
818
819                 if (!hereCate->GetTitle().empty()) {
820                         error = maps_place_category_set_name(mapsCate,
821                                 hereCate->GetTitle().c_str());
822                         is_valid |= (error == MAPS_ERROR_NONE);
823                 }
824
825                 if (!hereCate->GetHref().empty()) {
826                         error = maps_place_category_set_url(mapsCate,
827                                 hereCate->GetHref().c_str());
828                         is_valid |= (error == MAPS_ERROR_NONE);
829                 }
830
831                 if (is_valid) {
832                         maps_item_list_append(mapsCateList, mapsCate, maps_place_category_clone);
833                 }
834                 maps_place_category_destroy(mapsCate);
835         }
836
837         if (maps_item_list_items(mapsCateList)) {
838                 maps_place_set_categories(mapsPlace, mapsCateList);
839                 maps_item_list_remove_all(mapsCateList, maps_place_category_destroy);
840         }
841         maps_item_list_destroy(mapsCateList);
842 }
843
844 void HerePlace::ProcessPlaceImage(PlaceDetails herePlace, maps_place_h mapsPlace)
845 {
846         ImageContentList hereImageList = herePlace.GetImageContent();
847         ImageContentList::iterator hereImage;
848         maps_item_list_h mapsImageList;
849         maps_place_image_h mapsImage;
850         maps_place_link_object_h mapsImageUser;
851         LinkObject hereImageUser;
852         int error;
853         bool is_valid, is_valid2;
854
855         if (hereImageList.empty()) return;
856
857         if (maps_item_list_create(&mapsImageList) != MAPS_ERROR_NONE) return;
858
859         for (hereImage = hereImageList.begin(); hereImage != hereImageList.end(); hereImage++) {
860                 if (maps_place_image_create(&mapsImage) != MAPS_ERROR_NONE) continue;
861
862                 is_valid = false;
863
864                 /* here not supported
865                 // maps_place_image_set_height(maps_place_image_h mapsPlace, const int height); */
866
867                 /* here not supported
868                 // maps_place_image_set_media(maps_place_image_h mapsPlace, maps_place_media_h media); */
869
870                 if (!hereImage->GetSource().empty()) {
871                         error = maps_place_image_set_url(mapsImage, (char*)hereImage->GetSource().c_str());
872                         is_valid |= (error == MAPS_ERROR_NONE);
873                 }
874
875                 if (!hereImage->GetImageId().empty()) {
876                         error = maps_place_image_set_id(mapsImage, (char*)hereImage->GetImageId().c_str());
877                         is_valid |= (error == MAPS_ERROR_NONE);
878                 }
879
880                 hereImageUser = hereImage->GetUser();
881                 if (maps_place_link_object_create(&mapsImageUser) == MAPS_ERROR_NONE) {
882                         is_valid2 = false;
883
884                         if (!hereImageUser.GetId().empty()) {
885                                 error = maps_place_link_object_set_id(mapsImageUser,
886                                                 (char*)hereImageUser.GetId().c_str());
887                                 is_valid2 |= (error == MAPS_ERROR_NONE);
888                         }
889
890                         if (!hereImageUser.GetTitle().empty()) {
891                                 error = maps_place_link_object_set_name(mapsImageUser,
892                                                 (char*)hereImageUser.GetTitle().c_str());
893                                 is_valid2 |= (error == MAPS_ERROR_NONE);
894                         }
895
896                         if (!hereImageUser.GetHref().empty()) {
897                                 error = maps_place_link_object_set_string(mapsImageUser,
898                                                 (char*)hereImageUser.GetHref().c_str());
899                                 is_valid2 |= (error == MAPS_ERROR_NONE);
900                         }
901
902                         if (!hereImageUser.GetType().empty()) {
903                                 error = maps_place_link_object_set_type(mapsImageUser,
904                                                 (char*)hereImageUser.GetType().c_str());
905                                 is_valid2 |= (error == MAPS_ERROR_NONE);
906                         }
907
908                         if (is_valid2) {
909                                 maps_place_image_set_user_link(mapsImage, mapsImageUser);
910                                 is_valid |= is_valid2;
911                         }
912                         maps_place_link_object_destroy(mapsImageUser);
913                 }
914
915                 if (is_valid)
916                         maps_item_list_append(mapsImageList, mapsImage, maps_place_image_clone);
917
918                 maps_place_image_destroy(mapsImage);
919         }
920
921         if (maps_item_list_items(mapsImageList)) {
922                 maps_place_set_images(mapsPlace, mapsImageList);
923                 maps_item_list_remove_all(mapsImageList, maps_place_image_destroy);
924         }
925         maps_item_list_destroy(mapsImageList);
926 }
927
928 void HerePlace::ProcessPlaceDetails(PlaceDetails herePlace, maps_place_h mapsPlace)
929 {
930         EditorialContentList hereEditList = herePlace.GetEditorialContent();
931         EditorialContentList::iterator hereEdit;
932         maps_item_list_h mapsEditList;
933         maps_place_editorial_h mapsEdit;
934         int error;
935         bool is_valid;
936
937         if (hereEditList.empty()) return;
938
939         if (maps_item_list_create(&mapsEditList) != MAPS_ERROR_NONE) return;
940
941         for (hereEdit = hereEditList.begin(); hereEdit != hereEditList.end(); hereEdit++) {
942                 if (maps_place_editorial_create(&mapsEdit) != MAPS_ERROR_NONE) continue;
943
944                 is_valid = false;
945
946                 if (!hereEdit->GetDescription().empty()) {
947                         error = maps_place_editorial_set_description(mapsEdit,
948                                 (char*)hereEdit->GetDescription().c_str());
949                         is_valid |= (error == MAPS_ERROR_NONE);
950                 }
951
952                 if (!hereEdit->GetLanguage().empty()) {
953                         error = maps_place_editorial_set_language(mapsEdit,
954                                 (char*)hereEdit->GetLanguage().c_str());
955                         is_valid |= (error == MAPS_ERROR_NONE);
956                 }
957
958                 /* maps_place_editorial_set_media(mapsEdit, maps_place_media_h media); */
959
960                 if (is_valid)
961                         maps_item_list_append(mapsEditList, mapsEdit, maps_place_editorial_clone);
962
963                 maps_place_editorial_destroy(mapsEdit);
964         }
965
966         if (maps_item_list_items(mapsEditList)) {
967                 maps_place_set_editorials(mapsPlace, mapsEditList);
968                 maps_item_list_remove_all(mapsEditList, maps_place_editorial_destroy);
969         }
970         maps_item_list_destroy(mapsEditList);
971 }
972
973 void HerePlace::ProcessPlaceReviews(PlaceDetails herePlace, maps_place_h mapsPlace)
974 {
975         ReviewContentList hereReviewList = herePlace.GetReviewContent();
976         ReviewContentList::iterator hereReview;
977         maps_place_review_h mapsReview;
978         maps_item_list_h mapsReviewList;
979         LinkObject hereReviewUser;
980         maps_place_link_object_h mapsReviewUser;
981         int error;
982         bool is_valid, is_valid2;
983
984         if (hereReviewList.empty()) return;
985
986         if (maps_item_list_create(&mapsReviewList) != MAPS_ERROR_NONE) return;
987
988         for (hereReview = hereReviewList.begin(); hereReview != hereReviewList.end(); hereReview++) {
989                 if (maps_place_review_create(&mapsReview) != MAPS_ERROR_NONE) continue;
990
991                 is_valid = false;
992
993                 if (!hereReview->GetDateTime().empty()) {
994                         error = maps_place_review_set_date(mapsReview,
995                                 (char*)hereReview->GetDateTime().c_str());
996                         is_valid |= (error == MAPS_ERROR_NONE);
997                 }
998
999                 if (!hereReview->GetDescription().empty()) {
1000                         error = maps_place_review_set_description(mapsReview,
1001                                 (char*)hereReview->GetDescription().c_str());
1002                         is_valid |= (error == MAPS_ERROR_NONE);
1003                 }
1004
1005                 if (!hereReview->GetLanguage().empty()) {
1006                         error = maps_place_review_set_language(mapsReview,
1007                                 (char*)hereReview->GetLanguage().c_str());
1008                         is_valid |= (error == MAPS_ERROR_NONE);
1009                 }
1010
1011                 /* maps_place_review_set_media(mapsReview, maps_place_media_h media) */
1012
1013                 maps_place_review_set_rating(mapsReview, hereReview->GetRating());
1014
1015                 if (!hereReview->GetTitle().empty()) {
1016                         error = maps_place_review_set_title(mapsReview,
1017                                 (char*)hereReview->GetTitle().c_str());
1018                         is_valid |= (error == MAPS_ERROR_NONE);
1019                 }
1020
1021                 hereReviewUser = hereReview->GetUser();
1022                 if (maps_place_link_object_create(&mapsReviewUser) == MAPS_ERROR_NONE) {
1023                         is_valid2 = false;
1024
1025                         if (!hereReviewUser.GetId().empty()) {
1026                                 error = maps_place_link_object_set_id(mapsReviewUser,
1027                                         (char*)hereReviewUser.GetId().c_str());
1028                                 is_valid2 |= (error == MAPS_ERROR_NONE);
1029                         }
1030
1031                         if (!hereReviewUser.GetTitle().empty()) {
1032                                 error = maps_place_link_object_set_name(mapsReviewUser,
1033                                         (char*)hereReviewUser.GetTitle().c_str());
1034                                 is_valid2 |= (error == MAPS_ERROR_NONE);
1035                         }
1036
1037                         if (!hereReviewUser.GetHref().empty()) {
1038                                 error = maps_place_link_object_set_string(mapsReviewUser,
1039                                         (char*)hereReviewUser.GetHref().c_str());
1040                                 is_valid2 |= (error == MAPS_ERROR_NONE);
1041                         }
1042
1043                         if (!hereReviewUser.GetType().empty()) {
1044                                 error = maps_place_link_object_set_type(mapsReviewUser,
1045                                         (char*)hereReviewUser.GetType().c_str());
1046                                 is_valid2 |= (error == MAPS_ERROR_NONE);
1047                         }
1048
1049                         if (is_valid2) {
1050                                 maps_place_review_set_user_link(mapsReview, mapsReviewUser);
1051                                 is_valid |= is_valid2;
1052                         }
1053
1054                         maps_place_link_object_destroy(mapsReviewUser);
1055                 }
1056
1057                 if (is_valid)
1058                         maps_item_list_append(mapsReviewList, mapsReview, maps_place_review_clone);
1059
1060                 maps_place_review_destroy(mapsReview);
1061         }
1062
1063         if (maps_item_list_items(mapsReviewList)) {
1064                 maps_place_set_reviews(mapsPlace, mapsReviewList);
1065                 maps_item_list_remove_all(mapsReviewList, maps_place_review_destroy);
1066         }
1067         maps_item_list_destroy(mapsReviewList);
1068 }
1069
1070 void HerePlace::ProcessPlaceRatings(PlaceDetails herePlace, maps_place_h mapsPlace)
1071 {
1072         Ratings hereRating = herePlace.GetRatings();
1073         maps_place_rating_h mapsRating;
1074
1075         if (maps_place_rating_create(&mapsRating) != MAPS_ERROR_NONE) return;
1076
1077         maps_place_rating_set_average(mapsRating, hereRating.GetAverage());
1078         maps_place_rating_set_count(mapsRating, hereRating.GetCount());
1079         maps_place_set_rating(mapsPlace, mapsRating);
1080         maps_place_rating_destroy(mapsRating);
1081 }
1082
1083 void HerePlace::ProcessPlaceRated(PlaceDetails herePlace, maps_place_h mapsPlace)
1084 {
1085         RelatedItem hereRelated = herePlace.GetRelatedItem();
1086         maps_place_link_object_h mapsRelated;
1087         int error;
1088         bool is_valid = false;
1089
1090         if (maps_place_link_object_create(&mapsRelated) != MAPS_ERROR_NONE) return;
1091
1092         //need to check if GetId() exist
1093         //maps_place_link_object_set_id(mapsRelated, hereRelated.GetId());
1094
1095         if (!hereRelated.GetTitle().empty()) {
1096                 error = maps_place_link_object_set_name(mapsRelated,
1097                         (char*)hereRelated.GetTitle().c_str());
1098                 is_valid |= (error == MAPS_ERROR_NONE);
1099         }
1100
1101         if (!hereRelated.GetHref().empty()) {
1102                 error = maps_place_link_object_set_string(mapsRelated,
1103                         (char*)hereRelated.GetHref().c_str());
1104                 is_valid |= (error == MAPS_ERROR_NONE);
1105         }
1106
1107         if (!hereRelated.GetType().empty()) {
1108                 error = maps_place_link_object_set_type(mapsRelated,
1109                         (char*)hereRelated.GetType().c_str());
1110                 is_valid |= (error == MAPS_ERROR_NONE);
1111         }
1112
1113         if (is_valid)
1114                 maps_place_set_related_link(mapsPlace, mapsRelated);
1115
1116         maps_place_link_object_destroy(mapsRelated);
1117 }
1118
1119 void HerePlace::__flushReplies(int error)
1120 {
1121         maps_place_h mapsPlace;
1122         maps_item_list_h placeList = NULL;
1123
1124         m_nReplyIdx = 0;
1125         __sortList(m_PlaceList);
1126
1127         if (m_bPlaceDetails) {
1128                 if (error != MAPS_ERROR_NONE) {
1129                         ((maps_service_get_place_details_cb)m_pCbFunc)((maps_error_e)error, m_nReqId, NULL, m_pUserData);
1130                         return;
1131                 }
1132
1133                 mapsPlace = m_PlaceList.front();
1134                 m_PlaceList.pop_front();
1135
1136                 ((maps_service_get_place_details_cb)m_pCbFunc)((maps_error_e)error, m_nReqId, mapsPlace, m_pUserData);
1137         } else if (m_bReplyWithList) {
1138                 if (error == MAPS_ERROR_NONE)
1139                         error = maps_place_list_create(&placeList);
1140
1141                 if (error != MAPS_ERROR_NONE) {
1142                         if (placeList)
1143                                 maps_place_list_destroy(placeList);
1144                         ((maps_service_search_place_list_cb)m_pCbFunc)((maps_error_e)error, m_nReqId, 0, NULL, m_pUserData);
1145                         return;
1146                 }
1147
1148                 while (m_nReplyIdx < m_nReplyCnt && !m_bCanceled && !m_PlaceList.empty()) {
1149                         mapsPlace = m_PlaceList.front();
1150                         m_PlaceList.pop_front();
1151
1152                         maps_item_list_append(placeList, mapsPlace, maps_place_clone);
1153                 }
1154
1155                 if (!m_bCanceled)
1156                         ((maps_service_search_place_list_cb)m_pCbFunc)((maps_error_e)error, m_nReqId, maps_item_list_items(placeList), placeList, m_pUserData);
1157                 else
1158                         maps_place_list_destroy(placeList);
1159         } else {
1160                 if (error != MAPS_ERROR_NONE) {
1161                         ((maps_service_search_place_cb)m_pCbFunc)((maps_error_e)error, m_nReqId, 0, 0, NULL, m_pUserData);
1162                         return;
1163                 }
1164
1165                 while (m_nReplyIdx < m_nReplyCnt && !m_bCanceled && !m_PlaceList.empty()) {
1166                         mapsPlace = m_PlaceList.front();
1167                         m_PlaceList.pop_front();
1168
1169                         /* callback function */
1170                         if (((maps_service_search_place_cb)m_pCbFunc)((maps_error_e)error, m_nReqId,
1171                                 m_nReplyIdx++, m_nReplyCnt, mapsPlace, m_pUserData) == FALSE)
1172                                 break;
1173                 }
1174         }
1175         m_bReplyFlushed = true;
1176 }
1177
1178 bool HerePlace::__compareWithTitle(const maps_place_h &item1, const maps_place_h &item2)
1179 {
1180         bool result = false;
1181         char *str1 = NULL, *str2 = NULL;
1182
1183         if (maps_place_get_name(item1, &str1) == MAPS_ERROR_NONE &&
1184                 maps_place_get_name(item2, &str2) == MAPS_ERROR_NONE)
1185                 result = (strcmp(str1, str2) < 0);
1186
1187         g_free(str1);
1188         g_free(str2);
1189         return result;
1190 }
1191
1192 bool HerePlace::__compareWithId(const maps_place_h &item1, const maps_place_h &item2)
1193 {
1194         bool result = false;
1195         char *str1 = NULL, *str2 = NULL;
1196
1197         if (maps_place_get_id(item1, &str1) == MAPS_ERROR_NONE &&
1198                 maps_place_get_id(item2, &str2) == MAPS_ERROR_NONE)
1199                 result = (strcmp(str1, str2) < 0);
1200
1201         g_free(str1);
1202         g_free(str2);
1203         return result;
1204 }
1205
1206 bool HerePlace::__compareWithDistance(const maps_place_h &item1, const maps_place_h &item2)
1207 {
1208         bool result = false;
1209         int num1 = 0, num2 = 0;
1210
1211         if (maps_place_get_distance(item1, &num1) == MAPS_ERROR_NONE &&
1212                 maps_place_get_distance(item2, &num2) == MAPS_ERROR_NONE)
1213                 result = (num1 < num2);
1214
1215         return result;
1216 }
1217
1218 bool HerePlace::__compareWithRating(const maps_place_h &item1, const maps_place_h &item2)
1219 {
1220         bool result = false;
1221         maps_place_rating_h rat1 = NULL, rat2 = NULL;
1222         double num1 = 0, num2 = 0;
1223
1224         if (maps_place_get_rating(item1, &rat1) == MAPS_ERROR_NONE &&
1225                 maps_place_get_rating(item2, &rat2) == MAPS_ERROR_NONE) {
1226                 if (maps_place_rating_get_average(rat1, &num1) == MAPS_ERROR_NONE &&
1227                         maps_place_rating_get_average(rat2, &num2) == MAPS_ERROR_NONE)
1228                         result = (num1 > num2);
1229         }
1230         maps_place_rating_destroy(rat1);
1231         maps_place_rating_destroy(rat2);
1232         return result;
1233 }
1234
1235 bool HerePlace::__compareWithCategoryCb(int index, int total,
1236                                          maps_place_category_h category,
1237                                          void *user_data)
1238 {
1239         user_data = category;
1240         return false;
1241 }
1242
1243 bool HerePlace::__compareWithCategory(const maps_place_h &item1, const maps_place_h &item2)
1244 {
1245         bool result = false;
1246         maps_place_category_h cat1 = NULL, cat2 = NULL;
1247         char *str1 = NULL, *str2 = NULL;
1248
1249         maps_place_foreach_category(item1, __compareWithCategoryCb, &cat1);
1250         maps_place_foreach_category(item2, __compareWithCategoryCb, &cat2);
1251
1252         if (maps_place_category_get_id(item1, &str1) == MAPS_ERROR_NONE &&
1253                 maps_place_category_get_id(item2, &str2) == MAPS_ERROR_NONE)
1254                 result = (strcmp(str1, str2) < 0);
1255
1256         maps_place_category_destroy(item1);
1257         maps_place_category_destroy(item2);
1258         g_free(str1);
1259         g_free(str2);
1260         return result;
1261 }
1262
1263 void HerePlace::__sortList(PlaceList &list)
1264 {
1265         if (!m_szSortBy) return;
1266
1267         if (!strcmp(m_szSortBy, "name") || !strcmp(m_szSortBy, "title")) {
1268                 std::sort(list.begin(), list.end(), __compareWithTitle);
1269         } else if (!strcmp(m_szSortBy, "id")) {
1270                 std::sort(list.begin(), list.end(), __compareWithId);
1271         } else if (!strcmp(m_szSortBy, "distance")) {
1272                 std::sort(list.begin(), list.end(), __compareWithDistance);
1273         } else if (!strcmp(m_szSortBy, "rate") || !strcmp(m_szSortBy, "rating")) {
1274                 std::sort(list.begin(), list.end(), __compareWithRating);
1275         } else if (!strcmp(m_szSortBy, "category")) {
1276                 std::sort(list.begin(), list.end(), __compareWithCategory);
1277         }
1278 }
1279
1280 HERE_PLUGIN_END_NAMESPACE