Add LCOV remarkers to increase line coverage rate
[platform/core/api/maps-service.git] / src / api / maps_view.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
18 #include <tizen.h>
19 #include <Ecore.h>
20 #include <Evas.h>
21 #include <unistd.h>
22 #include <glib.h>
23 #include <Elementary.h>
24
25 #include "maps_view.h"
26 #include "maps_view_plugin.h"
27 #include "maps_util.h"
28 #include "module.h"
29 #include "empty_module.h"
30 #include "commands.h"
31 #include "command_queue.h"
32 #include "poly_shape_hit_test.h"
33 #include "gesture_processor.h"
34 #include "inertial_camera.h"
35 #include "inertial_gesture.h"
36 #include "gesture_detector_statemachine.h"
37 #include "maps_view_event_data.h"
38 #include "maps_condition.h"
39
40 /*
41  * The structure of callbacks info, Maps View is invoking during events
42  */
43 typedef struct _maps_view_callback_info_s {
44         maps_view_on_event_cb callback;
45         void *user_data;
46 } maps_view_callback_info_s;
47
48 /*
49  * The structure of map view idle listener callbacks info
50  */
51 typedef struct _maps_view_idle_listener_info_s {
52         void (*callback)(void *user_data);
53         void *user_data;
54 } maps_view_idle_listener_info_s;
55
56 /*
57  * The structure of Maps View internal data
58  */
59 typedef struct _maps_view_s {
60         /* Map Coordinates and Area */
61         maps_area_h area;
62         maps_coordinates_h center;
63
64         /* Run-time scale values */
65         double zoom_factor;
66         double rotation_angle; /* in graduses */
67         int zoom_level;
68
69         /* Camera inertial transition data */
70         view::inertial_camera *inertial_camera;
71         view::inertial_gesture *inertial_gesture;
72         maps_view_idle_listener_info_s idle_listener;
73
74         /* We'd better to store that values in order to easily limit zoom level
75          * and factor in the run time without accessing the plugin frequently */
76         int min_zoom_level;
77         int max_zoom_level;
78
79         /* The handle of Maps Service, used by Map View */
80         maps_service_h maps;
81
82         /* List of Visual Objects on the View */
83         maps_item_list_h view_objects;
84
85         /* Evas basis */
86         Evas *canvas;
87         Evas_Object *panel;
88         Evas_Object *parent;
89         Evas_Object *clipper;
90
91         /* Gesture Support */
92         maps_view_action_e gesture_actions[MAPS_VIEW_GESTURE_LONG_PRESS + 1];
93         bool gesture_available[MAPS_VIEW_GESTURE_LONG_PRESS + 1];
94
95         /* Continuous gesture info */
96         view::finger_event_stream *finger_stream;
97
98         /* Map View callbacks */
99         maps_view_callback_info_s event_callbacks[MAPS_VIEW_EVENT_READY + 1];
100         bool ready;
101
102         /* Evas Queue support */
103         Ecore_Idler *idler;
104         Ecore_Animator *animator;
105         volatile bool ready_to_draw;
106
107         /* Map View Preferences */
108         maps_view_type_e type;
109         char *language;
110         bool buildings_enabled;
111         bool traffic_enabled;
112         bool public_transit_enabled;
113         bool scalebar_enabled;
114
115         /* To check hit_test */
116         int screen_dpi;
117         int min_hit_area;
118
119         void *maps_plugin_view_handle;
120 } maps_view_s;
121
122
123 /* ---------------------------------------------------------------------------*/
124
125
126 const gsize _MAPS_VIEW_LANGUAGE_MAX_LENGTH = MAPS_BASE_TYPE_MAX_LEN;
127
128
129 /* ---------------------------------------------------------------------------*/
130
131 extern plugin::plugin_s *__extract_plugin(maps_service_h maps);
132 extern int _maps_view_event_data_set_type(const maps_view_event_data_h event, maps_view_event_type_e event_type);
133 extern int _maps_view_event_data_set_gesture_type(const maps_view_event_data_h event, maps_view_gesture_e gesture_type);
134 extern int _maps_view_event_data_set_action_type(const maps_view_event_data_h event, maps_view_action_e action_type);
135 extern int _maps_view_event_data_set_center(const maps_view_event_data_h event, const maps_coordinates_h center);
136 extern int _maps_view_event_data_set_delta(const maps_view_event_data_h event, int delta_x, int delta_y);
137 extern int _maps_view_event_data_set_position(const maps_view_event_data_h event, int x, int y);
138 extern int _maps_view_event_data_set_fingers(const maps_view_event_data_h event, int fingers);
139 extern int _maps_view_event_data_set_zoom_factor(const maps_view_event_data_h event, double zoom_factor);
140 extern int _maps_view_event_data_set_rotation_angle(const maps_view_event_data_h event, double rotation_angle);
141 extern int _maps_view_event_data_set_object(const maps_view_event_data_h event, const maps_view_object_h object);
142 extern int _maps_view_event_data_create(maps_view_event_data_h *event);
143 extern int _maps_view_object_set_view(const maps_view_object_h object, const maps_view_h view);
144 maps_view_event_data_h _maps_view_create_event_data(maps_view_event_type_e type);
145 void _maps_view_invoke_event_callback(const maps_view_h view, const maps_view_event_data_h event_data);
146 int _maps_view_set_inertia_enabled(const maps_view_h view, bool enabled);
147 extern bool _maps_view_object_overlay_cb(int index, int total, maps_view_object_h object, void *user_data);
148 extern int _maps_view_object_overlay_operation(maps_view_h view, maps_view_object_h object, maps_view_object_operation_e operation);
149 static int __maps_view_set_center(maps_view_h view, maps_coordinates_h coordinates, bool internal);
150 int _maps_view_move_center(maps_view_h view, const int delta_x, const int delta_y);
151 int _maps_view_get_plugin_center(const maps_view_h view, maps_coordinates_h *center);
152 int _maps_coordinates_copy(maps_coordinates_h orig, maps_coordinates_h dest);
153
154 /* ---------------------------------------------------------------------------*/
155
156
157 /* TODO: Apply this approach for other cases, particularly, in maps_service.h*/
158 const plugin::interface_s *__get_plugin_interface(maps_view_h view)
159 {
160         const plugin::plugin_s *p =
161                 __extract_plugin(((maps_view_s *)view)->maps);
162         return (p) ? (&p->interface) : plugin::get_empty_interface_ptr();
163 }
164
165
166 /* ---------------------------------------------------------------------------*/
167
168
169 static void __maps_view_on_event_empty_cb(maps_view_event_type_e type,
170         maps_view_event_data_h event_data, void *user_data)
171 {
172         /* empty */
173 }
174
175 //LCOV_EXCL_START
176 session::command_queue *__maps_view_select_q()
177 {
178         /*
179          *  This is a draw-enforcing mode, when the rendering and drawing
180          *  of the map is happening as fast as it possible.
181          *  This mode is good when the Map View is a single active widget
182          *  of the App.
183          *  In this mode we are relying on the ecore main loop and the
184          *  assumption, that loop steps will apear continuously, not
185          *  simultaneously.
186          *  https://docs.enlightenment.org/efl/1.15.0/Ecore_Main_Loop_Page.html
187          */
188         return session::command_queue_sync::interface();
189
190         /*
191          * This is an analogy of previous mode, but with thread safety
192          * implemented
193          */
194         /*return session::command_queue_async::interface();*/
195
196         /*
197          *  This is a thread-friendly mode, when all heavy computations
198          *  are performed in the "idle" mode.
199          *  This mode is good for apps, which has other active widgets in
200          *  addition to Map View.
201          *  This approach allows compression of repeating commands as well
202          */
203         /* return session::command_queue_view::interface(); */
204 }
205
206 bool _maps_view_is_gesture_available(maps_view_h view, maps_view_gesture_e gesture)
207 {
208         if (!view)
209                 return false;
210         maps_view_s *v = (maps_view_s *)view;
211         return v->gesture_available[gesture];
212 }
213
214 maps_view_action_e _maps_view_get_gesture_action(maps_view_h view, maps_view_gesture_e gesture)
215 {
216         if (!view)
217                 return MAPS_VIEW_ACTION_NONE;
218         maps_view_s *v = (maps_view_s *)view;
219         return v->gesture_actions[gesture];
220 }
221
222 void *_maps_view_get_maps_service_ptr(maps_view_h view)
223 {
224         if (!view)
225                 return NULL;
226         maps_view_s *v = (maps_view_s *)view;
227         return v->maps;
228 }
229
230 int _maps_view_on_overlay_update_all(maps_view_h view)
231 {
232         if (!view)
233                 return MAPS_ERROR_INVALID_PARAMETER;
234
235         maps_view_s *v = (maps_view_s *)view;
236         if (!v->view_objects)
237                 return MAPS_ERROR_NOT_FOUND;
238         return maps_item_list_foreach(v->view_objects, NULL, _maps_view_object_overlay_cb, v->clipper);
239 }
240 //LCOV_EXCL_STOP
241
242 int _maps_view_on_object_operation(maps_view_h view, maps_view_object_h object, maps_view_object_operation_e operation)
243 {
244         if (!view)
245                 return  MAPS_ERROR_INVALID_PARAMETER;
246
247         maps_view_object_type_e type;
248         maps_view_object_get_type(object, &type);
249         if (type == MAPS_VIEW_OBJECT_OVERLAY) {
250                 return _maps_view_object_overlay_operation(view, object, operation);
251         } else {
252                 if(!__get_plugin_interface(view)->maps_plugin_on_object)
253                         return  MAPS_ERROR_INVALID_PARAMETER;
254
255                 return __get_plugin_interface(view)->maps_plugin_on_object(view, object, operation);
256         }
257 }
258
259 //LCOV_EXCL_START
260 static void __on_canvas_tap(void *data, Evas *e, Evas_Object *obj, void *event_info)
261 {
262         MAPS_LOGI("__on_canvas_tap");
263         if (!event_info || !data)
264                 return;
265
266         /* Extract the view ptr */
267         maps_view_s *v = (maps_view_s *)data;
268         if (!v->finger_stream)
269                 return;
270
271         /* Detect & Process the gesture */
272         v->finger_stream->tap((Evas_Event_Mouse_Down *)event_info);
273 }
274
275 static void __on_canvas_up(void *data, Evas *e, Evas_Object *obj, void *event_info)
276 {
277         MAPS_LOGI("__on_canvas_up");
278         if (!event_info || !data)
279                 return;
280
281         /* Extract the view ptr */
282         maps_view_s *v = (maps_view_s *)data;
283         if (!v->finger_stream)
284                 return;
285
286         /* Detect & Process the gesture */
287         v->finger_stream->up((Evas_Event_Mouse_Up *)event_info);
288 }
289
290 static void __on_canvas_line(void *data, Evas *e, Evas_Object *obj, void *event_info)
291 {
292         MAPS_LOGI("__on_canvas_line");
293         if (!event_info || !data)
294                 return;
295
296         /*  Extract view ptr */
297         maps_view_s *v = (maps_view_s *)data;
298         if (!v->finger_stream)
299                 return;
300
301         /* Detect & Process the gesture */
302         v->finger_stream->move((Evas_Event_Mouse_Move *)event_info);
303 }
304
305 static void __on_canvas_multi_tap(void *data, Evas *e, Evas_Object *obj, void *event_info)
306 {
307         MAPS_LOGI("__on_canvas_multi_tap");
308         if (!event_info || !data)
309                 return;
310
311         /*  Extract view ptr */
312         maps_view_s *v = (maps_view_s *)data;
313         if (!v->finger_stream)
314                 return;
315
316         /* Detect & Process the gesture */
317         v->finger_stream->multi_tap((Evas_Event_Multi_Down *)event_info);
318 }
319
320 static void __on_canvas_multi_up(void *data, Evas *e, Evas_Object *obj, void *event_info)
321 {
322         MAPS_LOGI("__on_canvas_multi_up");
323         if (!event_info || !data)
324                 return;
325
326         /*  Extract view ptr */
327         maps_view_s *v = (maps_view_s *)data;
328         if (!v->finger_stream)
329                 return;
330
331         /* Detect & Process the gesture */
332         v->finger_stream->multi_up((Evas_Event_Multi_Up *)event_info);
333 }
334
335 static void __on_canvas_multi_line(void *data, Evas *e, Evas_Object *obj, void *event_info)
336 {
337         MAPS_LOGI("__on_canvas_multi_line");
338         if (!event_info || !data)
339                 return;
340
341         /*  Extract view ptr */
342         maps_view_s *v = (maps_view_s *)data;
343         if (!v->finger_stream)
344                 return;
345
346         /* Detect & Process the gesture */
347         v->finger_stream->multi_move((Evas_Event_Multi_Move *)event_info);
348 }
349 //LCOV_EXCL_STOP
350
351 static int __maps_plugin_render_map(const maps_view_h view,
352         const maps_coordinates_h coordinates, const double zoom_factor, const double rotation_angle)
353 {
354         if (!view || !coordinates)
355                 return MAPS_ERROR_INVALID_PARAMETER;
356
357         return __get_plugin_interface(view)->maps_plugin_render_map(view,
358                                                                                 coordinates, zoom_factor, rotation_angle);
359 }
360
361 //LCOV_EXCL_START
362 void _maps_view_set_idle_listener(const maps_view_h view,
363         void (*callback)(void *user_data), void *user_data)
364 {
365         if (!view)
366                 return;
367         maps_view_s *v = (maps_view_s *)view;
368         v->idle_listener.callback = callback;
369         v->idle_listener.user_data = user_data;
370 }
371
372 void _maps_view_halt_inertial_camera(maps_view_h view)
373 {
374         maps_view_s *v = (maps_view_s *)view;
375         if (v && v->inertial_camera && v->inertial_camera->is_transiting()) {
376                 v->inertial_camera->set_transiting(false);
377                 g_usleep(0);
378         }
379 }
380
381 static Eina_Bool __maps_view_on_idle_cb(void *data)
382 {
383         if (!data)
384                 return ECORE_CALLBACK_RENEW;
385
386         maps_view_s *v = (maps_view_s *)data;
387
388         bool is_transiting = false;
389         bool is_continue = false;
390
391         view::inertial_gesture *ig = v->inertial_gesture;
392         if (ig && ig->is_transiting()) {
393                 is_transiting |= true;
394                 is_continue |= ig->next_transition_step();
395                 g_usleep(5*1000);
396         }
397
398         view::inertial_camera *ic = v->inertial_camera;
399         if (ic && ic->is_transiting()) {
400                 is_transiting |= true;
401                 is_continue |= ic->next_transition_step();
402                 __maps_plugin_render_map(v,
403                                          ic->get_cur_center(),
404                                          ic->get_cur_zoom_factor(),
405                                          ic->get_cur_rotation_angle());
406                 _maps_coordinates_copy(ic->get_cur_center(), v->center);
407
408                 _maps_view_on_overlay_update_all(v);
409                 g_usleep(10*1000);
410         }
411
412         if (is_transiting && !is_continue) {
413                 maps_view_event_data_h ed = _maps_view_create_event_data(MAPS_VIEW_EVENT_READY);
414                 if (ed) {
415                         _maps_view_invoke_event_callback(v, ed);
416                         maps_view_event_data_destroy(ed);
417                 }
418         }
419
420         return ECORE_CALLBACK_RENEW; // same as EINA_TRUE
421 }
422
423 static Eina_Bool __maps_view_animator_cb(void *data)
424 {
425         return ECORE_CALLBACK_RENEW;
426 }
427 //LCOV_EXCL_STOP
428
429 void __maps_view_ready(const maps_view_h view)
430 {
431         if (!view) return;
432
433         maps_view_s *v = (maps_view_s*)view;
434         v->ready = true;
435
436         _maps_view_set_inertia_enabled(view, true);
437
438         /* Invoke user registered event callback */
439         maps_view_event_data_h ed = _maps_view_create_event_data(MAPS_VIEW_EVENT_READY);
440         if (ed) {
441                 _maps_view_invoke_event_callback(view, ed);
442                 maps_view_event_data_destroy(ed);
443         }
444 }
445
446
447 /* ----------------------CREATE AND DESTROY-----------------------------------*/
448
449 //LCOV_EXCL_START
450 static void __maps_view_parent_resize_cb(void *data, Evas *e, Evas_Object *obj, void *event_info)
451 {
452         maps_view_s *v = (maps_view_s*)data;
453
454         int x, y, w, h, ox, oy, ow, oh;
455
456         /* get geometries of evas object to check how much are changed */
457         evas_object_geometry_get(v->parent, &x, &y, &w, &h);
458         evas_object_geometry_get(v->panel, &ox, &oy, &ow, &oh);
459
460         /* compensate difference of center to keep the map image not to move for eyes after ready */
461         if (v->ready)
462                 _maps_view_move_center(v, (x - ox) / 2, (y - oy) / 2);
463
464         /* set center with stored value */
465         _maps_view_get_plugin_center(v, &v->center);
466         maps_view_set_screen_location(v, x, y, w, h);
467 }
468
469 static void __maps_view_panel_resize_cb(void *data, Evas *e, Evas_Object *obj, void *event_info)
470 {
471         maps_view_s *v = (maps_view_s*)data;
472
473         int x, y, w, h, ox, oy, ow, oh;
474
475         /* get geometries of evas object to check how much are changed */
476         evas_object_geometry_get(v->panel, &x, &y, &w, &h);
477         evas_object_geometry_get(v->clipper, &ox, &oy, &ow, &oh);
478
479         /* compensate difference of center to keep the map image not to move for eyes after ready */
480         if (v->ready)
481                 _maps_view_move_center(v, (x - ox) / 2, (y - oy) / 2);
482
483         /* set center with stored value */
484         _maps_view_get_plugin_center(v, &v->center);
485         maps_view_set_screen_location(v, x, y, w, h);
486 }
487 //LCOV_EXCL_STOP
488
489 static void __maps_view_create_panel(maps_view_h view, Evas_Object *obj)
490 {
491         if (!view || !obj)
492                 return;
493
494         maps_view_s *v = (maps_view_s*)view;
495
496         /* Initialize the panel */
497         if (!strncmp(evas_object_type_get(obj), "image", strlen("image"))) {
498                 /* if obj is Evas_Image object */
499                 MAPS_LOGD("The panel is a Evas_Image");
500                 v->parent = NULL;
501                 v->panel = obj;
502                 evas_object_event_callback_add(v->panel, EVAS_CALLBACK_RESIZE, __maps_view_panel_resize_cb, v);
503         } else {
504                 /* if obj is the other kind of (smart) objects */
505                 v->parent = obj;
506                 v->panel = evas_object_image_add(evas_object_evas_get(v->parent));
507                 evas_object_smart_member_add(v->panel, v->parent);
508                 evas_object_event_callback_add(v->parent, EVAS_CALLBACK_RESIZE, __maps_view_parent_resize_cb, v);
509
510                 if (evas_object_visible_get(v->parent))
511                         evas_object_show(v->panel);
512                 else
513                         evas_object_hide(v->panel);
514
515                 /* Equal size of a panel object and a parent object */
516                 int x, y, w, h;
517                 evas_object_geometry_get(v->parent, &x, &y, &w, &h);
518                 evas_object_move(v->panel, x, y);
519                 evas_object_resize(v->panel, w, h);
520                 evas_object_image_fill_set(v->panel, 0, 0, w, h);
521         }
522         evas_object_image_filled_set(v->panel, EINA_FALSE);
523 }
524
525 /* Create the panel and link it to the instance of Maps Service */
526 EXPORT_API int maps_view_create(maps_service_h maps, Evas_Object *obj, maps_view_h *view)
527 {
528         if (!maps_condition_check_maps_feature())
529                 return MAPS_ERROR_NOT_SUPPORTED;
530         if (!maps)
531                 return MAPS_ERROR_INVALID_PARAMETER;
532         if (!maps_condition_check_service_supported(maps, MAPS_SERVICE_VIEW))
533                 return MAPS_ERROR_NOT_SUPPORTED;
534         if (!obj || !view)
535                 return MAPS_ERROR_INVALID_PARAMETER;
536         if (!maps_condition_check_privilege())
537                 return MAPS_ERROR_PERMISSION_DENIED;
538
539         maps_view_s *v = g_slice_new0(maps_view_s);
540         if (!v) {
541                 //LCOV_EXCL_START
542                 MAPS_LOGE("OUT_OF_MEMORY(0x%08x)", MAPS_ERROR_OUT_OF_MEMORY);
543                 return MAPS_ERROR_OUT_OF_MEMORY;
544                 //LCOV_EXCL_STOP
545         }
546
547         /* Initialize the list with visual objects */
548         maps_item_list_create(&v->view_objects);
549
550         /* Initialize the panel */
551         __maps_view_create_panel(v, obj);
552
553         v->maps_plugin_view_handle = NULL;
554
555         /* Set up event callbacks by default */
556         const int event_callback_cnt =
557                 sizeof(v->event_callbacks) / sizeof(v->event_callbacks[0]);
558         for(int i = 0; i < event_callback_cnt; i ++) {
559                 v->event_callbacks[i].callback = __maps_view_on_event_empty_cb;
560                 v->event_callbacks[i].user_data = NULL;
561         }
562
563         /* Assign gestures to actions */
564         v->gesture_actions[MAPS_VIEW_GESTURE_SCROLL] = MAPS_VIEW_ACTION_NONE;
565         v->gesture_actions[MAPS_VIEW_GESTURE_ZOOM] = MAPS_VIEW_ACTION_ZOOM;
566         v->gesture_actions[MAPS_VIEW_GESTURE_TAP] = MAPS_VIEW_ACTION_NONE;
567         v->gesture_actions[MAPS_VIEW_GESTURE_DOUBLE_TAP] = MAPS_VIEW_ACTION_ZOOM_IN;
568         v->gesture_actions[MAPS_VIEW_GESTURE_2_FINGER_TAP] = MAPS_VIEW_ACTION_ZOOM_OUT;
569         v->gesture_actions[MAPS_VIEW_GESTURE_ROTATE] = MAPS_VIEW_ACTION_ROTATE;
570         v->gesture_actions[MAPS_VIEW_GESTURE_LONG_PRESS] = MAPS_VIEW_ACTION_NONE;
571         v->gesture_actions[MAPS_VIEW_GESTURE_NONE] = MAPS_VIEW_ACTION_NONE;
572
573         /* Set up gesture availability */
574         v->gesture_available[MAPS_VIEW_GESTURE_SCROLL] = true;
575         v->gesture_available[MAPS_VIEW_GESTURE_ZOOM] = true;
576         v->gesture_available[MAPS_VIEW_GESTURE_TAP] = true;
577         v->gesture_available[MAPS_VIEW_GESTURE_DOUBLE_TAP] = true;
578         v->gesture_available[MAPS_VIEW_GESTURE_2_FINGER_TAP] = true;
579         v->gesture_available[MAPS_VIEW_GESTURE_ROTATE] = true;
580         v->gesture_available[MAPS_VIEW_GESTURE_LONG_PRESS] = true;
581         v->gesture_available[MAPS_VIEW_GESTURE_NONE] = false;
582
583         /* Gesture Processing */
584         v->finger_stream = new view::finger_event_stream(v);
585         if (!v->finger_stream) {
586                 //LCOV_EXCL_START
587                 MAPS_LOGE("OUT_OF_MEMORY(0x%08x)", MAPS_ERROR_OUT_OF_MEMORY);
588                 return MAPS_ERROR_OUT_OF_MEMORY;
589                 //LCOV_EXCL_STOP
590         }
591         evas_object_event_callback_add(v->panel, EVAS_CALLBACK_MOUSE_DOWN, __on_canvas_tap, v);
592         evas_object_event_callback_add(v->panel, EVAS_CALLBACK_MOUSE_UP, __on_canvas_up, v);
593         evas_object_event_callback_add(v->panel, EVAS_CALLBACK_MOUSE_MOVE, __on_canvas_line, v);
594
595         evas_object_event_callback_add(v->panel, EVAS_CALLBACK_MULTI_DOWN, __on_canvas_multi_tap, v);
596         evas_object_event_callback_add(v->panel, EVAS_CALLBACK_MULTI_UP, __on_canvas_multi_up, v);
597         evas_object_event_callback_add(v->panel, EVAS_CALLBACK_MULTI_MOVE, __on_canvas_multi_line, v);
598
599         /* Set up canvas and Ecore */
600         v->canvas = evas_object_evas_get(v->panel);
601         /*v->ee = ecore_evas_ecore_evas_get(v->canvas);*/
602
603         v->clipper = evas_object_rectangle_add(v->canvas);
604
605         /* Link with Maps Service */
606         v->maps = maps;
607
608         /* Set up canvas and Ecore */
609         v->language = g_strdup("en-US");
610
611         /* Add an idle handler */
612         v->idler = ecore_idler_add(__maps_view_on_idle_cb, v);
613
614         /* Set up the animation frame rate */
615         /*ecore_animator_frametime_set(0.1);*/
616
617         /* Create the animator and assign the drawing task */
618         v->animator = ecore_animator_add(__maps_view_animator_cb, v);
619
620         /* Set up the output pointer to the Maps View */
621         *view = (maps_view_h) v;
622
623         if (__get_plugin_interface(v)) {
624                 /* Notify the Plugin, that the view is created */
625                 if (__get_plugin_interface(v)->maps_plugin_create_map_view)
626                         __get_plugin_interface(v)->maps_plugin_create_map_view(*view, __maps_view_ready);
627                 else
628                         MAPS_LOGE("ERROR!! maps_plugin_create_map_view function pointer is null");
629
630                 /* Set up zoom and rotation */
631                 if (__get_plugin_interface(v)->maps_plugin_get_min_zoom_level)
632                         __get_plugin_interface(v)->maps_plugin_get_min_zoom_level(v, &v->min_zoom_level);
633                 else
634                         MAPS_LOGE("ERROR!! maps_plugin_get_min_zoom_level function pointer is null");
635
636                 if (__get_plugin_interface(v)->maps_plugin_get_max_zoom_level)
637                         __get_plugin_interface(v)->maps_plugin_get_max_zoom_level(v, &v->max_zoom_level);
638                 else
639                         MAPS_LOGE("ERROR!! maps_plugin_get_max_zoom_level function pointer is null");
640         }
641
642         if (v->min_zoom_level <= 0)
643                 v->min_zoom_level = 2;
644         if (v->max_zoom_level <= 0)
645                 v->max_zoom_level = 2;
646
647         v->zoom_level = v->min_zoom_level;
648         v->zoom_factor = double(v->zoom_level);
649         v->rotation_angle = 0.;
650
651         maps_coordinates_create(.0, .0, &v->center);
652
653         v->type = MAPS_VIEW_TYPE_NORMAL;
654         v->buildings_enabled = false;
655         v->traffic_enabled = false;
656         v->public_transit_enabled = false;
657
658         /* To check hit_test */
659         maps_get_screen_dpi(&v->screen_dpi);
660         v->min_hit_area = MAX(20, v->screen_dpi / 5);
661
662         /* Update map view */
663         __maps_view_set_center(v, v->center, TRUE);
664
665         return MAPS_ERROR_NONE;
666 }
667
668 /* Destroy the panel and unlink it from the instance of Maps Service */
669 EXPORT_API int maps_view_destroy(maps_view_h view)
670 {
671         if (!maps_condition_check_maps_feature())
672                 return MAPS_ERROR_NOT_SUPPORTED;
673         if (!view)
674                 return MAPS_ERROR_INVALID_PARAMETER;
675         if (!maps_condition_check_privilege())
676                 return MAPS_ERROR_PERMISSION_DENIED;
677
678         maps_view_s *v = (maps_view_s *) view;
679
680         /* Unregister gesture processing */
681         if (v->finger_stream)
682                 delete v->finger_stream;
683         v->finger_stream = NULL;
684
685         evas_object_event_callback_del(v->panel, EVAS_CALLBACK_MOUSE_DOWN, __on_canvas_tap);
686         evas_object_event_callback_del(v->panel, EVAS_CALLBACK_MOUSE_UP, __on_canvas_up);
687         evas_object_event_callback_del(v->panel, EVAS_CALLBACK_MOUSE_MOVE, __on_canvas_line);
688
689         evas_object_event_callback_del(v->panel, EVAS_CALLBACK_MULTI_DOWN, __on_canvas_multi_tap);
690         evas_object_event_callback_del(v->panel, EVAS_CALLBACK_MULTI_UP, __on_canvas_multi_up);
691         evas_object_event_callback_del(v->panel, EVAS_CALLBACK_MULTI_MOVE, __on_canvas_multi_line);
692
693
694         /* Unregister idle handler */
695         if (v->idler)
696                 ecore_idler_del(v->idler);
697
698         view::inertial_camera *inertial_camera = v->inertial_camera;
699         v->inertial_camera = NULL;
700         v->idle_listener.callback = NULL;
701
702         /* Delete the animator */
703         if (v->animator)
704                 ecore_animator_del(v->animator);
705
706         /* Notify the Plugin, that the view is to be destroyed */
707         if (__get_plugin_interface(view)) {
708                 if (__get_plugin_interface(view)->maps_plugin_destroy_map_view)
709                         __get_plugin_interface(view)->maps_plugin_destroy_map_view(view);
710                 else
711                         MAPS_LOGE("ERROR!! maps_plugin_destroy_map_view function pointer is null");
712         }
713
714         /* Destroy a visual panel */
715         if (v->panel)
716                 evas_object_del(v->panel);
717
718         if (v->clipper)
719                 evas_object_del(v->clipper);
720
721         if (v->center)
722                 maps_coordinates_destroy(v->center);
723
724         if (v->area)
725                 maps_area_destroy(v->area);
726
727         /* Destroy the list with visual objects */
728         maps_item_list_remove_all(v->view_objects, maps_view_object_destroy);
729         maps_item_list_destroy(v->view_objects);
730
731         if (v->language)
732                 g_free(v->language);
733
734         g_slice_free(maps_view_s, v);
735
736         if (inertial_camera)
737                 delete inertial_camera;
738
739         return MAPS_ERROR_NONE;
740 }
741
742 //LCOV_EXCL_START
743 int _maps_view_set_center_directly(const maps_view_h view,
744                                                                 const maps_coordinates_h coordinates)
745 {
746         if (!view || !coordinates)
747                 return MAPS_ERROR_INVALID_PARAMETER;
748
749         maps_view_s *v = (maps_view_s *) view;
750         if (v->center != coordinates) {
751                 if (v->center)
752                         maps_coordinates_destroy(v->center);
753                 maps_coordinates_clone(coordinates, &v->center);
754         }
755         return MAPS_ERROR_NONE;
756 }
757
758 int _maps_view_get_plugin_center(const maps_view_h view,
759                                                                 maps_coordinates_h *center)
760 {
761         if (!view || !center)
762                 return MAPS_ERROR_INVALID_PARAMETER;
763
764         return __get_plugin_interface(view)->maps_plugin_get_center(view, center);
765 }
766 //LCOV_EXCL_STOP
767
768 /*----------------------MAP ZOOM, ROTATE, SET CENTER--------------------------*/
769
770 /* Show the map with a given position centered using current zoom level and
771  * rotation angle */
772
773 static int __maps_view_set_center(maps_view_h view, maps_coordinates_h coordinates, bool internal)
774 {
775         if (!view || !coordinates)
776                 return MAPS_ERROR_INVALID_PARAMETER;
777         double zoom_factor = 1.;
778         int error = maps_view_get_zoom_factor(view, &zoom_factor);
779         if (error != MAPS_ERROR_NONE)
780                 return error;
781
782         double rotation_angle = 0.;
783         error = maps_view_get_orientation(view, &rotation_angle);
784         if (error != MAPS_ERROR_NONE)
785                 return error;
786
787         maps_view_s *v = (maps_view_s *) view;
788
789         /* Set up the target for camera inertial movement */
790         if(v->inertial_camera && !internal)
791                 v->inertial_camera->set_targets(coordinates,
792                                                 zoom_factor,
793                                                 rotation_angle);
794         else
795                 /* Rund rendering in the plugin */
796                 error = __maps_plugin_render_map(view,
797                                                  coordinates,
798                                                  zoom_factor,
799                                                  rotation_angle);
800
801         if (v->center != coordinates) {
802                 maps_coordinates_destroy(v->center);
803                 maps_coordinates_clone(coordinates, &v->center);
804         }
805
806         _maps_view_on_overlay_update_all(view);
807
808         if (!internal) {
809                 /* Invoke user registered event callback */
810                 maps_view_event_data_h ed =
811                         _maps_view_create_event_data(MAPS_VIEW_EVENT_ACTION);
812                 if(ed) {
813                         _maps_view_event_data_set_action_type(ed, MAPS_VIEW_ACTION_SCROLL);
814                         _maps_view_event_data_set_center(ed, v->center);
815                         _maps_view_invoke_event_callback(v, ed);
816                         maps_view_event_data_destroy(ed);
817                 }
818         }
819
820         return error;
821 }
822
823 EXPORT_API int maps_view_set_center(maps_view_h view, maps_coordinates_h coordinates)
824 {
825         if (!maps_condition_check_maps_feature() || !maps_condition_check_internet_feature())
826                 return MAPS_ERROR_NOT_SUPPORTED;
827         if (!view || !coordinates)
828                 return MAPS_ERROR_INVALID_PARAMETER;
829         if (!maps_condition_check_privilege())
830                 return MAPS_ERROR_PERMISSION_DENIED;
831
832         return __maps_view_set_center(view, coordinates, FALSE);
833 }
834
835 //LCOV_EXCL_START
836 int _maps_view_move_center(maps_view_h view, const int delta_x, const int delta_y)
837 {
838         if (!view)
839                 return MAPS_ERROR_INVALID_PARAMETER;
840
841         int error = __get_plugin_interface(view)->maps_plugin_move_center(view, delta_x, delta_y);
842
843         /* update position of overlay objects */
844         _maps_view_on_overlay_update_all(view);
845
846         /* Invoke user registered event callback */
847         maps_view_event_data_h ed =
848                 _maps_view_create_event_data(MAPS_VIEW_EVENT_ACTION);
849         if (ed) {
850                 _maps_view_event_data_set_action_type(ed, MAPS_VIEW_ACTION_SCROLL);
851                 _maps_view_event_data_set_delta(ed, delta_x, delta_y);
852                 _maps_view_invoke_event_callback(view, ed);
853                 maps_view_event_data_destroy(ed);
854         }
855
856         return error;
857 }
858 //LCOV_EXCL_STOP
859
860 EXPORT_API int maps_view_set_scalebar_enabled(const maps_view_h view, bool enable)
861 {
862         if (!maps_condition_check_maps_feature() || !maps_condition_check_internet_feature())
863                 return MAPS_ERROR_NOT_SUPPORTED;
864         if (!view)
865                 return MAPS_ERROR_INVALID_PARAMETER;
866         if (!maps_condition_check_view_data_supported(view, MAPS_VIEW_SCALEBAR))
867                 return MAPS_ERROR_NOT_SUPPORTED;
868         if (!maps_condition_check_privilege())
869                 return MAPS_ERROR_PERMISSION_DENIED;
870
871         return __get_plugin_interface(view)->maps_plugin_set_scalebar(view, enable);
872 }
873
874 EXPORT_API int maps_view_get_scalebar_enabled(const maps_view_h view, bool *enabled)
875 {
876         if (!maps_condition_check_maps_feature())
877                 return MAPS_ERROR_NOT_SUPPORTED;
878         if (!view)
879                 return MAPS_ERROR_INVALID_PARAMETER;
880         if (!maps_condition_check_view_data_supported(view, MAPS_VIEW_SCALEBAR))
881                 return MAPS_ERROR_NOT_SUPPORTED;
882         if (!enabled)
883                 return MAPS_ERROR_INVALID_PARAMETER;
884
885         return __get_plugin_interface(view)->maps_plugin_get_scalebar(view, enabled);
886 }
887
888 EXPORT_API int maps_view_get_center(const maps_view_h view, maps_coordinates_h *coordinates)
889 {
890         if (!maps_condition_check_maps_feature())
891                 return MAPS_ERROR_NOT_SUPPORTED;
892         if (!view || !coordinates)
893                 return MAPS_ERROR_INVALID_PARAMETER;
894         maps_view_s *v = (maps_view_s *) view;
895         return maps_coordinates_clone(v->center, coordinates);
896 }
897
898 EXPORT_API int maps_view_set_zoom_level(maps_view_h view, int level)
899 {
900         if (!maps_condition_check_maps_feature() || !maps_condition_check_internet_feature())
901                 return MAPS_ERROR_NOT_SUPPORTED;
902         if (!view)
903                 return MAPS_ERROR_INVALID_PARAMETER;
904         if (!maps_condition_check_privilege())
905                 return MAPS_ERROR_PERMISSION_DENIED;
906
907         maps_view_s *v = (maps_view_s *) view;
908         int new_level = level;
909         if (new_level < v->min_zoom_level) new_level = v->min_zoom_level;
910         if (new_level > v->max_zoom_level) new_level = v->max_zoom_level;
911
912         /* Add inertia to the zoom process */
913         if (v->inertial_camera)
914                 v->inertial_camera->set_zoom_target(double(new_level)); //LCOV_EXCL_LINE
915
916         v->zoom_level = new_level;
917         v->zoom_factor = double(new_level); /* Update the integer  zoom level too */
918
919         const int error = maps_view_set_center(view, v->center);
920
921         /* Invoke user registered event callback */
922         maps_view_event_data_h ed =
923                 _maps_view_create_event_data(MAPS_VIEW_EVENT_ACTION);
924         if (ed) {
925                 _maps_view_event_data_set_action_type(ed, MAPS_VIEW_ACTION_ZOOM);
926                 _maps_view_event_data_set_zoom_factor(ed, v->zoom_factor);
927                 _maps_view_invoke_event_callback(v, ed);
928                 maps_view_event_data_destroy(ed);
929         }
930
931         return error;
932 }
933
934 EXPORT_API int maps_view_get_zoom_level(const maps_view_h view, int *level)
935 {
936         if (!maps_condition_check_maps_feature())
937                 return MAPS_ERROR_NOT_SUPPORTED;
938         if (!view || !level)
939                 return MAPS_ERROR_INVALID_PARAMETER;
940         maps_view_s *v = (maps_view_s *) view;
941         *level = v->zoom_level;
942         return MAPS_ERROR_NONE;
943 }
944
945 EXPORT_API int maps_view_set_min_zoom_level(maps_view_h view, int level)
946 {
947         if (!maps_condition_check_maps_feature())
948                 return MAPS_ERROR_NOT_SUPPORTED;
949         if (!view)
950                 return MAPS_ERROR_INVALID_PARAMETER;
951         if (!maps_condition_check_privilege())
952                 return MAPS_ERROR_PERMISSION_DENIED;
953
954         maps_view_s *v = (maps_view_s *) view;
955         int min_zoom_level = -1;
956         __get_plugin_interface(v)->maps_plugin_get_min_zoom_level(view, &min_zoom_level);
957         if (min_zoom_level < 0)
958                 return MAPS_ERROR_INVALID_OPERATION;
959         if ((level < min_zoom_level) || (level > v->max_zoom_level))
960                 return MAPS_ERROR_INVALID_PARAMETER;
961         v->min_zoom_level = level;
962         if (v->min_zoom_level > v->zoom_level)
963                 maps_view_set_zoom_level(view, v->min_zoom_level);
964         return MAPS_ERROR_NONE;
965 }
966
967 EXPORT_API int maps_view_get_min_zoom_level(const maps_view_h view, int *min_zoom_level)
968 {
969         if (!maps_condition_check_maps_feature())
970                 return MAPS_ERROR_NOT_SUPPORTED;
971         if (!view || !min_zoom_level)
972                 return MAPS_ERROR_INVALID_PARAMETER;
973         maps_view_s *v = (maps_view_s *) view;
974         *min_zoom_level = v->min_zoom_level;
975         return MAPS_ERROR_NONE;
976 }
977
978 EXPORT_API int maps_view_set_max_zoom_level(maps_view_h view, int level)
979 {
980         if (!maps_condition_check_maps_feature())
981                 return MAPS_ERROR_NOT_SUPPORTED;
982         if (!view)
983                 return MAPS_ERROR_INVALID_PARAMETER;
984         if (!maps_condition_check_privilege())
985                 return MAPS_ERROR_PERMISSION_DENIED;
986
987         maps_view_s *v = (maps_view_s *) view;
988         int max_zoom_level = -1;
989         __get_plugin_interface(v)->maps_plugin_get_max_zoom_level(view, &max_zoom_level);
990         if (max_zoom_level < 0)
991                 return MAPS_ERROR_INVALID_OPERATION;
992         if ((level < v->min_zoom_level) || (level > max_zoom_level))
993                 return MAPS_ERROR_INVALID_PARAMETER;
994         v->max_zoom_level = level;
995         if (v->max_zoom_level < v->zoom_level)
996                 maps_view_set_zoom_level(view, v->max_zoom_level);
997         return MAPS_ERROR_NONE;
998 }
999
1000 EXPORT_API int maps_view_get_max_zoom_level(const maps_view_h view, int *max_zoom_level)
1001 {
1002         if (!maps_condition_check_maps_feature())
1003                 return MAPS_ERROR_NOT_SUPPORTED;
1004         if (!view || !max_zoom_level)
1005                 return MAPS_ERROR_INVALID_PARAMETER;
1006         maps_view_s *v = (maps_view_s *) view;
1007         *max_zoom_level = v->max_zoom_level;
1008         return MAPS_ERROR_NONE;
1009 }
1010
1011 int _maps_view_set_zoom_rotate(maps_view_h view,
1012                                                                 const bool zoom_changed,
1013                                                                 const double factor,
1014                                                                 const bool rotation_changed,
1015                                                                 const double angle)
1016 {
1017         if (!view)
1018                 return MAPS_ERROR_INVALID_PARAMETER;
1019
1020         maps_view_s *v = (maps_view_s *) view;
1021
1022         /* 1. Apply new zoom and orientation values */
1023         if (zoom_changed) {
1024                 double new_factor = factor;
1025                 if (new_factor < v->min_zoom_level) new_factor = v->min_zoom_level;
1026                 if (new_factor > v->max_zoom_level) new_factor = v->max_zoom_level;
1027
1028                 /* Add inertia to the zoom process */
1029                 if (v->inertial_camera)
1030                         v->inertial_camera->set_zoom_target(new_factor);
1031
1032                 /* Update Map View zoom factor */
1033                 v->zoom_factor = new_factor;
1034
1035                 /* Update the integer zoom level too */
1036                 v->zoom_level = int(new_factor);
1037         }
1038
1039         if (rotation_changed) {
1040                 /* Add inertia to the rotation process */
1041                 if (v->inertial_camera)
1042                         v->inertial_camera->set_rotation_target(angle); //LCOV_EXCL_LINE
1043
1044                 /* Update Map View rotation angle */
1045                 v->rotation_angle = angle;
1046         }
1047
1048         /* 2. Send update center command to the plugin */
1049         const int error = maps_view_set_center(view, v->center);
1050
1051         /* Notify the user about changes */
1052         if (zoom_changed) {
1053                 /* Invoke user registered event callback */
1054                 maps_view_event_data_h ed =
1055                         _maps_view_create_event_data(MAPS_VIEW_EVENT_ACTION);
1056                 if (ed) {
1057                         //LCOV_EXCL_START
1058                         _maps_view_event_data_set_action_type(ed, MAPS_VIEW_ACTION_ZOOM);
1059                         _maps_view_event_data_set_zoom_factor(ed, v->zoom_factor);
1060                         _maps_view_invoke_event_callback(v, ed);
1061                         maps_view_event_data_destroy(ed);
1062                         //LCOV_EXCL_STOP
1063                 }
1064         }
1065
1066         if (rotation_changed) {
1067                 /* Invoke user registered event callback */
1068                 maps_view_event_data_h ed =
1069                         _maps_view_create_event_data(MAPS_VIEW_EVENT_ACTION);
1070                 if (ed) {
1071                         _maps_view_event_data_set_action_type(ed, MAPS_VIEW_ACTION_ROTATE);
1072                         _maps_view_event_data_set_rotation_angle(ed, v->rotation_angle);
1073                         _maps_view_invoke_event_callback(v, ed);
1074                         maps_view_event_data_destroy(ed);
1075                 }
1076         }
1077
1078         return error;
1079 }
1080
1081 EXPORT_API int maps_view_set_zoom_factor(const maps_view_h view,
1082                                         const double factor)
1083 {
1084         if (!maps_condition_check_maps_feature())
1085                 return MAPS_ERROR_NOT_SUPPORTED;
1086         if (!view)
1087                 return MAPS_ERROR_INVALID_PARAMETER;
1088
1089         maps_view_s *v = (maps_view_s *) view;
1090         double new_factor = factor;
1091         if (new_factor < v->min_zoom_level) new_factor = v->min_zoom_level;
1092         if (new_factor > v->max_zoom_level) new_factor = v->max_zoom_level;
1093
1094         return _maps_view_set_zoom_rotate(view, true, new_factor, false, .0);
1095 }
1096
1097 EXPORT_API int maps_view_get_zoom_factor(const maps_view_h view, double *factor)
1098 {
1099         if (!maps_condition_check_maps_feature())
1100                 return MAPS_ERROR_NOT_SUPPORTED;
1101         if (!view || !factor)
1102                 return MAPS_ERROR_INVALID_PARAMETER;
1103         maps_view_s *v = (maps_view_s *) view;
1104         *factor = v->zoom_factor;
1105         return MAPS_ERROR_NONE;
1106 }
1107
1108 EXPORT_API int maps_view_set_orientation(maps_view_h view, double angle)
1109 {
1110         if (!maps_condition_check_maps_feature() || !maps_condition_check_internet_feature())
1111                 return MAPS_ERROR_NOT_SUPPORTED;
1112         if (!view)
1113                 return MAPS_ERROR_INVALID_PARAMETER;
1114         if (!maps_condition_check_privilege())
1115                 return MAPS_ERROR_PERMISSION_DENIED;
1116
1117         /* Add inertia to the rotation process */
1118         maps_view_s *v = (maps_view_s *)view;
1119         if (v->inertial_camera)
1120                 v->inertial_camera->set_rotation_target(angle); //LCOV_EXCL_LINE
1121
1122         return _maps_view_set_zoom_rotate(view, false, .0, true, angle);
1123 }
1124
1125 EXPORT_API int maps_view_get_orientation(const maps_view_h view, double *angle)
1126 {
1127         if (!maps_condition_check_maps_feature())
1128                 return MAPS_ERROR_NOT_SUPPORTED;
1129         if (!view || !angle)
1130                 return MAPS_ERROR_INVALID_PARAMETER;
1131         maps_view_s *v = (maps_view_s *) view;
1132         *angle = v->rotation_angle;
1133         return MAPS_ERROR_NONE;
1134 }
1135
1136
1137 /*----------------------SCREEN <--> GEOGRAPHY---------------------------------*/
1138
1139
1140 /* Converting screen coordinates to geographical */
1141 EXPORT_API int maps_view_screen_to_geolocation(maps_view_h view,
1142         int x, int y, maps_coordinates_h *coordinates)
1143 {
1144         if (!maps_condition_check_maps_feature())
1145                 return MAPS_ERROR_NOT_SUPPORTED;
1146         if (!view || !coordinates)
1147                 return MAPS_ERROR_INVALID_PARAMETER;
1148         if (!maps_condition_check_privilege())
1149                 return MAPS_ERROR_PERMISSION_DENIED;
1150
1151         int posx = 0;
1152         int posy = 0;
1153         maps_view_get_screen_location(view, &posx, &posy, NULL, NULL);
1154         return __get_plugin_interface(view)->
1155                                                 maps_plugin_screen_to_geography(view, x - posx, y - posy, coordinates);
1156 }
1157
1158 EXPORT_API int maps_view_geolocation_to_screen(const maps_view_h view,
1159         const maps_coordinates_h coordinates, int *x, int *y)
1160 {
1161         if (!maps_condition_check_maps_feature())
1162                 return MAPS_ERROR_NOT_SUPPORTED;
1163         if (!view || !coordinates || !x || !y)
1164                 return MAPS_ERROR_INVALID_PARAMETER;
1165         if (!maps_condition_check_privilege())
1166                 return MAPS_ERROR_PERMISSION_DENIED;
1167
1168         int posx = 0;
1169         int posy = 0;
1170         maps_view_get_screen_location(view, &posx, &posy, NULL, NULL);
1171         const int error = __get_plugin_interface(view)->
1172                                                 maps_plugin_geography_to_screen(view, coordinates, x, y);
1173         *x += posx;
1174         *y += posy;
1175         return error;
1176 }
1177
1178
1179 /* --------------------MAPS VIEW PREFERENCES----------------------------------*/
1180
1181
1182 EXPORT_API int maps_view_set_type(maps_view_h view, maps_view_type_e type)
1183 {
1184         if (!maps_condition_check_maps_feature() || !maps_condition_check_internet_feature())
1185                 return MAPS_ERROR_NOT_SUPPORTED;
1186         if (!view)
1187                 return MAPS_ERROR_INVALID_PARAMETER;
1188         if ((type < MAPS_VIEW_TYPE_NORMAL) || (type > MAPS_VIEW_TYPE_HYBRID))
1189                 return MAPS_ERROR_INVALID_PARAMETER;
1190         if (!maps_condition_check_privilege())
1191                 return MAPS_ERROR_PERMISSION_DENIED;
1192
1193         maps_view_s *v = (maps_view_s *) view;
1194         v->type = type;
1195         return maps_view_set_center(view, v->center);
1196 }
1197
1198 EXPORT_API int maps_view_get_type(const maps_view_h view, maps_view_type_e *type)
1199 {
1200         if (!maps_condition_check_maps_feature())
1201                 return MAPS_ERROR_NOT_SUPPORTED;
1202         if (!view || !type)
1203                 return MAPS_ERROR_INVALID_PARAMETER;
1204         maps_view_s *v = (maps_view_s *) view;
1205         *type = v->type;
1206         return MAPS_ERROR_NONE;
1207 }
1208
1209 EXPORT_API int maps_view_set_buildings_enabled(maps_view_h view, bool enabled)
1210 {
1211         if (!maps_condition_check_maps_feature() || !maps_condition_check_internet_feature())
1212                 return MAPS_ERROR_NOT_SUPPORTED;
1213         if (!view)
1214                 return MAPS_ERROR_INVALID_PARAMETER;
1215         if (!maps_condition_check_view_data_supported(view, MAPS_VIEW_BUILDING))
1216                 return MAPS_ERROR_NOT_SUPPORTED;
1217         if (!maps_condition_check_privilege())
1218                 return MAPS_ERROR_PERMISSION_DENIED;
1219
1220         maps_view_s *v = (maps_view_s *) view;
1221         v->buildings_enabled = enabled;
1222         return maps_view_set_center(view, v->center);
1223 }
1224
1225 EXPORT_API int maps_view_get_buildings_enabled(const maps_view_h view, bool *enabled)
1226 {
1227         if (!maps_condition_check_maps_feature())
1228                 return MAPS_ERROR_NOT_SUPPORTED;
1229         if (!view)
1230                 return MAPS_ERROR_INVALID_PARAMETER;
1231         if (!maps_condition_check_view_data_supported(view, MAPS_VIEW_BUILDING))
1232                 return MAPS_ERROR_NOT_SUPPORTED;
1233         if (!enabled)
1234                 return MAPS_ERROR_INVALID_PARAMETER;
1235         maps_view_s *v = (maps_view_s *) view;
1236         *enabled = v->buildings_enabled;
1237         return MAPS_ERROR_NONE;
1238 }
1239
1240 EXPORT_API int maps_view_set_traffic_enabled(maps_view_h view, bool enabled)
1241 {
1242         if (!maps_condition_check_maps_feature() || !maps_condition_check_internet_feature())
1243                 return MAPS_ERROR_NOT_SUPPORTED;
1244         if (!view)
1245                 return MAPS_ERROR_INVALID_PARAMETER;
1246         if (!maps_condition_check_view_data_supported(view, MAPS_VIEW_TRAFFIC))
1247                 return MAPS_ERROR_NOT_SUPPORTED;
1248         if (!maps_condition_check_privilege())
1249                 return MAPS_ERROR_PERMISSION_DENIED;
1250
1251         maps_view_s *v = (maps_view_s *) view;
1252         v->traffic_enabled = enabled;
1253         return maps_view_set_center(view, v->center);
1254 }
1255
1256 EXPORT_API int maps_view_get_traffic_enabled(const maps_view_h view, bool *enabled)
1257 {
1258         if (!maps_condition_check_maps_feature())
1259                 return MAPS_ERROR_NOT_SUPPORTED;
1260         if (!view)
1261                 return MAPS_ERROR_INVALID_PARAMETER;
1262         if (!maps_condition_check_view_data_supported(view, MAPS_VIEW_TRAFFIC))
1263                 return MAPS_ERROR_NOT_SUPPORTED;
1264         if (!enabled)
1265                 return MAPS_ERROR_INVALID_PARAMETER;
1266         maps_view_s *v = (maps_view_s *) view;
1267         *enabled = v->traffic_enabled;
1268         return MAPS_ERROR_NONE;
1269 }
1270
1271 EXPORT_API int maps_view_set_public_transit_enabled(maps_view_h view, bool enabled)
1272 {
1273         if (!maps_condition_check_maps_feature() || !maps_condition_check_internet_feature())
1274                 return MAPS_ERROR_NOT_SUPPORTED;
1275         if (!view)
1276                 return MAPS_ERROR_INVALID_PARAMETER;
1277         if (!maps_condition_check_view_data_supported(view, MAPS_VIEW_PUBLIC_TRANSIT))
1278                 return MAPS_ERROR_NOT_SUPPORTED;
1279         if (!maps_condition_check_privilege())
1280                 return MAPS_ERROR_PERMISSION_DENIED;
1281
1282         maps_view_s *v = (maps_view_s *) view;
1283         v->public_transit_enabled = enabled;
1284         return maps_view_set_center(view, v->center);
1285 }
1286
1287 EXPORT_API int maps_view_get_public_transit_enabled(const maps_view_h view, bool *enabled)
1288 {
1289         if (!maps_condition_check_maps_feature())
1290                 return MAPS_ERROR_NOT_SUPPORTED;
1291         if (!view)
1292                 return MAPS_ERROR_INVALID_PARAMETER;
1293         if (!maps_condition_check_view_data_supported(view, MAPS_VIEW_PUBLIC_TRANSIT))
1294                 return MAPS_ERROR_NOT_SUPPORTED;
1295         if (!enabled)
1296                 return MAPS_ERROR_INVALID_PARAMETER;
1297         maps_view_s *v = (maps_view_s *) view;
1298         *enabled = v->public_transit_enabled;
1299         return MAPS_ERROR_NONE;
1300 }
1301
1302 int _maps_view_set_inertia_enabled(maps_view_h view, bool enabled)
1303 {
1304         if (!view)
1305                 return MAPS_ERROR_INVALID_PARAMETER;
1306         maps_view_s *v = (maps_view_s *) view;
1307
1308         if (enabled) {
1309                 if (!v->inertial_gesture) {
1310                         v->inertial_gesture = new view::inertial_gesture(view);
1311                         if (!v->inertial_gesture) {
1312                                 //LCOV_EXCL_START
1313                                 MAPS_LOGE("OUT_OF_MEMORY(0x%08x)", MAPS_ERROR_OUT_OF_MEMORY);
1314                                 return MAPS_ERROR_OUT_OF_MEMORY;
1315                                 //LCOV_EXCL_STOP
1316                         }
1317                 }
1318
1319                 if (!v->inertial_camera) {
1320                         v->inertial_camera = new view::inertial_camera(view);
1321                         if (!v->inertial_camera) {
1322                                 //LCOV_EXCL_START
1323                                 MAPS_LOGE("OUT_OF_MEMORY(0x%08x)", MAPS_ERROR_OUT_OF_MEMORY);
1324                                 return MAPS_ERROR_OUT_OF_MEMORY;
1325                                 //LCOV_EXCL_STOP
1326                         }
1327                 }
1328
1329                 v->finger_stream->set_gesture_detector(v->inertial_gesture);
1330         } else {
1331                 v->finger_stream->set_gesture_detector(new view::gesture_detector_statemachine(view));
1332
1333                 if (v->inertial_gesture) {
1334                         /* Unset Inertial Camera */
1335                         if (v->inertial_gesture->is_transiting()) {
1336                                 v->inertial_gesture->set_transiting(false);
1337                                 sleep(0);
1338                         }
1339                         view::inertial_gesture *inertial_gesture = v->inertial_gesture;
1340                         v->inertial_gesture = NULL;
1341                         delete inertial_gesture;
1342                 }
1343
1344                 if (v->inertial_camera) {
1345                         /* Unset Inertial Camera */
1346                         if (v->inertial_camera->is_transiting()) {
1347                                 v->inertial_camera->set_transiting(false);
1348                                 sleep(0);
1349                         }
1350                         view::inertial_camera *inertial_camera = v->inertial_camera;
1351                         v->inertial_camera = NULL;
1352                         delete inertial_camera;
1353                 }
1354         }
1355         return MAPS_ERROR_NONE;
1356 }
1357
1358 //LCOV_EXCL_START
1359 EXPORT_API int maps_view_get_inertia_enabled(maps_view_h view, bool *enabled)
1360 {
1361         if (!maps_condition_check_maps_feature())
1362                 return MAPS_ERROR_NOT_SUPPORTED;
1363         if (!view || !enabled)
1364                 return MAPS_ERROR_INVALID_PARAMETER;
1365
1366         maps_view_s *v = (maps_view_s *) view;
1367         *enabled = v->inertial_camera != NULL;
1368         return MAPS_ERROR_NONE;
1369 }
1370 //LCOV_EXCL_STOP
1371
1372 EXPORT_API int maps_view_set_language(maps_view_h view, const char *language)
1373 {
1374         if (!maps_condition_check_maps_feature() || !maps_condition_check_internet_feature())
1375                 return MAPS_ERROR_NOT_SUPPORTED;
1376         if (!view || !language)
1377                 return MAPS_ERROR_INVALID_PARAMETER;
1378         if (!maps_condition_check_privilege())
1379                 return MAPS_ERROR_PERMISSION_DENIED;
1380
1381         maps_view_s *v = (maps_view_s *) view;
1382         int error = maps_set_string(language, _MAPS_VIEW_LANGUAGE_MAX_LENGTH, &v->language);
1383         if (error == MAPS_ERROR_NONE)
1384                 error = maps_view_set_center(view, v->center);
1385         return error;
1386 }
1387
1388 EXPORT_API int maps_view_get_language(const maps_view_h view, char **language)
1389 {
1390         if (!maps_condition_check_maps_feature())
1391                 return MAPS_ERROR_NOT_SUPPORTED;
1392         if (!view || !language)
1393                 return MAPS_ERROR_INVALID_PARAMETER;
1394         return maps_get_string(((maps_view_s *) view)->language,
1395                 _MAPS_VIEW_LANGUAGE_MAX_LENGTH, language);
1396 }
1397
1398
1399 /* --------------------MAPS PANEL MANIPULATIONS-------------------------------*/
1400
1401 EXPORT_API int maps_view_get_viewport(const maps_view_h view, Evas_Object **viewport)
1402 {
1403         if (!maps_condition_check_maps_feature())
1404                 return MAPS_ERROR_NOT_SUPPORTED;
1405         if (!view || !viewport)
1406                 return MAPS_ERROR_INVALID_PARAMETER;
1407         maps_view_s *v = (maps_view_s *) view;
1408         *viewport = v->panel;
1409         return MAPS_ERROR_NONE;
1410 }
1411
1412 int _maps_view_get_parent(const maps_view_h view, Evas_Object **parent)
1413 {
1414         if (!view || !parent)
1415                 return MAPS_ERROR_INVALID_PARAMETER;
1416         maps_view_s *v = (maps_view_s *) view;
1417         *parent = v->parent;
1418         return MAPS_ERROR_NONE;
1419 }
1420
1421 int _maps_view_get_clipper(const maps_view_h view, Evas_Object **clipper)
1422 {
1423         if (!view || !clipper)
1424                 return MAPS_ERROR_INVALID_PARAMETER;
1425         maps_view_s *v = (maps_view_s *) view;
1426         *clipper = v->clipper;
1427         return MAPS_ERROR_NONE;
1428 }
1429
1430 EXPORT_API int maps_view_set_screen_location(maps_view_h view, int x, int y, int width, int height)
1431 {
1432         if (!maps_condition_check_maps_feature() || !maps_condition_check_internet_feature())
1433                 return MAPS_ERROR_NOT_SUPPORTED;
1434         if (!view)
1435                 return MAPS_ERROR_INVALID_PARAMETER;
1436         if (!maps_condition_check_privilege())
1437                 return MAPS_ERROR_PERMISSION_DENIED;
1438
1439         int error = maps_view_move(view, x, y);
1440         if (error == MAPS_ERROR_NONE)
1441                 error = maps_view_resize(view, width, height);
1442         return error;
1443 }
1444
1445 EXPORT_API int maps_view_get_screen_location(const maps_view_h view, int *x, int *y, int *width, int *height)
1446 {
1447         if (!maps_condition_check_maps_feature())
1448                 return MAPS_ERROR_NOT_SUPPORTED;
1449         if (!view || (!x && !y && !width && !height))
1450                 return MAPS_ERROR_INVALID_PARAMETER;
1451         maps_view_s *v = (maps_view_s *) view;
1452         evas_object_geometry_get(v->panel, x, y, width, height);
1453         return MAPS_ERROR_NONE;
1454 }
1455
1456 EXPORT_API int maps_view_move(maps_view_h view, int x, int y)
1457 {
1458         if (!maps_condition_check_maps_feature() || !maps_condition_check_internet_feature())
1459                 return MAPS_ERROR_NOT_SUPPORTED;
1460         if (!view)
1461                 return MAPS_ERROR_INVALID_PARAMETER;
1462
1463         maps_view_s *v = (maps_view_s *) view;
1464         evas_object_move(v->panel, x, y);
1465         evas_object_move(v->clipper, x, y);
1466         return MAPS_ERROR_NONE;
1467 }
1468
1469 EXPORT_API int maps_view_resize(maps_view_h view, int width, int height)
1470 {
1471         if (!maps_condition_check_maps_feature() || !maps_condition_check_internet_feature())
1472                 return MAPS_ERROR_NOT_SUPPORTED;
1473         if (!view || (width <= 0) || (height <= 0))
1474                 return MAPS_ERROR_INVALID_PARAMETER;
1475         if (!maps_condition_check_privilege())
1476                 return MAPS_ERROR_PERMISSION_DENIED;
1477
1478         maps_view_s *v = (maps_view_s *) view;
1479         evas_object_resize(v->panel, width, height);
1480         evas_object_resize(v->clipper, width, height);
1481         evas_object_image_fill_set(v->panel, 0, 0, width, height);
1482         return __maps_view_set_center(view, v->center, TRUE);
1483 }
1484
1485 EXPORT_API int maps_view_set_visibility(maps_view_h view, bool visible)
1486 {
1487         if (!maps_condition_check_maps_feature())
1488                 return MAPS_ERROR_NOT_SUPPORTED;
1489         if (!view)
1490                 return MAPS_ERROR_INVALID_PARAMETER;
1491
1492         maps_view_s *v = (maps_view_s *) view;
1493         if (visible)
1494                 evas_object_show(v->panel);
1495         else
1496                 evas_object_hide(v->panel);
1497         return MAPS_ERROR_NONE;
1498 }
1499
1500 EXPORT_API int maps_view_get_visibility(const maps_view_h view, bool *visible)
1501 {
1502         if (!maps_condition_check_maps_feature())
1503                 return MAPS_ERROR_NOT_SUPPORTED;
1504         if (!view || !visible)
1505                 return MAPS_ERROR_INVALID_PARAMETER;
1506
1507         maps_view_s *v = (maps_view_s *) view;
1508         *visible = evas_object_visible_get(v->panel) == EINA_TRUE;
1509         return MAPS_ERROR_NONE;
1510 }
1511
1512 //LCOV_EXCL_START
1513 int _maps_view_redraw(const maps_view_h view)
1514 {
1515         if (!view)
1516                 return MAPS_ERROR_INVALID_PARAMETER;
1517
1518         maps_view_s *v = (maps_view_s *) view;
1519
1520         /* Signal to the animator, that we are ready to draw */
1521         v->ready_to_draw = true;
1522
1523         return MAPS_ERROR_NONE;
1524 }
1525 //LCOV_EXCL_STOP
1526
1527 /* ---------------------USER CONTROL------------------------------------------*/
1528
1529
1530 EXPORT_API int maps_view_set_event_cb(maps_view_h view, maps_view_event_type_e type,
1531         maps_view_on_event_cb callback, void *user_data)
1532 {
1533         if (!maps_condition_check_maps_feature())
1534                 return MAPS_ERROR_NOT_SUPPORTED;
1535         if (!view || !callback)
1536                 return MAPS_ERROR_INVALID_PARAMETER;
1537         if ((type < MAPS_VIEW_EVENT_GESTURE) || (type > MAPS_VIEW_EVENT_READY))
1538                 return MAPS_ERROR_INVALID_PARAMETER;
1539
1540         maps_view_s *v = (maps_view_s *) view;
1541         v->event_callbacks[type].callback = callback;
1542         v->event_callbacks[type].user_data = user_data;
1543
1544         return MAPS_ERROR_NONE;
1545 }
1546
1547 EXPORT_API int maps_view_unset_event_cb(maps_view_h view, maps_view_event_type_e type)
1548 {
1549         if (!maps_condition_check_maps_feature())
1550                 return MAPS_ERROR_NOT_SUPPORTED;
1551         if (!view)
1552                 return MAPS_ERROR_INVALID_PARAMETER;
1553         if ((type < MAPS_VIEW_EVENT_GESTURE) || (type > MAPS_VIEW_EVENT_READY))
1554                 return MAPS_ERROR_INVALID_PARAMETER;
1555
1556         maps_view_s *v = (maps_view_s *) view;
1557         v->event_callbacks[type].callback = __maps_view_on_event_empty_cb;
1558         v->event_callbacks[type].user_data = NULL;
1559
1560         return MAPS_ERROR_NONE;
1561 }
1562
1563 EXPORT_API int maps_view_set_gesture_enabled(maps_view_h view, maps_view_gesture_e gesture, bool enabled)
1564 {
1565         if (!maps_condition_check_maps_feature())
1566                 return MAPS_ERROR_NOT_SUPPORTED;
1567         if (!view)
1568                 return MAPS_ERROR_INVALID_PARAMETER;
1569         if ((gesture < MAPS_VIEW_GESTURE_NONE) || (gesture > MAPS_VIEW_GESTURE_LONG_PRESS))
1570                 return MAPS_ERROR_INVALID_PARAMETER;
1571         maps_view_s *v = (maps_view_s *) view;
1572         v->gesture_available[gesture] = enabled;
1573         return MAPS_ERROR_NONE;
1574 }
1575
1576 EXPORT_API int maps_view_get_gesture_enabled(const maps_view_h view, maps_view_gesture_e gesture, bool *enabled)
1577 {
1578         if (!maps_condition_check_maps_feature())
1579                 return MAPS_ERROR_NOT_SUPPORTED;
1580         if (!view || !enabled)
1581                 return MAPS_ERROR_INVALID_PARAMETER;
1582         if ((gesture < MAPS_VIEW_GESTURE_NONE) || (gesture > MAPS_VIEW_GESTURE_LONG_PRESS))
1583                 return MAPS_ERROR_INVALID_PARAMETER;
1584         maps_view_s *v = (maps_view_s *) view;
1585         *enabled = v->gesture_available[gesture];
1586         return MAPS_ERROR_NONE;
1587 }
1588
1589
1590 /* ---------------------VISUAL OBJECTS ON THE MAP-----------------------------*/
1591
1592 EXPORT_API int maps_view_add_object(maps_view_h view, maps_view_object_h object)
1593 {
1594         if (!maps_condition_check_maps_feature())
1595                 return MAPS_ERROR_NOT_SUPPORTED;
1596         if (!view || !object)
1597                 return MAPS_ERROR_INVALID_PARAMETER;
1598         if (!maps_condition_check_privilege())
1599                 return MAPS_ERROR_PERMISSION_DENIED;
1600
1601         int error = MAPS_ERROR_NONE;
1602         do {
1603                 /* Add Visual Object to the list of View Visual Objects */
1604                 maps_view_s *v = (maps_view_s *)view;
1605                 error = maps_item_list_append(v->view_objects, object, NULL);
1606                 if (error != MAPS_ERROR_NONE)
1607                         break;
1608
1609                 /* Link the object with the View */
1610                 error = _maps_view_object_set_view(object, view);
1611                 if (error != MAPS_ERROR_NONE)
1612                         break;
1613
1614                 /* Notify the plugin about added object */
1615                 error = _maps_view_on_object_operation(view, object, MAPS_VIEW_OBJECT_ADD);
1616                 if (error != MAPS_ERROR_NONE)
1617                         break;
1618
1619                 /* Redraw the view */
1620                 error = _maps_view_redraw(v);
1621                 if (error != MAPS_ERROR_NONE)
1622                         break;
1623
1624                 return MAPS_ERROR_NONE;
1625         } while (false);
1626
1627         return error; //LCOV_EXCL_LINE
1628 }
1629
1630 EXPORT_API int maps_view_remove_object(maps_view_h view, maps_view_object_h object)
1631 {
1632         if (!maps_condition_check_maps_feature())
1633                 return MAPS_ERROR_NOT_SUPPORTED;
1634         if (!view || !object)
1635                 return MAPS_ERROR_INVALID_PARAMETER;
1636         if (!maps_condition_check_privilege())
1637                 return MAPS_ERROR_PERMISSION_DENIED;
1638
1639         int error = MAPS_ERROR_NONE;
1640         do {
1641                 /* Remove Visual Object from the list of View Visual Objects */
1642                 maps_view_s *v = (maps_view_s *)view;
1643                 error =  maps_item_list_remove(v->view_objects, object, maps_view_object_destroy);
1644                 if (error != MAPS_ERROR_NONE)
1645                         return error;
1646
1647                 /* Redraw the view */
1648                 error = _maps_view_redraw(v);
1649                 if (error != MAPS_ERROR_NONE)
1650                         return error; //LCOV_EXCL_LINE
1651
1652                 return MAPS_ERROR_NONE;
1653         } while (false);
1654
1655         return error;
1656 }
1657
1658 EXPORT_API int maps_view_remove_all_objects(maps_view_h view)
1659 {
1660         if (!maps_condition_check_maps_feature())
1661                 return MAPS_ERROR_NOT_SUPPORTED;
1662         if (!view)
1663                 return MAPS_ERROR_INVALID_PARAMETER;
1664         if (!maps_condition_check_privilege())
1665                 return MAPS_ERROR_PERMISSION_DENIED;
1666
1667         int error = MAPS_ERROR_NONE;
1668         do {
1669                 maps_view_s *v = (maps_view_s *)view;
1670                 error = maps_item_list_remove_all(v->view_objects, maps_view_object_destroy);
1671                 if (error != MAPS_ERROR_NONE)
1672                         return error;
1673
1674                 /* Redraw the view */
1675                 error = _maps_view_redraw(v);
1676                 if (error != MAPS_ERROR_NONE)
1677                         return error; //LCOV_EXCL_LINE
1678
1679                 return MAPS_ERROR_NONE;
1680         } while (false);
1681
1682         return error;
1683 }
1684
1685 EXPORT_API int maps_view_foreach_object(maps_view_h view, maps_view_object_cb callback, void *user_data)
1686 {
1687         if (!maps_condition_check_maps_feature())
1688                 return MAPS_ERROR_NOT_SUPPORTED;
1689         if (!view || !callback)
1690                 return MAPS_ERROR_INVALID_PARAMETER;
1691         maps_view_s *v = (maps_view_s *)view;
1692         if (!v->view_objects)
1693                 return MAPS_ERROR_NOT_FOUND;
1694         return maps_item_list_foreach(v->view_objects, NULL, callback, user_data);
1695 }
1696
1697
1698 /* ----------------------SEND MAP VIEW CALLBACK TO THE USER-------------------*/
1699
1700 /* TODO: Consider refactoring of send Map View Callbacks to the User */
1701
1702 maps_view_event_data_h _maps_view_create_event_data(maps_view_event_type_e type)
1703 {
1704         maps_view_event_data_h event_data = NULL;
1705         const int error = _maps_view_event_data_create(&event_data);
1706         if (error != MAPS_ERROR_NONE) {
1707                 //LCOV_EXCL_START
1708                 maps_view_event_data_destroy(event_data);
1709                 return NULL;
1710                 //LCOV_EXCL_STOP
1711         }
1712         if (!event_data)
1713                 return NULL;
1714         _maps_view_event_data_set_type(event_data, type);
1715         return event_data;
1716 }
1717
1718 void _maps_view_invoke_event_callback(maps_view_h view, maps_view_event_data_h event_data)
1719 {
1720         if (!view || !event_data)
1721                 return; //LCOV_EXCL_LINE
1722
1723         maps_view_s *v = (maps_view_s *)view;
1724
1725         maps_view_event_type_e type = MAPS_VIEW_EVENT_GESTURE;
1726         maps_view_event_data_get_type(event_data, &type);
1727
1728 #if 0 // log
1729         int maps_view_event_data_get_gesture_type(const maps_view_event_data_h event, maps_view_gesture_e *gesture_type);
1730         int maps_view_event_data_get_action_type(const maps_view_event_data_h event, maps_view_action_e *action_type);
1731         int maps_view_event_data_get_object(const maps_view_event_data_h event, maps_view_object_h *object);
1732         int maps_view_object_get_type(maps_view_object_h object, maps_view_object_type_e *type);
1733
1734         int subtype = 0;
1735         if (type == MAPS_VIEW_EVENT_GESTURE) {
1736                 maps_view_event_data_get_gesture_type(event_data, (maps_view_gesture_e*)&subtype);
1737         } else if (type == MAPS_VIEW_EVENT_ACTION) {
1738                 maps_view_event_data_get_action_type(event_data, (maps_view_action_e*)&subtype);
1739         } else if (type == MAPS_VIEW_EVENT_OBJECT) {
1740                 maps_view_object_h object;
1741                 maps_view_event_data_get_object(event_data, &object);
1742                 maps_view_object_get_type(object, (maps_view_object_type_e*)&subtype);
1743         }
1744         if (type == MAPS_VIEW_EVENT_READY)
1745                 MAPS_LOGD("[invoked event] type=%d, subtype=%d", type, subtype);
1746 #endif
1747
1748         v->event_callbacks[type].callback(type, event_data, v->event_callbacks[type].user_data);
1749 }
1750
1751 /* ----------------------HIT TEST---------------------------------------------*/
1752 /* TODO: consider refactoring of Hit Test features and separation as
1753  *  dedicated classes */
1754
1755 typedef struct _maps_view_hit_test_data_s {
1756         maps_view_s *v;
1757         int x;
1758         int y;
1759         maps_view_object_h object;
1760 } maps_view_hit_test_data_s;
1761
1762
1763 typedef struct _maps_view_collect_poly_object_point_s {
1764         maps_view_s *v;
1765         view::poly_shape_hit_test *pd;
1766 } maps_view_collect_poly_object_point_s;
1767
1768 //LCOV_EXCL_START
1769 static bool __maps_view_object_poly_collect_points_cb(int index, maps_coordinates_h point, void *user_data)
1770 {
1771         if (!point || !user_data)
1772                 return false;
1773
1774         maps_view_collect_poly_object_point_s *cpop =
1775                 (maps_view_collect_poly_object_point_s *)user_data;
1776
1777         int x = 0;
1778         int y = 0;
1779         if (maps_view_geolocation_to_screen(cpop->v, point, &x, &y) == MAPS_ERROR_NONE)
1780                 cpop->pd->add_point(float(x), float(y));
1781
1782         return true;
1783 }
1784
1785 static bool __maps_view_hit_test_cb(int index, int total, maps_view_object_h object, void *user_data)
1786 {
1787         if (!object || !user_data)
1788                 return false;
1789
1790         /* If it is an unvisible object, skip this hit-testing. */
1791         bool visible = false;
1792         maps_view_object_get_visible(object, &visible);
1793         if (!visible) return true;
1794
1795         maps_view_hit_test_data_s *htd = (maps_view_hit_test_data_s *)user_data;
1796
1797         maps_view_object_type_e type;
1798         maps_view_object_get_type(object, &type);
1799         switch(type) {
1800                 case MAPS_VIEW_OBJECT_POLYLINE: {
1801                         view::poly_shape_hit_test pd;
1802                         maps_view_collect_poly_object_point_s cpop = {htd->v, &pd};
1803                         int error = maps_view_object_polyline_foreach_point(object,
1804                                 __maps_view_object_poly_collect_points_cb, &cpop);
1805                         if (error != MAPS_ERROR_NONE)
1806                                 break;
1807
1808                         int width = 0;
1809                         maps_view_object_polyline_get_width(object, &width);
1810                         if (pd.hit_test(float(htd->x), float(htd->y), false, width))
1811                                 htd->object = object;
1812
1813                         break;
1814                 }
1815
1816                 case MAPS_VIEW_OBJECT_POLYGON: {
1817                         view::poly_shape_hit_test pd;
1818                         maps_view_collect_poly_object_point_s cpop = {htd->v, &pd};
1819                         int error = maps_view_object_polygon_foreach_point(object,
1820                                 __maps_view_object_poly_collect_points_cb, &cpop);
1821                         if (error != MAPS_ERROR_NONE)
1822                                 break;
1823
1824                         if (pd.hit_test(float(htd->x), float(htd->y), true))
1825                                 htd->object = object;
1826
1827                         break;
1828                 }
1829                 case MAPS_VIEW_OBJECT_MARKER: {
1830                         maps_coordinates_h c = NULL;
1831                         maps_view_object_marker_get_coordinates(object, &c);
1832
1833                         int x = 0;
1834                         int y = 0;
1835                         maps_view_geolocation_to_screen(htd->v, c, &x, &y);
1836                         maps_coordinates_destroy(c);
1837
1838                         int w = 0;
1839                         int h = 0;
1840                         maps_view_object_marker_get_size(object, &w, &h);
1841
1842                         /* In case of PIN marker type, rearrange the hit-area. */
1843                         maps_view_marker_type_e marker_type;
1844                         maps_view_object_marker_get_type(object, &marker_type);
1845                         if (marker_type == MAPS_VIEW_MARKER_PIN)
1846                                 y -= h / 2;
1847
1848                         /* Add some margin of the hit-area. */
1849                         w = MAX(w, htd->v->min_hit_area);
1850                         h = MAX(h, htd->v->min_hit_area);
1851
1852                         /* Gets a half range to check hit-area */
1853                         int hw = (int)(w / 2. + .5);
1854                         int hh = (int)(h / 2. + .5);
1855
1856                         /* Check hit-area */
1857                         if ((x > (htd->x - hw)) && (x < (htd->x + hw))
1858                            && (y > (htd->y - hh)) && (y < (htd->y + hh))) {
1859                                 htd->object = object;
1860                         }
1861                         break;
1862                 }
1863                 default:
1864                         break;
1865         }
1866
1867         if (htd->object)
1868                 return false;
1869
1870         return true;
1871 }
1872
1873
1874 maps_view_object_h _maps_view_object_hit_test(maps_view_h view, int x, int y, maps_view_gesture_e gesture)
1875 {
1876         if (!view)
1877                 return NULL;
1878
1879         maps_view_s *v = (maps_view_s *)view;
1880
1881         /* Check if we are going to inform anyone about object events */
1882         if (v->event_callbacks[MAPS_VIEW_EVENT_OBJECT].callback
1883                 == __maps_view_on_event_empty_cb)
1884                 return NULL;
1885
1886         /* 1. Iterate through the list of object and test the hit */
1887         maps_view_hit_test_data_s htd = {v, x, y, NULL};
1888         int error = maps_view_foreach_object(view, __maps_view_hit_test_cb, &htd);
1889         if ((error != MAPS_ERROR_NONE) || !htd.object)
1890                 return NULL;
1891
1892         /*g_print("Hit Test: FOUND OBJECT: %p\n", htd.object);*/
1893
1894         /* Invoke user registered event callback */
1895         maps_view_event_data_h ed =
1896                 _maps_view_create_event_data(MAPS_VIEW_EVENT_OBJECT);
1897         if (ed) {
1898                 _maps_view_event_data_set_object(ed, htd.object);
1899                 _maps_view_event_data_set_gesture_type(ed, gesture);
1900                 _maps_view_invoke_event_callback(view, ed);
1901                 maps_view_event_data_destroy(ed);
1902         }
1903
1904         /* 2. Extract test result */
1905         return htd.object;
1906 }
1907 //LCOV_EXCL_STOP
1908
1909 EXPORT_API int maps_view_get_maps_plugin_view_handle(maps_view_h view, void **maps_plugin_view_handle)
1910 {
1911         if (!maps_condition_check_maps_feature())
1912                 return MAPS_ERROR_NOT_SUPPORTED;
1913         if (!view || !maps_plugin_view_handle)
1914                 return MAPS_ERROR_INVALID_PARAMETER;
1915
1916         maps_view_s *v = (maps_view_s *)view;
1917         *maps_plugin_view_handle = v->maps_plugin_view_handle;
1918         return MAPS_ERROR_NONE;
1919 }
1920
1921 EXPORT_API int maps_view_set_maps_plugin_view_handle(maps_view_h view, void *maps_plugin_view_handle)
1922 {
1923         if (!maps_condition_check_maps_feature())
1924                 return MAPS_ERROR_NOT_SUPPORTED;
1925         if (!view)
1926                 return MAPS_ERROR_INVALID_PARAMETER;
1927
1928         maps_view_s *v = (maps_view_s *)view;
1929         v->maps_plugin_view_handle = maps_plugin_view_handle;
1930         return MAPS_ERROR_NONE;
1931 }
1932
1933 EXPORT_API int maps_view_get_scale_factor(maps_view_h view, double *scale_factor)
1934 {
1935         if (!maps_condition_check_maps_feature())
1936                 return MAPS_ERROR_NOT_SUPPORTED;
1937         if (!view || !scale_factor)
1938                 return MAPS_ERROR_INVALID_PARAMETER;
1939
1940         const plugin::interface_s *plugin = __get_plugin_interface(view);
1941         if (!plugin)
1942                 return MAPS_ERROR_INVALID_PARAMETER;
1943         if (!plugin->maps_plugin_get_view_scale_factor)
1944                 return MAPS_ERROR_NOT_SUPPORTED;
1945         return plugin->maps_plugin_get_view_scale_factor(view, scale_factor);
1946 }
1947
1948 EXPORT_API int maps_view_set_scale_factor(maps_view_h view, double scale_factor)
1949 {
1950         if (!maps_condition_check_maps_feature())
1951                 return MAPS_ERROR_NOT_SUPPORTED;
1952         if (!view)
1953                 return MAPS_ERROR_INVALID_PARAMETER;
1954         if (scale_factor < 0.1 || scale_factor > 10.0)
1955                 return MAPS_ERROR_INVALID_PARAMETER;
1956
1957         const plugin::interface_s *plugin = __get_plugin_interface(view);
1958         if (!plugin)
1959                 return MAPS_ERROR_INVALID_PARAMETER;
1960         if (!plugin->maps_plugin_set_view_scale_factor)
1961                 return MAPS_ERROR_NOT_SUPPORTED;
1962
1963         return plugin->maps_plugin_set_view_scale_factor(view, scale_factor);
1964 }
1965