Fix Svace defects in gerrit
[platform/core/api/maps-service.git] / src / api / maps_view_object.cpp
1 /* Copyright (c) 2010-2014 Samsung Electronics Co., Ltd. All rights reserved.
2 *
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 <glib.h>
18 #include <cairo.h>
19 #include "maps_view_object.h"
20 #include "maps_view_object_plugin.h"
21 #include "maps_error.h"
22 #include "maps_util.h"
23 #include "maps_view.h"
24 #include "maps_extra_types.h"
25 #include "maps_condition.h"
26 #include "marker_constructor.h"
27 #include "polyline_constructor.h"
28 #include "polygon_constructor.h"
29 #include "overlay_constructor.h"
30
31 #ifndef M_PI
32 #define M_PI    3.14159265358979323846
33 #endif
34
35 /*
36 * This represents marker visual object information
37  */
38 typedef struct _maps_view_marker_data_s {
39         maps_coordinates_h coordinates;
40         int width;
41         int height;
42         char *file_path;
43         maps_view_marker_type_e type;
44         int z_order;
45 } maps_view_marker_data_s;
46
47 const gsize _MAPS_VIEW_MARKER_FILE_PATH_MAX_LENGTH = MAPS_BASE_URL_MAX_LEN;
48
49 /*
50 * This represents polyline visual object information
51  */
52 typedef struct _maps_view_polyline_data_s {
53         /* The list of maps_coordinates_h points, comprising the polyline */
54         maps_coordinates_list_h points;
55
56         /* Line color */
57         unsigned char r;
58         unsigned char g;
59         unsigned char b;
60         unsigned char a;
61
62         /* Line width */
63         int width;
64 } maps_view_polyline_data_s;
65
66 /*
67 * This represents polygon visual object information
68  */
69 typedef struct _maps_view_polygon_data_s {
70         /* The list of maps_coordinates_h points, comprising the polygon */
71         maps_coordinates_list_h points;
72
73         /* The polygon backgraund color */
74         unsigned char r;
75         unsigned char g;
76         unsigned char b;
77         unsigned char a;
78 } maps_view_polygon_data_s;
79
80 typedef struct _maps_view_overlay_data_s {
81         maps_coordinates_h coordinates;
82         Evas_Object *object;
83         int min_zoom_level;
84         int max_zoom_level;
85         maps_view_overlay_type_e type;
86         Evas_Object *bubble;
87         Evas_Object *clipper;
88 } maps_view_overlay_data_s;
89
90 const int _OVERLAY_BUBBLE_MARGIN = 20;
91 const int _OVERLAY_BUBBLE_PIN_SIZE = 20;
92
93 /*
94 * This represents visual object information
95  */
96 typedef struct _maps_view_object_s {
97         maps_view_object_type_e type;   /* marker, polyline, polygon, group */
98         void *shape_data;                               /* Pointer to the visual object data, such as
99                                                                            maps_view_marker_data_s or maps_view_polyline_data_s */
100         bool visible;
101         maps_view_object_h parent_group; /* The group, owning the object */
102         maps_view_h view;       /* Link with the parent Map View */
103 } maps_view_object_s;
104
105 int _maps_view_on_object_operation(maps_view_h view, maps_view_object_h object,
106                                                                 maps_view_object_operation_e operation);
107 int _maps_view_get_parent(const maps_view_h view, Evas_Object **parent);
108 int _maps_view_get_clipper(const maps_view_h view, Evas_Object **clipper);
109
110 static maps_view_h __get_view(const maps_view_object_h object);
111 static maps_view_polyline_data_s *__get_polyline_data(const maps_view_object_h object);
112 static maps_view_polygon_data_s *__get_polygon_data(const maps_view_object_h object);
113 static maps_view_marker_data_s *__get_marker_data(const maps_view_object_h object);
114 static maps_view_overlay_data_s *__get_overlay_data(const maps_view_object_h object);
115
116 static int __maps_view_polyline_data_create(void **polyline);
117 static int __maps_view_polygon_data_create(void **polygon);
118 static int __maps_view_marker_data_create(void **marker);
119 static int __maps_view_overlay_data_create(void **marker);
120
121 static int __maps_view_polyline_data_destroy(void *polyline);
122 static int __maps_view_polygon_data_destroy(void *polygon);
123 static int __maps_view_marker_data_destroy(void *marker);
124 static int __maps_view_overlay_data_destroy(void *marker);
125
126 static maps_view_h __get_view(const maps_view_object_h object)
127 {
128         if (!object)
129                 return NULL;
130         maps_view_object_s *o = (maps_view_object_s *)object;
131         return o->view;
132 }
133
134 static maps_view_polyline_data_s *__get_polyline_data(const maps_view_object_h object)
135 {
136         maps_view_object_s *o = (maps_view_object_s *)object;
137         if (!o || (o->type != MAPS_VIEW_OBJECT_POLYLINE))
138                 return NULL;
139         return (maps_view_polyline_data_s *)o->shape_data;
140 }
141
142 static int __maps_view_polyline_data_create(void **polyline)
143 {
144         if (!polyline)
145                 return MAPS_ERROR_INVALID_PARAMETER;
146
147         int error = MAPS_ERROR_NONE;
148         maps_view_polyline_data_s *p = NULL;
149
150         do {
151                 p = g_slice_new0(maps_view_polyline_data_s);
152                 if (!p) {
153                         //LCOV_EXCL_START
154                         MAPS_LOGE("OUT_OF_MEMORY(0x%08x)",
155                                   MAPS_ERROR_OUT_OF_MEMORY);
156                         return MAPS_ERROR_OUT_OF_MEMORY;
157                         //LCOV_EXCL_STOP
158                 }
159
160                 error = maps_coordinates_list_create(&p->points);
161                 if (error != MAPS_ERROR_NONE)
162                         break;
163
164                 *polyline = (maps_view_polyline_data_s *) p;
165                 return MAPS_ERROR_NONE;
166         } while (false);
167
168         //LCOV_EXCL_START
169         __maps_view_polyline_data_destroy(p);
170         return error;
171         //LCOV_EXCL_STOP
172 }
173
174 static int __maps_view_polyline_data_destroy(void *polyline)
175 {
176         if (!polyline)
177                 return MAPS_ERROR_INVALID_PARAMETER;
178
179         maps_view_polyline_data_s *p = (maps_view_polyline_data_s *)polyline;
180         if (p->points)
181                 maps_coordinates_list_destroy(p->points);
182
183         g_slice_free(maps_view_polyline_data_s, p);
184
185         return MAPS_ERROR_NONE;
186 }
187
188 static maps_view_polygon_data_s *__get_polygon_data(const maps_view_object_h object)
189 {
190         maps_view_object_s *o = (maps_view_object_s *)object;
191         if (!o || (o->type != MAPS_VIEW_OBJECT_POLYGON))
192                 return NULL;
193         return (maps_view_polygon_data_s *)o->shape_data;
194 }
195
196 static int __maps_view_polygon_data_create(void **polygon)
197 {
198         if (!polygon)
199                 return MAPS_ERROR_INVALID_PARAMETER;
200
201         int error = MAPS_ERROR_NONE;
202         maps_view_polygon_data_s *p = NULL;
203
204         do {
205                 p = g_slice_new0(maps_view_polygon_data_s);
206                 if (!p) {
207                         //LCOV_EXCL_START
208                         MAPS_LOGE("OUT_OF_MEMORY(0x%08x)",
209                                   MAPS_ERROR_OUT_OF_MEMORY);
210                         return MAPS_ERROR_OUT_OF_MEMORY;
211                         //LCOV_EXCL_STOP
212                 }
213
214                 error = maps_coordinates_list_create(&p->points);
215                 if (error != MAPS_ERROR_NONE)
216                         break;
217
218                 *polygon = (maps_view_polygon_data_s *) p;
219                 return MAPS_ERROR_NONE;
220         } while (false);
221
222         //LCOV_EXCL_START
223         __maps_view_polygon_data_destroy(p);
224         return error;
225         //LCOV_EXCL_STOP
226 }
227
228 static int __maps_view_polygon_data_destroy(void *polygon)
229 {
230         if (!polygon)
231                 return MAPS_ERROR_INVALID_PARAMETER;
232
233         maps_view_polygon_data_s *p = (maps_view_polygon_data_s *)polygon;
234         if (p->points)
235                 maps_coordinates_list_destroy(p->points);
236
237         g_slice_free(maps_view_polygon_data_s, p);
238
239         return MAPS_ERROR_NONE;
240 }
241
242 static maps_view_marker_data_s *__get_marker_data(const maps_view_object_h object)
243 {
244         maps_view_object_s *o = (maps_view_object_s *)object;
245         if (!o || (o->type != MAPS_VIEW_OBJECT_MARKER))
246                 return NULL;
247         return (maps_view_marker_data_s *)o->shape_data;
248 }
249
250 static int __maps_view_marker_data_create(void **marker)
251 {
252         if (!marker)
253                 return MAPS_ERROR_INVALID_PARAMETER;
254
255
256         int error = MAPS_ERROR_NONE;
257         maps_view_marker_data_s *m = NULL;
258
259         do {
260                 m = g_slice_new0(maps_view_marker_data_s);
261                 if (!m) {
262                         //LCOV_EXCL_START
263                         MAPS_LOGE("OUT_OF_MEMORY(0x%08x)",
264                                   MAPS_ERROR_OUT_OF_MEMORY);
265                         return MAPS_ERROR_OUT_OF_MEMORY;
266                         //LCOV_EXCL_STOP
267                 }
268
269                 error = maps_coordinates_create(.0, .0, &m->coordinates);
270                 if (error != MAPS_ERROR_NONE)
271                         break;
272
273                 m->type = MAPS_VIEW_MARKER_PIN;
274                 m->width = 0;
275                 m->height = 0;
276                 m->z_order = 0;
277                 *marker = (maps_view_marker_data_s *) m;
278                 return MAPS_ERROR_NONE;
279         } while (false);
280
281         //LCOV_EXCL_START
282         __maps_view_marker_data_destroy(m);
283         return error;
284         //LCOV_EXCL_STOP
285 }
286
287 static int __maps_view_marker_data_destroy(void *marker)
288 {
289         if (!marker)
290                 return MAPS_ERROR_INVALID_PARAMETER;
291
292         maps_view_marker_data_s *m = (maps_view_marker_data_s *)marker;
293         if (m->coordinates)
294                 maps_coordinates_destroy(m->coordinates);
295
296         if (m->file_path)
297                 g_free(m->file_path);
298
299         g_slice_free(maps_view_marker_data_s, m);
300
301         return MAPS_ERROR_NONE;
302 }
303
304 static maps_view_overlay_data_s *__get_overlay_data(const maps_view_object_h object)
305 {
306         maps_view_object_s *o = (maps_view_object_s *)object;
307         if (!o || (o->type != MAPS_VIEW_OBJECT_OVERLAY))
308                 return NULL;
309         return (maps_view_overlay_data_s *)o->shape_data;
310 }
311
312 static int __maps_view_overlay_data_create(void **overlay)
313 {
314         if (!overlay)
315                 return MAPS_ERROR_INVALID_PARAMETER;
316
317         int error = MAPS_ERROR_NONE;
318         maps_view_overlay_data_s *m = NULL;
319
320         do {
321                 m = g_slice_new0(maps_view_overlay_data_s);
322                 if (!m) {
323                         //LCOV_EXCL_START
324                         MAPS_LOGE("OUT_OF_MEMORY(0x%08x)",
325                                   MAPS_ERROR_OUT_OF_MEMORY);
326                         return MAPS_ERROR_OUT_OF_MEMORY;
327                         //LCOV_EXCL_STOP
328                 }
329
330                 error = maps_coordinates_create(.0, .0, &m->coordinates);
331                 if (error != MAPS_ERROR_NONE)
332                         break;
333
334                 *overlay = (maps_view_overlay_data_s *) m;
335                 return MAPS_ERROR_NONE;
336         } while (false);
337
338         //LCOV_EXCL_START
339         __maps_view_overlay_data_destroy(m);
340         return error;
341         //LCOV_EXCL_STOP
342 }
343
344 static int __maps_view_overlay_data_destroy(void *overlay)
345 {
346         if (!overlay)
347                 return MAPS_ERROR_INVALID_PARAMETER;
348
349         maps_view_overlay_data_s *m = (maps_view_overlay_data_s *)overlay;
350
351         if (m->coordinates)
352                 maps_coordinates_destroy(m->coordinates);
353
354         if (m->object)
355                 evas_object_del(m->object);
356
357         if (m->bubble)
358                 evas_object_del(m->bubble);
359
360         if (m->clipper) {
361                 const Eina_List *clipees = evas_object_clipees_get(m->clipper);
362                 if (!clipees || eina_list_count(clipees) == 0) {
363                         evas_object_hide(m->clipper);
364                         MAPS_LOGD("hide clipper");
365                 }
366         }
367
368         g_slice_free(maps_view_overlay_data_s, m);
369
370         return MAPS_ERROR_NONE;
371 }
372
373 int _maps_view_object_create(maps_view_object_type_e type, maps_view_object_h *object)
374 {
375         if (!object)
376                 return MAPS_ERROR_INVALID_PARAMETER;
377         if (type < MAPS_VIEW_OBJECT_POLYLINE || type > MAPS_VIEW_OBJECT_OVERLAY)
378                 return MAPS_ERROR_INVALID_PARAMETER;
379
380         int error = MAPS_ERROR_NONE;
381         maps_view_object_s *o = NULL;
382
383         do {
384                 o = g_slice_new0(maps_view_object_s);
385                 if (!o) {
386                         //LCOV_EXCL_START
387                         MAPS_LOGE("OUT_OF_MEMORY(0x%08x)",
388                                   MAPS_ERROR_OUT_OF_MEMORY);
389                         return MAPS_ERROR_OUT_OF_MEMORY;
390                         //LCOV_EXCL_STOP
391                 }
392
393                 o->type = type;
394                 o->view = NULL;
395                 o->visible = true;
396
397                 int error = MAPS_ERROR_NONE;
398                 switch(o->type) {
399                 case MAPS_VIEW_OBJECT_POLYLINE:
400                         error = __maps_view_polyline_data_create(&o->shape_data);
401                         break;
402                 case MAPS_VIEW_OBJECT_POLYGON:
403                         error = __maps_view_polygon_data_create(&o->shape_data);
404                         break;
405                 case MAPS_VIEW_OBJECT_MARKER:
406                         error = __maps_view_marker_data_create(&o->shape_data);
407                         break;
408                 case MAPS_VIEW_OBJECT_OVERLAY:
409                         error = __maps_view_overlay_data_create(&o->shape_data);
410                         break;
411                 default:
412                         break;
413                 }
414
415                 if ((!o->shape_data) || (error != MAPS_ERROR_NONE))
416                         break;
417
418                 /* Notify view, that the object was constructed */
419                 /*if (view)
420                   _maps_view_on_object_operation(view,
421                   o,
422                   MAPS_VIEW_OBJECT_ADD);*/
423
424                 *object = (maps_view_object_h) o;
425                 return MAPS_ERROR_NONE;
426         } while (false);
427         //LCOV_EXCL_START
428         maps_view_object_destroy(o);
429         return error;
430         //LCOV_EXCL_STOP
431 }
432
433 int _maps_view_object_set_view(maps_view_object_h object, maps_view_h view)
434 {
435         if (!object || !view)
436                 return MAPS_ERROR_INVALID_PARAMETER;
437
438         maps_view_object_s *o = (maps_view_object_s *) object;
439         o->view = view;
440
441         maps_view_object_type_e type;
442         maps_view_object_get_type(object, &type);
443         if (type == MAPS_VIEW_OBJECT_OVERLAY)   {
444                 int min_zoom = 0, max_zoom = 0;
445                 maps_view_object_overlay_get_min_zoom_level(object, &min_zoom);
446                 maps_view_object_overlay_get_max_zoom_level(object, &max_zoom);
447                 if (min_zoom == 0) {
448                         maps_view_get_min_zoom_level(view, &min_zoom);
449                         maps_view_object_overlay_set_min_zoom_level(object, min_zoom);
450                 }
451                 if (max_zoom == 0) {
452                         maps_view_get_max_zoom_level(view, &max_zoom);
453                         maps_view_object_overlay_set_max_zoom_level(object, max_zoom);
454                 }
455         }
456         return MAPS_ERROR_NONE;
457 }
458
459 EXPORT_API int maps_view_object_create_marker(maps_coordinates_h coordinates,
460         const char *image_file_path, maps_view_marker_type_e type, maps_view_object_h *marker)
461 {
462         if (!maps_condition_check_maps_feature())
463                 return MAPS_ERROR_NOT_SUPPORTED;
464         if (!coordinates || !marker)
465                 return MAPS_ERROR_INVALID_PARAMETER;
466         if (type < MAPS_VIEW_MARKER_PIN || type > MAPS_VIEW_MARKER_STICKER)
467                 return MAPS_ERROR_INVALID_PARAMETER;
468
469         /* Create a Marker Visual Object */
470         view::marker_constructor mc;
471         *marker = mc.construct(coordinates, image_file_path, type);
472         if (mc.get_error() == MAPS_ERROR_NONE)
473                 return mc.get_error();
474
475         /* Marker create failure */
476         maps_view_object_destroy(*marker);
477         *marker = NULL;
478         return mc.get_error();
479 }
480
481 EXPORT_API int maps_view_object_create_polyline(maps_coordinates_list_h coordinates,
482         unsigned char r, unsigned char g, unsigned char b, unsigned char a, int width,
483         maps_view_object_h *polyline)
484 {
485         if (!maps_condition_check_maps_feature())
486                 return MAPS_ERROR_NOT_SUPPORTED;
487         if (!coordinates || !polyline || width < 1 || width > 100)
488                 return MAPS_ERROR_INVALID_PARAMETER;
489
490         /* Create a Polyline Visual Object */
491         view::polyline_constructor pc;
492         *polyline = pc.construct(coordinates, r, g, b, a, width);
493         if (pc.get_error() == MAPS_ERROR_NONE)
494                 return pc.get_error();
495
496         /* Polyline create failure */
497         //LCOV_EXCL_START
498         maps_view_object_destroy(*polyline);
499         *polyline = NULL;
500         return pc.get_error();
501         //LCOV_EXCL_STOP
502 }
503
504 EXPORT_API int maps_view_object_create_polygon(maps_coordinates_list_h coordinates,
505         unsigned char r, unsigned char g, unsigned char b, unsigned char a, maps_view_object_h *polygon)
506 {
507         if (!maps_condition_check_maps_feature())
508                 return MAPS_ERROR_NOT_SUPPORTED;
509         if (!coordinates || !polygon)
510                 return MAPS_ERROR_INVALID_PARAMETER;
511
512         /* Create a Polygon Visual Object */
513         view::polygon_constructor pc;
514         *polygon = pc.construct(coordinates, r, g, b, a);
515         if (pc.get_error() == MAPS_ERROR_NONE)
516                 return pc.get_error();
517
518         /* Polygon create failure */
519         //LCOV_EXCL_START
520         maps_view_object_destroy(*polygon);
521         *polygon = NULL;
522         return pc.get_error();
523         //LCOV_EXCL_STOP
524 }
525
526 EXPORT_API int maps_view_object_create_overlay(maps_coordinates_h coordinates,
527         Evas_Object *object, maps_view_overlay_type_e type, maps_view_object_h *overlay)
528 {
529         if (!maps_condition_check_maps_feature())
530                 return MAPS_ERROR_NOT_SUPPORTED;
531         if (!overlay || !coordinates)
532                 return MAPS_ERROR_INVALID_PARAMETER;
533         if (type < MAPS_VIEW_OVERLAY_NORMAL || type > MAPS_VIEW_OVERLAY_BOX)
534                 return MAPS_ERROR_INVALID_PARAMETER;
535
536         double lat, lon;
537         maps_coordinates_get_latitude_longitude(coordinates, &lat, &lon);
538
539         /* Create a Overlay Visual Object */
540         view::overlay_constructor pc;
541         *overlay = pc.construct(coordinates, object, type);
542         if (pc.get_error() == MAPS_ERROR_NONE)
543                 return pc.get_error();
544
545         /* Overlay create failure */
546         //LCOV_EXCL_START
547         maps_view_object_destroy(*overlay);
548         *overlay = NULL;
549         return pc.get_error();
550         //LCOV_EXCL_STOP
551 }
552
553 EXPORT_API int maps_view_object_destroy(maps_view_object_h object)
554 {
555         if (!maps_condition_check_maps_feature())
556                 return MAPS_ERROR_NOT_SUPPORTED;
557         if (!object)
558                 return MAPS_ERROR_INVALID_PARAMETER;
559
560         maps_view_object_s *o = (maps_view_object_s *) object;
561
562         /* Notify view, that the object is to be destroyed shortly */
563         _maps_view_on_object_operation(o->view, o, MAPS_VIEW_OBJECT_REMOVE);
564
565         int error = MAPS_ERROR_NONE;
566         switch(o->type) {
567         case MAPS_VIEW_OBJECT_POLYLINE:
568                 error = __maps_view_polyline_data_destroy(o->shape_data);
569                 break;
570         case MAPS_VIEW_OBJECT_POLYGON:
571                 error = __maps_view_polygon_data_destroy(o->shape_data);
572                 break;
573         case MAPS_VIEW_OBJECT_MARKER:
574                 error = __maps_view_marker_data_destroy(o->shape_data);
575                 break;
576         case MAPS_VIEW_OBJECT_OVERLAY:
577                 error = __maps_view_overlay_data_destroy(o->shape_data);
578                 break;
579         default:
580                 break;
581         }
582         g_slice_free(maps_view_object_s, object);
583         return error;
584 }
585
586 EXPORT_API int maps_view_object_get_type(maps_view_object_h object, maps_view_object_type_e *type)
587 {
588         if (!maps_condition_check_maps_feature())
589                 return MAPS_ERROR_NOT_SUPPORTED;
590         if (!object || !type)
591                 return MAPS_ERROR_INVALID_PARAMETER;
592         *type = ((maps_view_object_s *)object)->type;
593         return MAPS_ERROR_NONE;
594 }
595
596
597 /**
598 * Visual Object Operations
599  */
600
601 EXPORT_API int maps_view_object_set_visible(maps_view_object_h object, bool visible)
602 {
603         if (!maps_condition_check_maps_feature())
604                 return MAPS_ERROR_NOT_SUPPORTED;
605         if (!object)
606                 return MAPS_ERROR_INVALID_PARAMETER;
607         maps_view_object_s *o = (maps_view_object_s *)object;
608         o->visible = visible;
609
610         /* Notify view, that the object visibility is changed */
611         _maps_view_on_object_operation(o->view, o, MAPS_VIEW_OBJECT_SET_VISIBLE);
612
613         return MAPS_ERROR_NONE;
614 }
615
616 EXPORT_API int maps_view_object_get_visible(const maps_view_object_h object, bool *visible)
617 {
618         if (!maps_condition_check_maps_feature())
619                 return MAPS_ERROR_NOT_SUPPORTED;
620         if (!object || !visible)
621                 return MAPS_ERROR_INVALID_PARAMETER;
622         maps_view_object_s *o = (maps_view_object_s *)object;
623         *visible = o->visible;
624         return MAPS_ERROR_NONE;
625 }
626
627
628 /*----------------------------------------------------------------------------*/
629 /*
630 * Polyline
631  */
632
633 EXPORT_API int maps_view_object_polyline_set_polyline(maps_view_object_h polyline,
634                                                                 maps_coordinates_list_h points)
635 {
636         if (!maps_condition_check_maps_feature())
637                 return MAPS_ERROR_NOT_SUPPORTED;
638         if (!polyline || !points)
639                 return MAPS_ERROR_INVALID_PARAMETER;
640
641         /* Get the polyline data pointer */
642         maps_view_polyline_data_s *p = __get_polyline_data(polyline);
643         if (!p)
644                 return MAPS_ERROR_INVALID_PARAMETER;
645
646         /* Set new polyline trajectory */
647         if (p->points != points) {
648                 maps_coordinates_list_destroy(p->points);
649                 p->points = points;
650         }
651
652         /* Notify view, that the object specific preferences is changed */
653         _maps_view_on_object_operation(__get_view(polyline), polyline, MAPS_VIEW_OBJECT_CHANGE);
654
655         return MAPS_ERROR_NONE;
656 }
657
658 EXPORT_API int maps_view_object_polyline_foreach_point(maps_view_object_h polyline,
659                                                                 maps_coordinates_cb callback, void *user_data)
660 {
661         if (!maps_condition_check_maps_feature())
662                 return MAPS_ERROR_NOT_SUPPORTED;
663         if (!polyline || !callback)
664                 return MAPS_ERROR_INVALID_PARAMETER;
665
666         /* Get the polyline data pointer */
667         maps_view_polyline_data_s *p = __get_polyline_data(polyline);
668         if (!p)
669                 return MAPS_ERROR_INVALID_PARAMETER;
670         if (!p->points)
671                 return MAPS_ERROR_NOT_FOUND;
672
673         /* Iterate over polyline trajectory */
674         return maps_coordinates_list_foreach(p->points, callback, user_data);
675 }
676
677 EXPORT_API int maps_view_object_polyline_set_color(maps_view_object_h polyline,
678         unsigned char r, unsigned char g, unsigned char b, unsigned char a)
679 {
680         if (!maps_condition_check_maps_feature())
681                 return MAPS_ERROR_NOT_SUPPORTED;
682         if (!polyline)
683                 return MAPS_ERROR_INVALID_PARAMETER;
684
685         /* Get the polyline data pointer */
686         maps_view_polyline_data_s *p = __get_polyline_data(polyline);
687         if (!p)
688                 return MAPS_ERROR_INVALID_PARAMETER;
689
690         /* Set new color */
691         p->r = r;
692         p->g = g;
693         p->b = b;
694         p->a = a;
695
696         /* Notify view, that the object specific preferences is changed */
697         _maps_view_on_object_operation(__get_view(polyline), polyline, MAPS_VIEW_OBJECT_CHANGE);
698
699         return MAPS_ERROR_NONE;
700 }
701
702 EXPORT_API int maps_view_object_polyline_get_color(const maps_view_object_h polyline,
703         unsigned char *r, unsigned char *g, unsigned char *b, unsigned char *a)
704 {
705         if (!maps_condition_check_maps_feature())
706                 return MAPS_ERROR_NOT_SUPPORTED;
707         if (!polyline || (!r && !g && !b && !a))
708                 return MAPS_ERROR_INVALID_PARAMETER;
709
710         /* Get the polyline data pointer */
711         maps_view_polyline_data_s *p = __get_polyline_data(polyline);
712         if (!p)
713                 return MAPS_ERROR_INVALID_PARAMETER;
714
715         /* Retrieve the color */
716         if (r)
717                 *r = p->r;
718         if (g)
719                 *g = p->g;
720         if (b)
721                 *b = p->b;
722         if (a)
723                 *a = p->a;
724         return MAPS_ERROR_NONE;
725 }
726
727
728 EXPORT_API int maps_view_object_polyline_set_width(maps_view_object_h polyline, int width)
729 {
730         if (!maps_condition_check_maps_feature())
731                 return MAPS_ERROR_NOT_SUPPORTED;
732         if (!polyline)
733                 return MAPS_ERROR_INVALID_PARAMETER;
734         if (width < 0 || width > 100)
735                 return MAPS_ERROR_INVALID_PARAMETER;
736
737         /* Get the polyline data pointer */
738         maps_view_polyline_data_s *p = __get_polyline_data(polyline);
739         if (!p)
740                 return MAPS_ERROR_INVALID_PARAMETER;
741
742         /* Update the width of polyline */
743         p->width = width;
744
745         /* Notify view, that the object specific preferences is changed */
746         _maps_view_on_object_operation(__get_view(polyline), polyline, MAPS_VIEW_OBJECT_CHANGE);
747
748         return MAPS_ERROR_NONE;
749 }
750
751 EXPORT_API int maps_view_object_polyline_get_width(const maps_view_object_h polyline, int *width)
752 {
753         if (!maps_condition_check_maps_feature())
754                 return MAPS_ERROR_NOT_SUPPORTED;
755         if (!polyline || !width)
756                 return MAPS_ERROR_INVALID_PARAMETER;
757
758         /* Get the polyline data pointer */
759         maps_view_polyline_data_s *p = __get_polyline_data(polyline);
760         if (!p)
761                 return MAPS_ERROR_INVALID_PARAMETER;
762
763         /* Retrieve the width of the polyline */
764         *width = p->width;
765         return MAPS_ERROR_NONE;
766 }
767
768 /*----------------------------------------------------------------------------*/
769 /*
770 * Polygon
771  */
772
773 EXPORT_API int maps_view_object_polygon_set_polygon(maps_view_object_h polygon, maps_coordinates_list_h points)
774 {
775         if (!maps_condition_check_maps_feature())
776                 return MAPS_ERROR_NOT_SUPPORTED;
777         if (!polygon || !points)
778                 return MAPS_ERROR_INVALID_PARAMETER;
779
780         /* Get the polygon data pointer */
781         maps_view_polygon_data_s *p = __get_polygon_data(polygon);
782         if (!p)
783                 return MAPS_ERROR_INVALID_PARAMETER;
784
785         /* Set new polygon border */
786         if (p->points != points) {
787                 maps_coordinates_list_destroy(p->points);
788                 p->points = points;
789         }
790
791         /* Notify view, that the object specific preferences is changed */
792         _maps_view_on_object_operation(__get_view(polygon), polygon, MAPS_VIEW_OBJECT_CHANGE);
793
794         return MAPS_ERROR_NONE;
795 }
796
797 EXPORT_API int maps_view_object_polygon_foreach_point(maps_view_object_h polygon,
798         maps_coordinates_cb callback, void *user_data)
799 {
800         if (!maps_condition_check_maps_feature())
801                 return MAPS_ERROR_NOT_SUPPORTED;
802         if (!polygon || !callback)
803                 return MAPS_ERROR_INVALID_PARAMETER;
804
805         /* Get the polygon data pointer */
806         maps_view_polygon_data_s *p = __get_polygon_data(polygon);
807         if (!p)
808                 return MAPS_ERROR_INVALID_PARAMETER;
809         if (!p->points)
810                 return MAPS_ERROR_NOT_FOUND;
811
812         /* Iterate over polygon border */
813         return maps_coordinates_list_foreach(p->points, callback, user_data);
814 }
815
816
817 EXPORT_API int maps_view_object_polygon_set_fill_color(maps_view_object_h polygon,
818         unsigned char r, unsigned char g, unsigned char b, unsigned char a)
819 {
820         if (!maps_condition_check_maps_feature())
821                 return MAPS_ERROR_NOT_SUPPORTED;
822         if (!polygon)
823                 return MAPS_ERROR_INVALID_PARAMETER;
824
825         /* Get the polygon data pointer */
826         maps_view_polygon_data_s *p = __get_polygon_data(polygon);
827         if (!p)
828                 return MAPS_ERROR_INVALID_PARAMETER;
829
830         /* Set new background color */
831         p->r = r;
832         p->g = g;
833         p->b = b;
834         p->a = a;
835
836         /* Notify view, that the object specific preferences is changed */
837         _maps_view_on_object_operation(__get_view(polygon), polygon, MAPS_VIEW_OBJECT_CHANGE);
838
839         return MAPS_ERROR_NONE;
840 }
841
842 EXPORT_API int maps_view_object_polygon_get_fill_color(const maps_view_object_h polygon,
843         unsigned char *r, unsigned char *g, unsigned char *b, unsigned char *a)
844 {
845         if (!maps_condition_check_maps_feature())
846                 return MAPS_ERROR_NOT_SUPPORTED;
847         if (!polygon || (!r && !g && !b && !a))
848                 return MAPS_ERROR_INVALID_PARAMETER;
849
850         /* Get the polygon data pointer */
851         maps_view_polygon_data_s *p = __get_polygon_data(polygon);
852         if (!p)
853                 return MAPS_ERROR_INVALID_PARAMETER;
854
855         /* Retrieve the background color */
856         if (r)
857                 *r = p->r;
858         if (g)
859                 *g = p->g;
860         if (b)
861                 *b = p->b;
862         if (a)
863                 *a = p->a;
864         return MAPS_ERROR_NONE;
865 }
866
867
868 /*----------------------------------------------------------------------------*/
869 /*
870 * Marker
871  */
872
873 EXPORT_API int maps_view_object_marker_set_coordinates(maps_view_object_h marker,
874         maps_coordinates_h coordinates)
875 {
876         if (!maps_condition_check_maps_feature())
877                 return MAPS_ERROR_NOT_SUPPORTED;
878         if (!marker || !coordinates)
879                 return MAPS_ERROR_INVALID_PARAMETER;
880         maps_view_marker_data_s *m = __get_marker_data(marker);
881         if (!m)
882                 return MAPS_ERROR_INVALID_PARAMETER;
883
884         /* Set new coordinates */
885         if (m->coordinates != coordinates) {
886                 maps_coordinates_destroy(m->coordinates);
887                 m->coordinates = coordinates;
888         }
889
890         /* Notify view, that the object specific preferences is changed */
891         _maps_view_on_object_operation(__get_view(marker), marker, MAPS_VIEW_OBJECT_CHANGE);
892
893         return MAPS_ERROR_NONE;
894 }
895
896 EXPORT_API int maps_view_object_marker_resize(maps_view_object_h marker, int width, int height)
897 {
898         if (!maps_condition_check_maps_feature())
899                 return MAPS_ERROR_NOT_SUPPORTED;
900         if (!marker || width < 0 || height < 0)
901                 return MAPS_ERROR_INVALID_PARAMETER;
902         maps_view_marker_data_s *m = __get_marker_data(marker);
903         if (!m)
904                 return MAPS_ERROR_INVALID_PARAMETER;
905         m->width = width;
906         m->height = height;
907
908         /* Notify view, that the object specific preferences is changed */
909         _maps_view_on_object_operation(__get_view(marker), marker, MAPS_VIEW_OBJECT_CHANGE);
910
911         return MAPS_ERROR_NONE;
912 }
913
914 EXPORT_API int maps_view_object_marker_set_image_file(maps_view_object_h marker, const char *file_path)
915 {
916         if (!maps_condition_check_maps_feature())
917                 return MAPS_ERROR_NOT_SUPPORTED;
918         if (!marker || !file_path)
919                 return MAPS_ERROR_INVALID_PARAMETER;
920         maps_view_marker_data_s *m = __get_marker_data(marker);
921         if (!m)
922                 return MAPS_ERROR_INVALID_PARAMETER;
923         const int error = maps_set_string(file_path, _MAPS_VIEW_MARKER_FILE_PATH_MAX_LENGTH, &m->file_path);
924
925         /* Notify view, that the object specific preferences is changed */
926         if (error == MAPS_ERROR_NONE) {
927                 maps_view_object_marker_set_size(marker, 0, 0);
928                 _maps_view_on_object_operation(__get_view(marker), marker, MAPS_VIEW_OBJECT_CHANGE);
929         }
930
931         return error;
932 }
933
934 EXPORT_API int maps_view_object_marker_get_image_file(const maps_view_object_h marker, char **file_path)
935 {
936         if (!maps_condition_check_maps_feature())
937                 return MAPS_ERROR_NOT_SUPPORTED;
938         if (!marker || !file_path)
939                 return MAPS_ERROR_INVALID_PARAMETER;
940         maps_view_marker_data_s *m = __get_marker_data(marker);
941         if (!m)
942                 return MAPS_ERROR_INVALID_PARAMETER;
943         return maps_get_string(m->file_path, _MAPS_VIEW_MARKER_FILE_PATH_MAX_LENGTH, file_path);
944 }
945
946 EXPORT_API int maps_view_object_marker_get_coordinates(const maps_view_object_h marker, maps_coordinates_h *coordinates)
947 {
948         if (!maps_condition_check_maps_feature())
949                 return MAPS_ERROR_NOT_SUPPORTED;
950         if (!marker || !coordinates)
951                 return MAPS_ERROR_INVALID_PARAMETER;
952         maps_view_marker_data_s *m = __get_marker_data(marker);
953         if (!m)
954                 return MAPS_ERROR_INVALID_PARAMETER;
955         return maps_coordinates_clone(m->coordinates, coordinates);
956 }
957
958 EXPORT_API int maps_view_object_marker_set_size(maps_view_object_h marker, int width, int height)
959 {
960         if (!maps_condition_check_maps_feature())
961                 return MAPS_ERROR_NOT_SUPPORTED;
962         if (!marker || width < 0 || height < 0)
963                 return MAPS_ERROR_INVALID_PARAMETER;
964         maps_view_marker_data_s *m = __get_marker_data(marker);
965         if (!m)
966                 return MAPS_ERROR_INVALID_PARAMETER;
967         m->width = width;
968         m->height = height;
969         return MAPS_ERROR_NONE;
970 }
971
972 EXPORT_API int maps_view_object_marker_get_size(const maps_view_object_h marker, int *width, int *height)
973 {
974         if (!maps_condition_check_maps_feature())
975                 return MAPS_ERROR_NOT_SUPPORTED;
976         if (!marker || (!width && !height))
977                 return MAPS_ERROR_INVALID_PARAMETER;
978         maps_view_marker_data_s *m = __get_marker_data(marker);
979         if (!m)
980                 return MAPS_ERROR_INVALID_PARAMETER;
981         if (width)
982                 *width = m->width;
983         if (height)
984                 *height = m->height;
985         return MAPS_ERROR_NONE;
986 }
987
988 int _maps_view_object_marker_set_type(maps_view_object_h marker, maps_view_marker_type_e type)
989 {
990         if (!marker)
991                 return MAPS_ERROR_INVALID_PARAMETER;
992         if ((type < MAPS_VIEW_MARKER_PIN) || (type > MAPS_VIEW_MARKER_STICKER))
993                 return MAPS_ERROR_INVALID_PARAMETER;
994         maps_view_marker_data_s *m = __get_marker_data(marker);
995         if (!m)
996                 return MAPS_ERROR_INVALID_PARAMETER;
997         m->type = type;
998         return MAPS_ERROR_NONE;
999 }
1000
1001 EXPORT_API int maps_view_object_marker_get_type(const maps_view_object_h marker, maps_view_marker_type_e *type)
1002 {
1003         if (!maps_condition_check_maps_feature())
1004                 return MAPS_ERROR_NOT_SUPPORTED;
1005         if (!marker || !type)
1006                 return MAPS_ERROR_INVALID_PARAMETER;
1007         maps_view_marker_data_s *m = __get_marker_data(marker);
1008         if (!m)
1009                 return MAPS_ERROR_INVALID_PARAMETER;
1010         *type = m->type;
1011         return MAPS_ERROR_NONE;
1012 }
1013
1014 EXPORT_API int maps_view_object_marker_set_z_order(maps_view_object_h marker, int z_order)
1015 {
1016         if (!maps_condition_check_maps_feature())
1017                 return MAPS_ERROR_NOT_SUPPORTED;
1018         if (!marker || (z_order > 100 || z_order < -100))
1019                 return MAPS_ERROR_INVALID_PARAMETER;
1020         maps_view_marker_data_s *m = __get_marker_data(marker);
1021         if (!m)
1022                 return MAPS_ERROR_INVALID_PARAMETER;
1023
1024         /* Notify view, that the object specific preferences is changed */
1025         if (m->z_order != z_order) {
1026                 m->z_order = z_order;
1027                 _maps_view_on_object_operation(__get_view(marker), marker, MAPS_VIEW_OBJECT_CHANGE);
1028         }
1029
1030         return MAPS_ERROR_NONE;
1031 }
1032
1033 EXPORT_API int maps_view_object_marker_get_z_order(const maps_view_object_h marker,     int *z_order)
1034 {
1035         if (!maps_condition_check_maps_feature())
1036                 return MAPS_ERROR_NOT_SUPPORTED;
1037         if (!marker || !z_order)
1038                 return MAPS_ERROR_INVALID_PARAMETER;
1039         maps_view_marker_data_s *m = __get_marker_data(marker);
1040         if (!m)
1041                 return MAPS_ERROR_INVALID_PARAMETER;
1042
1043         *z_order = m->z_order;
1044         return MAPS_ERROR_NONE;
1045 }
1046
1047 int _maps_view_object_overlay_set_type(maps_view_object_h overlay, maps_view_overlay_type_e type)
1048 {
1049         if (!overlay || (type < MAPS_VIEW_OVERLAY_NORMAL || type > MAPS_VIEW_OVERLAY_BOX))
1050                 return MAPS_ERROR_INVALID_PARAMETER;
1051         maps_view_overlay_data_s *m = __get_overlay_data(overlay);
1052         if (!m)
1053                 return MAPS_ERROR_INVALID_PARAMETER;
1054         m->type = type;
1055         return MAPS_ERROR_NONE;
1056 }
1057
1058 //LCOV_EXCL_START
1059 int _maps_view_object_overlay_get_bubble(maps_view_object_h overlay, Evas_Object **object)
1060 {
1061         if (!overlay || !object)
1062                 return MAPS_ERROR_INVALID_PARAMETER;
1063         maps_view_overlay_data_s *m = __get_overlay_data(overlay);
1064         if (!m)
1065                 return MAPS_ERROR_INVALID_PARAMETER;
1066         *object = m->bubble;
1067         return MAPS_ERROR_NONE;
1068 }
1069 //LCOV_EXCL_STOP
1070
1071 int _maps_view_object_overlay_set_bubble(maps_view_object_h overlay)
1072 {
1073         if (!overlay)
1074                 return MAPS_ERROR_INVALID_PARAMETER;
1075         maps_view_overlay_data_s *m = __get_overlay_data(overlay);
1076         if (!m)
1077                 return MAPS_ERROR_INVALID_PARAMETER;
1078
1079         int x, y, w, h;
1080         evas_object_geometry_get(m->object, &x, &y, &w, &h);
1081
1082         w += _OVERLAY_BUBBLE_MARGIN * 2;
1083         h += _OVERLAY_BUBBLE_MARGIN * 2 + _OVERLAY_BUBBLE_PIN_SIZE;
1084
1085         m->bubble = evas_object_image_filled_add(evas_object_evas_get(m->object));
1086         evas_object_stack_below(m->bubble, m->object);
1087         evas_object_move(m->bubble, x, y);
1088         evas_object_resize(m->bubble, w, h);
1089         evas_object_show(m->bubble);
1090
1091         unsigned char *pixels;
1092         int row_stride;
1093         cairo_t *cairo;
1094         cairo_surface_t *surface;
1095
1096         evas_object_image_alpha_set(m->bubble, EINA_TRUE);
1097         evas_object_image_colorspace_set(m->bubble, EVAS_COLORSPACE_ARGB8888);
1098         evas_object_image_size_set(m->bubble, w, h);
1099         evas_object_image_fill_set(m->bubble, 0, 0, w, h);
1100
1101         pixels = (unsigned char *)evas_object_image_data_get(m->bubble, EINA_TRUE);
1102         row_stride = cairo_format_stride_for_width(CAIRO_FORMAT_ARGB32, w);
1103         surface = cairo_image_surface_create_for_data(pixels, CAIRO_FORMAT_ARGB32,
1104                                                                                                    w, h, row_stride);
1105         /* Create the cairo context */
1106         cairo = cairo_create(surface);
1107
1108         /* Configuration */
1109         cairo_set_source_rgba(cairo, 0, 0, 0, 0);
1110         cairo_paint_with_alpha(cairo, 0);
1111
1112         /* set the size of bubble */
1113         double bx = x + 2;
1114         double by = y + 2;
1115         double bw = w - bx * 2;
1116         double bh = h - by - _OVERLAY_BUBBLE_PIN_SIZE;
1117
1118         /* build a path */
1119         cairo_new_path(cairo);
1120         if (m->type == MAPS_VIEW_OVERLAY_BUBBLE) {
1121                 double r = bh / 8.;
1122                 double d = M_PI / 180.;
1123                 cairo_arc(cairo, bx + bw - r, by + r, r, -90 * d, 0 * d);
1124                 cairo_arc(cairo, bx + bw - r, by + bh - r, r, 0 * d, 90 * d);
1125                 cairo_line_to(cairo, bx + bw / 2 + _OVERLAY_BUBBLE_PIN_SIZE, by + bh);
1126                 cairo_line_to(cairo, bx + bw / 2, by + bh + _OVERLAY_BUBBLE_PIN_SIZE);
1127                 cairo_line_to(cairo, bx + bw / 2 - _OVERLAY_BUBBLE_PIN_SIZE, by + bh);
1128                 cairo_arc(cairo, bx + r, by + bh - r, r, 90 * d, 180 * d);
1129                 cairo_arc(cairo, bx + r, by + r, r, 180 * d, 270 * d);
1130         } else {
1131                 cairo_move_to(cairo, 1., 1.);
1132                 cairo_line_to(cairo, 1., bh);
1133                 cairo_line_to(cairo, bw / 2 - _OVERLAY_BUBBLE_PIN_SIZE, bh);
1134                 cairo_line_to(cairo, bw / 2, bh + _OVERLAY_BUBBLE_PIN_SIZE);
1135                 cairo_line_to(cairo, bw / 2 + _OVERLAY_BUBBLE_PIN_SIZE, bh);
1136                 cairo_line_to(cairo, bw, bh);
1137                 cairo_line_to(cairo, bw, 1);
1138         }
1139         cairo_close_path(cairo);
1140
1141         /* clipping */
1142         cairo_clip_preserve(cairo);
1143         cairo_set_source_rgb(cairo, 1., 1., 1.);
1144         cairo_fill_preserve(cairo);
1145         cairo_set_source_rgb(cairo, .1, .1, .1);
1146         cairo_set_line_width(cairo, 3);
1147
1148
1149         cairo_stroke(cairo);
1150         cairo_destroy(cairo);
1151         cairo_surface_destroy(surface);
1152
1153         evas_object_image_data_set(m->bubble, pixels);
1154         evas_object_image_data_update_add(m->bubble, 0, 0, w, h);
1155
1156         return MAPS_ERROR_NONE;
1157 }
1158
1159 EXPORT_API int maps_view_object_overlay_get_object(maps_view_object_h overlay, Evas_Object **object)
1160 {
1161         if (!maps_condition_check_maps_feature())
1162                 return MAPS_ERROR_NOT_SUPPORTED;
1163         if (!overlay || !object)
1164                 return MAPS_ERROR_INVALID_PARAMETER;
1165         maps_view_overlay_data_s *m = __get_overlay_data(overlay);
1166         if (!m)
1167                 return MAPS_ERROR_INVALID_PARAMETER;
1168         *object = m->object;
1169         return MAPS_ERROR_NONE;
1170 }
1171
1172 int _maps_view_object_overlay_set_object(maps_view_object_h overlay, Evas_Object *object)
1173 {
1174         if (!overlay || !object)
1175                 return MAPS_ERROR_INVALID_PARAMETER;
1176         maps_view_overlay_data_s *m = __get_overlay_data(overlay);
1177         if (!m)
1178                 return MAPS_ERROR_INVALID_PARAMETER;
1179         m->object = object;
1180         if (m->type != MAPS_VIEW_OVERLAY_NORMAL)
1181                 _maps_view_object_overlay_set_bubble(overlay);
1182
1183         return MAPS_ERROR_NONE;
1184 }
1185
1186 EXPORT_API int maps_view_object_overlay_set_coordinates(maps_view_object_h overlay, maps_coordinates_h coordinates)
1187 {
1188         if (!maps_condition_check_maps_feature())
1189                 return MAPS_ERROR_NOT_SUPPORTED;
1190         if (!overlay || !coordinates)
1191                 return MAPS_ERROR_INVALID_PARAMETER;
1192         maps_view_overlay_data_s *m = __get_overlay_data(overlay);
1193         if (!m)
1194                 return MAPS_ERROR_INVALID_PARAMETER;
1195
1196         if (m->coordinates != coordinates) {
1197                 maps_coordinates_destroy(m->coordinates);
1198                 m->coordinates = coordinates;
1199         }
1200
1201         /* Notify view, that the object specific preferences is changed */
1202         _maps_view_on_object_operation(__get_view(overlay), overlay, MAPS_VIEW_OBJECT_CHANGE);
1203
1204         return MAPS_ERROR_NONE;
1205 }
1206
1207 EXPORT_API int maps_view_object_overlay_get_coordinates(const maps_view_object_h overlay, maps_coordinates_h *coordinates)
1208 {
1209         if (!maps_condition_check_maps_feature())
1210                 return MAPS_ERROR_NOT_SUPPORTED;
1211         if (!overlay || !coordinates)
1212                 return MAPS_ERROR_INVALID_PARAMETER;
1213         maps_view_overlay_data_s *m = __get_overlay_data(overlay);
1214         if (!m)
1215                 return MAPS_ERROR_INVALID_PARAMETER;
1216         return maps_coordinates_clone(m->coordinates, coordinates);
1217 }
1218
1219 EXPORT_API int maps_view_object_overlay_set_min_zoom_level(maps_view_object_h overlay, int zoom)
1220 {
1221         if (!maps_condition_check_maps_feature())
1222                 return MAPS_ERROR_NOT_SUPPORTED;
1223         if (!overlay || zoom < 0)
1224                 return MAPS_ERROR_INVALID_PARAMETER;
1225         maps_view_overlay_data_s *m = __get_overlay_data(overlay);
1226         if (!m)
1227                 return MAPS_ERROR_INVALID_PARAMETER;
1228         int map_min_zoom_level = 0;
1229         maps_view_get_min_zoom_level(__get_view(overlay), &map_min_zoom_level);
1230         if (zoom < map_min_zoom_level)
1231                 m->min_zoom_level = map_min_zoom_level;
1232         else
1233                 m->min_zoom_level = zoom;
1234         return MAPS_ERROR_NONE;
1235 }
1236
1237 EXPORT_API int maps_view_object_overlay_get_max_zoom_level(const maps_view_object_h overlay, int *zoom)
1238 {
1239         if (!maps_condition_check_maps_feature())
1240                 return MAPS_ERROR_NOT_SUPPORTED;
1241         if (!overlay || !zoom)
1242                 return MAPS_ERROR_INVALID_PARAMETER;
1243         maps_view_overlay_data_s *m = __get_overlay_data(overlay);
1244         if (!m)
1245                 return MAPS_ERROR_INVALID_PARAMETER;
1246         *zoom = m->max_zoom_level;
1247         return MAPS_ERROR_NONE;
1248 }
1249
1250 EXPORT_API int maps_view_object_overlay_set_max_zoom_level(maps_view_object_h overlay, int zoom)
1251 {
1252         if (!maps_condition_check_maps_feature())
1253                 return MAPS_ERROR_NOT_SUPPORTED;
1254         if (!overlay || zoom < 0)
1255                 return MAPS_ERROR_INVALID_PARAMETER;
1256         maps_view_overlay_data_s *m = __get_overlay_data(overlay);
1257         if (!m)
1258                 return MAPS_ERROR_INVALID_PARAMETER;
1259         int map_max_zoom_level = 0;
1260         maps_view_get_max_zoom_level(__get_view(overlay), &map_max_zoom_level);
1261         if (zoom < map_max_zoom_level)
1262                 m->max_zoom_level = map_max_zoom_level;
1263         else
1264                 m->max_zoom_level = zoom;
1265         return MAPS_ERROR_NONE;
1266 }
1267
1268 EXPORT_API int maps_view_object_overlay_get_min_zoom_level(const maps_view_object_h overlay, int *zoom)
1269 {
1270         if (!maps_condition_check_maps_feature())
1271                 return MAPS_ERROR_NOT_SUPPORTED;
1272         if (!overlay || !zoom)
1273                 return MAPS_ERROR_INVALID_PARAMETER;
1274         maps_view_overlay_data_s *m = __get_overlay_data(overlay);
1275         if (!m)
1276                 return MAPS_ERROR_INVALID_PARAMETER;
1277         *zoom = m->min_zoom_level;
1278         return MAPS_ERROR_NONE;
1279 }
1280
1281 static bool __maps_view_object_overlay_set_visible(maps_view_object_h overlay)
1282 {
1283         if (!overlay)
1284                 return false;
1285
1286         maps_view_overlay_data_s *m = __get_overlay_data(overlay);
1287         if (!m)
1288                 return false;
1289
1290         maps_view_object_s *o = (maps_view_object_s *)overlay;
1291         if (o->visible) {
1292                 int zoom;
1293                 maps_view_get_zoom_level(__get_view(overlay), &zoom);
1294                 if (zoom < m->min_zoom_level || zoom > m->max_zoom_level) {
1295                         evas_object_hide(m->object);
1296                         if (m->bubble)
1297                                 evas_object_hide(m->bubble);
1298                 } else {
1299                         evas_object_show(m->object);
1300                         if (m->bubble)
1301                                 evas_object_show(m->bubble);
1302                 }
1303         } else {
1304                 evas_object_hide(m->object);
1305                 if (m->bubble)
1306                         evas_object_hide(m->bubble);
1307         }
1308         return true;
1309 }
1310
1311 static bool __maps_view_object_overlay_clip(maps_view_object_h overlay, Evas_Object *clipper)
1312 {
1313         if (!overlay || !clipper)
1314                 return false;
1315
1316         int x, y, w, h;
1317         maps_view_get_screen_location(__get_view(overlay), &x, &y, &w, &h);
1318         maps_view_overlay_data_s *m = __get_overlay_data(overlay);
1319         if (!m)
1320                 return false;
1321         evas_object_color_set(clipper, 255, 255, 255, 255);
1322         evas_object_move(clipper, x, y);
1323         evas_object_resize(clipper, w, h);
1324         evas_object_clip_set(m->object, clipper);
1325         if (m->bubble)
1326                 evas_object_clip_set(m->bubble, clipper);
1327         evas_object_show(clipper);
1328
1329         m->clipper = clipper;
1330         return true;
1331 }
1332
1333 static bool __maps_view_object_overlay_move(maps_view_object_h overlay, maps_coordinates_h coordinates)
1334 {
1335         if (!overlay || !coordinates)
1336                 return false;
1337
1338         int x, y, w, h;
1339         maps_view_geolocation_to_screen(__get_view(overlay), coordinates, &x, &y);
1340         maps_view_overlay_data_s *m = __get_overlay_data(overlay);
1341         if (!m)
1342                 return false;
1343         evas_object_geometry_get(m->object, NULL, NULL, &w, &h);
1344
1345         x -= w / 2;
1346         y -= h;
1347
1348         if (m->type != MAPS_VIEW_OVERLAY_NORMAL) {
1349                 y -= _OVERLAY_BUBBLE_MARGIN + _OVERLAY_BUBBLE_PIN_SIZE;
1350                 evas_object_move(m->object, x, y);
1351
1352                 if (m->bubble) {
1353                         x -= _OVERLAY_BUBBLE_MARGIN;
1354                         y -= _OVERLAY_BUBBLE_MARGIN ;
1355                         evas_object_move(m->bubble, x, y);
1356                 }
1357         } else {
1358                 evas_object_move(m->object, x, y);
1359         }
1360         return true;
1361 }
1362
1363 static bool __maps_view_object_overlay_update(maps_view_object_h overlay, Evas_Object *clipper)
1364 {
1365         if (!overlay || !clipper)
1366                 return false;
1367
1368         bool ret = false;
1369         maps_coordinates_h coordinates = NULL;
1370
1371         do {
1372                 ret = __maps_view_object_overlay_set_visible(overlay);
1373                 if (!ret) break;
1374
1375                 ret = __maps_view_object_overlay_clip(overlay, clipper);
1376                 if (!ret) break;
1377
1378                 maps_view_object_overlay_get_coordinates(overlay, &coordinates);
1379                 ret = __maps_view_object_overlay_move(overlay, coordinates);
1380         } while (0);
1381
1382         if (coordinates)
1383                 maps_coordinates_destroy(coordinates);
1384
1385         return ret;
1386 }
1387
1388 //LCOV_EXCL_START
1389 bool _maps_view_object_overlay_cb(int index, int total, maps_view_object_h object, void *user_data)
1390 {
1391         if (!object || !user_data)
1392                 return false;
1393
1394         maps_view_object_type_e type;
1395         maps_view_object_get_type(object, &type);
1396         if (type != MAPS_VIEW_OBJECT_OVERLAY)
1397                 return true;
1398         return __maps_view_object_overlay_update(object, (Evas_Object*)user_data);
1399 }
1400 //LCOV_EXCL_STOP
1401
1402 int _maps_view_object_overlay_operation(maps_view_h view, maps_view_object_h object, maps_view_object_operation_e operation)
1403 {
1404         if (!view || !object)
1405                 return MAPS_ERROR_INVALID_PARAMETER;
1406
1407         Evas_Object *parent = NULL, *clipper = NULL;
1408         maps_view_overlay_data_s *o = __get_overlay_data(object);
1409
1410         if (!o)
1411                 return MAPS_ERROR_INVALID_PARAMETER;
1412
1413         if (operation == MAPS_VIEW_OBJECT_ADD) {
1414                 _maps_view_get_parent(view, &parent);
1415                 evas_object_smart_member_add(o->bubble, parent);
1416                 evas_object_smart_member_add(o->object, parent);
1417         }
1418
1419         if (operation != MAPS_VIEW_OBJECT_REMOVE) {
1420                 _maps_view_get_clipper(view, &clipper);
1421                 __maps_view_object_overlay_update(object, clipper);
1422         }
1423
1424         return MAPS_ERROR_NONE;
1425 }