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