[Coding Style] Polish map.c
[apps/native/sample/adventure.git] / src / item.c
1 #include <Elementary.h>
2 #include <system_settings.h>
3 #include <time.h>
4 #include <stdio.h>
5 #include <stdlib.h>
6 #include <app.h>
7 #include <time.h>
8
9 #include "log.h"
10 #include "conf.h"
11 #include "util.h"
12 #include "city.h"
13 #include "item.h"
14 #include "main_view.h"
15 #include "scroller.h"
16 #include "popup.h"
17 #include "map.h"
18 #include "notification.h"
19 #include "group_info.h"
20 #include "db.h"
21
22 #define _EDJ(o) elm_layout_edje_get(o)
23
24 const char *const DATA_KEY_CITY = "city";
25 const char *const DATA_KEY_MAIN_VIEW_INFO = "mvi";
26
27 const char *const ITEM_EDJE = "item.edj";
28 const char *const BEST_TIME_EDJE = "best_time.edj";
29 const char *const ITEM2_EDJE = "item2.edj";
30 static int color_index[MAXIMUM_SELECTED_CITY] = { 0, 0, 0 };
31
32 void item_reset_color_index(void)
33 {
34         register int i = 0;
35         for (; i < MAXIMUM_SELECTED_CITY; i++) {
36                 if (EINA_FALSE == remove_city_from_map(i))
37                         _E("cannot remove the city");
38
39                 color_index[i] = 0;
40         }
41 }
42
43 void _text_set_here_time(Evas_Object *item, const char *part)
44 {
45         char *timezone_str = NULL;
46         struct tm *local_time = NULL;
47
48         int ret = SYSTEM_SETTINGS_ERROR_NONE;
49         time_t t = 0;
50         char time_result[PATH_LEN] = {0, };
51
52         ret_if(!item);
53         ret_if(!part);
54
55         local_time = localtime(&t);
56         ret_if(!local_time);
57
58         ret = system_settings_get_value_string(SYSTEM_SETTINGS_KEY_LOCALE_TIMEZONE, &timezone_str);
59         if (ret != SYSTEM_SETTINGS_ERROR_NONE)
60                 _E("cannot get the timezone string");
61
62         /* Timezone
63            Asia/Seoul
64          */
65         if (local_time->tm_gmtoff >= 0l)
66                 snprintf(time_result, sizeof(time_result), "%s, +%ld", timezone_str, local_time->tm_gmtoff / 3600l);
67         else
68                 snprintf(time_result, sizeof(time_result), "%s, %ld", timezone_str, local_time->tm_gmtoff / 3600l);
69
70         free(timezone_str);
71
72         elm_object_part_text_set(item, part, timezone_str);
73 }
74
75 static void _item_typing_del_cb(void *data, Evas *e, Evas_Object *obj, void *event_info)
76 {
77         item_destroy_typing(obj);
78 }
79
80 static void _item_typing_down_cb(void *data, Evas_Object *obj, const char *emission, const char *source)
81 {
82         _D("An item is down");
83 }
84
85 static void _item_typing_up_cb(void *data, Evas_Object *obj, const char *emission, const char *source)
86 {
87         Evas_Object *item = obj;
88         Evas_Object *selecting_item = NULL;
89         Evas_Object *entry = NULL;
90         main_view_s *main_view_info = data;
91         struct tm *local_time = NULL;
92         int city = 0;
93         int count = 0;
94         time_t t = 0;
95
96         ret_if(!item);
97         ret_if(!main_view_info);
98         ret_if(!main_view_info->city_list);
99
100         _D("An item is selected");
101
102         time(&t);
103         local_time = localtime(&t);
104
105         if (scroller_is_scrolling(main_view_info->searchlist))
106                 return;
107
108         count = scroller_count_item(main_view_info->city_list);
109         if (count + 1 > MAXIMUM_SELECTED_CITY) {
110                 _D("Cities selected are limited.");
111                 notification_status_message_post("Maximum number of cities reached");
112                 return;
113         }
114
115         city = (int) evas_object_data_get(item, DATA_KEY_CITY);
116         selecting_item = item_create_selecting(main_view_info->city_list, city, local_time, main_view_info);
117         ret_if(!selecting_item);
118         scroller_append_item(main_view_info->city_list, selecting_item);
119         count++;
120
121         if (count > 1) {
122                 elm_object_signal_emit(main_view_info->main_view, "momentic,state,add_description,hide", "");
123                 elm_object_signal_emit(main_view_info->main_view, "momentic,state,next_btn,show", "");
124         } else {
125                 elm_object_signal_emit(main_view_info->main_view, "momentic,state,add_description,show", "");
126                 elm_object_signal_emit(main_view_info->main_view, "momentic,state,next_btn,hide", "");
127         }
128
129         entry = elm_object_part_content_get(main_view_info->searchbar, "entry");
130         elm_entry_entry_set(entry, "");
131         elm_object_focus_set(main_view_info->next_btn, EINA_TRUE);
132 }
133
134 Evas_Object *item_create_typing(Evas_Object *parent, int city, main_view_s *main_view_info)
135 {
136         Evas_Object *item = NULL;
137         city_s *city_info = NULL;
138
139         char *path = NULL;
140         char full_path[PATH_LEN] = {0, };
141         char city_str[PATH_LEN] = {0, };
142
143         retv_if(!parent, NULL);
144
145         path = app_get_resource_path();
146         retv_if(!path, NULL);
147
148         snprintf(full_path, sizeof(full_path), "%s/edje/%s", path, ITEM_EDJE);
149         free(path);
150
151         item = elm_layout_add(parent);
152         retv_if(!item, NULL);
153
154         elm_layout_file_set(item, full_path, "item_typing");
155
156         evas_object_size_hint_weight_set(item, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
157         evas_object_size_hint_align_set(item, EVAS_HINT_FILL, EVAS_HINT_FILL);
158         evas_object_data_set(item, DATA_KEY_CITY, (void *) city);
159         evas_object_event_callback_add(item, EVAS_CALLBACK_DEL, _item_typing_del_cb, NULL);
160         elm_object_signal_callback_add(item, "down", "item", _item_typing_down_cb, NULL);
161         elm_object_signal_callback_add(item, "up", "item", _item_typing_up_cb, main_view_info);
162
163         evas_object_show(item);
164
165         if (city < 0) {
166                 elm_object_part_text_set(item, "city", "No results");
167                 elm_object_signal_emit(item, "disable", "item");
168                 return item;
169         }
170
171         city_info = city_get();
172         if (!city_info) {
173                 _E("Critical, no city information");
174                 evas_object_del(item);
175                 return NULL;
176         }
177
178         snprintf(city_str, sizeof(city_str), "%s, %s", city_info[city].name, city_info[city].nation);
179         elm_object_part_text_set(item, "city", city_str);
180
181         return item;
182 }
183
184 void item_destroy_typing(Evas_Object *item)
185 {
186         ret_if(!item);
187
188         evas_object_event_callback_del(item, EVAS_CALLBACK_DEL, _item_typing_del_cb);
189         elm_object_signal_callback_del(item, "down", "item", _item_typing_down_cb);
190         elm_object_signal_callback_del(item, "up", "item", _item_typing_up_cb);
191
192         evas_object_data_del(item, DATA_KEY_CITY);
193         evas_object_del(item);
194 }
195
196 static void _item_selecting_del_cb(void *data, Evas *e, Evas_Object *obj, void *event_info)
197 {
198         item_destroy_selecting(obj);
199 }
200
201 static void _delete_selecting_item_cb(void *data, Evas_Object *obj, void *event_info)
202 {
203         main_view_s *main_view_info = NULL;
204         Evas_Object *item = data;
205         int count = 0;
206
207         _D("clicked, delete the selected item");
208
209         ret_if(!item);
210
211         main_view_info = evas_object_data_get(item, DATA_KEY_MAIN_VIEW_INFO);
212         ret_if(!main_view_info);
213
214         item_destroy_selecting(item);
215
216         count = scroller_count_item(main_view_info->city_list);
217         if (count > 1) {
218                 elm_object_signal_emit(main_view_info->main_view, "momentic,state,add_description,hide", "");
219                 elm_object_signal_emit(main_view_info->main_view, "momentic,state,next_btn,show", "");
220         } else {
221                 elm_object_signal_emit(main_view_info->main_view, "momentic,state,add_description,show", "");
222                 elm_object_signal_emit(main_view_info->main_view, "momentic,state,next_btn,hide", "");
223         }
224 }
225
226 void _text_set_local_time(Evas_Object *item, const char *part, int city, struct tm *local_time)
227 {
228         city_s *city_info = NULL;
229         int hour = local_time->tm_hour;
230         int minute = local_time->tm_min;
231
232         char time_result[PATH_LEN] = {0, };
233
234         ret_if(!item);
235         ret_if(!part);
236
237         city_info = city_get();
238         ret_if(!city_info);
239
240         if (((double) ((int) city_info[city].timezone)) < city_info[city].timezone) {
241                 minute += 30;
242                 if (minute > 60) {
243                         hour++;
244                         minute -= 60;
245                 }
246         }
247
248         hour -= local_time->tm_gmtoff / 3600l;
249         hour += (int) city_info[city].timezone;
250         if (hour < 0)
251                 hour += 24;
252
253         hour %= 24;
254
255         snprintf(time_result, sizeof(time_result), "%2d:%02d", hour, minute);
256         elm_object_part_text_set(item, part, time_result);
257 }
258
259 Evas_Object *item_create_selecting(Evas_Object *parent, int city, struct tm *local_time, main_view_s *main_view_info)
260 {
261         Evas_Object *item = NULL;
262         Evas_Object *btn = NULL;
263         city_s *city_info = NULL;
264         selecting_info_s *selecting_info = NULL;
265
266         char *path = NULL;
267         char full_path[PATH_LEN] = {0, };
268         char city_str[PATH_LEN] = {0, };
269         char gmt_str[PATH_LEN] = {0, };
270
271         retv_if(!parent, NULL);
272
273         city_info = city_get();
274         goto_if(!city_info, error);
275
276         int i = 0;
277         for (i = 0; i < MAXIMUM_SELECTED_CITY; i++) {
278                 if (color_index[i]) continue;
279
280                 if (EINA_FALSE == add_city_to_map(i, &city_info[city])) {
281                         _E("cannot add a city to the map");
282                         break;
283                 }
284                 break;
285         }
286
287         path = app_get_resource_path();
288         retv_if(!path, NULL);
289
290         snprintf(full_path, sizeof(full_path), "%s/edje/%s", path, ITEM2_EDJE);
291         free(path);
292
293         selecting_info = calloc(1, sizeof(selecting_info_s));
294         retv_if(!selecting_info, NULL);
295         selecting_info->city = city;
296         selecting_info->color = i;
297
298         item = elm_layout_add(parent);
299         retv_if(!item, NULL);
300
301         elm_layout_file_set(item, full_path, "item");
302
303         evas_object_size_hint_weight_set(item, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
304         evas_object_size_hint_align_set(item, EVAS_HINT_FILL, EVAS_HINT_FILL);
305         evas_object_data_set(item, DATA_KEY_MAIN_VIEW_INFO, main_view_info);
306         evas_object_data_set(item, DATA_KEY_SELECTING, selecting_info);
307         evas_object_event_callback_add(item, EVAS_CALLBACK_DEL, _item_selecting_del_cb, NULL);
308         evas_object_show(item);
309
310         btn = elm_button_add(item);
311         if (btn) {
312                 elm_object_style_set(btn, "transparent");
313                 elm_object_part_content_set(item, "delete_event", btn);
314                 evas_object_smart_callback_add(btn, "clicked", _delete_selecting_item_cb, item);
315                 evas_object_show(btn);
316         }
317
318         snprintf(city_str, sizeof(city_str), "%s, %s", city_info[city].name, city_info[city].nation);
319         elm_object_part_text_set(item, "city", city_str);
320
321         if (city_info[city].timezone > 0)
322                 snprintf(gmt_str, sizeof(gmt_str), "GMT +%.1f", city_info[city].timezone);
323         else 
324                 snprintf(gmt_str, sizeof(gmt_str), "GMT %.1f", city_info[city].timezone);
325
326         elm_object_part_text_set(item, "gmt", gmt_str);
327         _text_set_local_time(item, "time", city, local_time);
328
329         if (set_marker(item, i) == EINA_FALSE)
330                 _E("cannot set the marker");
331
332         color_index[i] = 1;
333
334         return item;
335
336 error:
337         if (item)
338                 evas_object_del(item);
339
340         if (selecting_info)
341                 free(selecting_info);
342
343         return NULL;
344 }
345
346 void item_destroy_selecting(Evas_Object *item)
347 {
348         selecting_info_s *selecting_info = NULL;
349
350         ret_if(!item);
351
352         evas_object_data_del(item, DATA_KEY_MAIN_VIEW_INFO);
353         selecting_info = evas_object_data_del(item, DATA_KEY_SELECTING);
354         if (selecting_info) {
355                 if (EINA_FALSE == remove_city_from_map(selecting_info->color))
356                         _E("cannot remove the city");
357
358                 color_index[selecting_info->color] = 0;
359                 free(selecting_info);
360         }
361
362         evas_object_event_callback_del(item, EVAS_CALLBACK_DEL, _item_selecting_del_cb);
363         evas_object_del(item);
364 }
365
366 static void _item_group_del_cb(void *data, Evas *e, Evas_Object *obj, void *event_info)
367 {
368         item_destroy_group(obj);
369 }
370
371 static void _item_group_down_cb(void *data, Evas_Object *obj, const char *emission, const char *source)
372 {
373         _D("An item is down");
374 }
375
376 static Eina_Bool _item_group_up_timer_cb(void *data)
377 {
378         Evas_Object *item = data;
379         Evas_Object *selecting_item = NULL;
380         main_view_s *main_view_info = NULL;
381         group_info_s *group_info = NULL;
382         struct tm *local_time = NULL;
383         time_t t = 0;
384         int i = 0;
385
386         retv_if(!item, ECORE_CALLBACK_CANCEL);
387
388         main_view_info = evas_object_data_get(item, DATA_KEY_MAIN_VIEW_INFO);
389         retv_if(!main_view_info, ECORE_CALLBACK_CANCEL);
390         retv_if(!main_view_info->city_list, ECORE_CALLBACK_CANCEL);
391
392         group_info = evas_object_data_get(item, GROUP_INFO);
393         retv_if(!group_info, ECORE_CALLBACK_CANCEL);
394
395         time(&t);
396         local_time = localtime(&t);
397
398         for (i = 0; i < MAXIMUM_SELECTED_CITY; i++) {
399                 if (!group_info->city[i]) {
400                         _D("No city anymore");
401                         break;
402                 }
403                 selecting_item = item_create_selecting(main_view_info->city_list, group_info->city[i], local_time, main_view_info);
404                 break_if(!selecting_item);
405                 scroller_append_item(main_view_info->city_list, selecting_item);
406         }
407
408         main_view_go_result(main_view_info);
409
410         elm_object_signal_emit(main_view_info->main_view, "momentic,state,drawer,hide", "");
411         //elm_object_signal_emit(main_view_info->main_view, "momentic,state,drawer_btn,hide", "");
412         elm_object_signal_emit(main_view_info->main_view, "momentic,state,result,show", "");
413         elm_object_signal_emit(main_view_info->main_view, "momentic,state,add_description,hide", "");
414
415
416         return ECORE_CALLBACK_CANCEL;
417 }
418
419 static void _item_group_up_cb(void *data, Evas_Object *obj, const char *emission, const char *source)
420 {
421         main_view_s *main_view_info = data;
422         ret_if(!main_view_info);
423         ret_if(!main_view_info->city_list);
424
425         scroller_clear_item(main_view_info->city_list);
426
427         ecore_timer_add(0.4, _item_group_up_timer_cb, obj);
428 }
429
430 static void _delete_group_item_cb(void *data, Evas_Object *obj, void *event_info)
431 {
432         main_view_s *main_view_info = NULL;
433         Evas_Object *item = data;
434         group_info_s *group_info = NULL;
435         int count = 0;
436
437         _D("clicked, delete the group item");
438
439         ret_if(!item);
440
441         main_view_info = evas_object_data_get(item, DATA_KEY_MAIN_VIEW_INFO);
442         ret_if(!main_view_info);
443
444         group_info = evas_object_data_get(item, GROUP_INFO);
445         ret_if(!group_info);
446
447         db_delete_group(main_view_info->moment_info->db, group_info->id);
448         main_view_info->moment_info->group_list = eina_list_remove(main_view_info->moment_info->group_list, group_info);
449         group_info_destroy(group_info);
450
451         item_destroy_group(item);
452
453         count = scroller_count_item(main_view_info->group_scroller);
454         if (count < 1) {
455                 elm_object_signal_emit(main_view_info->main_view, "momentic,state,drawer,noresult,show", "");
456         }
457
458         
459 }
460
461 Evas_Object *item_create_group(Evas_Object *parent, group_info_s *group_info, main_view_s *main_view_info)
462 {
463         Evas_Object *item = NULL;
464         Evas_Object *btn = NULL;
465
466         char *path = NULL;
467         char full_path[PATH_LEN] = {0, };
468
469         retv_if(!parent, NULL);
470
471         path = app_get_resource_path();
472         retv_if(!path, NULL);
473
474         snprintf(full_path, sizeof(full_path), "%s/edje/%s", path, ITEM_EDJE);
475         free(path);
476
477         item = elm_layout_add(parent);
478         retv_if(!item, NULL);
479
480         elm_layout_file_set(item, full_path, "item_group");
481         evas_object_data_set(item, GROUP_INFO, group_info);
482         evas_object_data_set(item, DATA_KEY_MAIN_VIEW_INFO, main_view_info);
483
484         evas_object_size_hint_weight_set(item, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
485         evas_object_size_hint_align_set(item, EVAS_HINT_FILL, EVAS_HINT_FILL);
486         evas_object_event_callback_add(item, EVAS_CALLBACK_DEL, _item_group_del_cb, NULL);
487         elm_object_signal_callback_add(item, "down", "item", _item_group_down_cb, NULL);
488         elm_object_signal_callback_add(item, "up", "item", _item_group_up_cb, main_view_info);
489
490         evas_object_show(item);
491
492         btn = elm_button_add(item);
493         if (btn) {
494                 elm_object_style_set(btn, "transparent");
495                 elm_object_part_content_set(item, "delete_event", btn);
496                 evas_object_smart_callback_add(btn, "clicked", _delete_group_item_cb, item);
497                 evas_object_show(btn);
498         }
499
500         elm_object_part_text_set(item, "title", group_info->title);
501
502         return item;
503 }
504
505 void item_destroy_group(Evas_Object *item)
506 {
507         ret_if(!item);
508
509         evas_object_data_del(item, GROUP_INFO);
510         evas_object_data_del(item, DATA_KEY_MAIN_VIEW_INFO);
511         evas_object_event_callback_del(item, EVAS_CALLBACK_DEL, _item_group_del_cb);
512         elm_object_signal_callback_del(item, "down", "item", _item_group_down_cb);
513         elm_object_signal_callback_del(item, "up", "item", _item_group_up_cb);
514
515         evas_object_del(item);
516 }
517
518 static void _item_padding_del_cb(void *data, Evas *e, Evas_Object *obj, void *event_info)
519 {
520         item_destroy_padding(obj);
521 }
522
523 Evas_Object *item_create_padding(Evas_Object *parent)
524 {
525         Evas_Object *item = NULL;
526
527         char *path = NULL;
528         char full_path[PATH_LEN] = {0, };
529
530         retv_if(!parent, NULL);
531
532         path = app_get_resource_path();
533         retv_if(!path, NULL);
534
535         snprintf(full_path, sizeof(full_path), "%s/edje/%s", path, ITEM_EDJE);
536         free(path);
537
538         item = elm_layout_add(parent);
539         retv_if(!item, NULL);
540
541         elm_layout_file_set(item, full_path, "item_padding");
542
543         evas_object_size_hint_weight_set(item, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
544         evas_object_size_hint_align_set(item, EVAS_HINT_FILL, EVAS_HINT_FILL);
545         evas_object_event_callback_add(item, EVAS_CALLBACK_DEL, _item_padding_del_cb, NULL);
546
547         evas_object_show(item);
548
549         return item;
550 }
551
552 void item_destroy_padding(Evas_Object *item)
553 {
554         ret_if(!item);
555         evas_object_event_callback_del(item, EVAS_CALLBACK_DEL, _item_padding_del_cb);
556         evas_object_del(item);
557 }
558
559 static void _item_best_time_del_cb(void *data, Evas *e, Evas_Object *obj, void *event_info)
560 {
561         item_destroy_best_time(obj);
562 }
563
564 Evas_Object *item_create_best_time(Evas_Object *parent, double start, double end)
565 {
566         Evas_Object *item = NULL;
567
568         char *path = NULL;
569         char full_path[PATH_LEN] = {0, };
570         char time_str[PATH_LEN] = {0, };
571
572         double half;
573         int tmp = 0;
574
575         retv_if(!parent, NULL);
576
577         path = app_get_resource_path();
578         retv_if(!path, NULL);
579
580         snprintf(full_path, sizeof(full_path), "%s/edje/%s", path, BEST_TIME_EDJE);
581         free(path);
582
583         item = elm_layout_add(parent);
584         retv_if(!item, NULL);
585
586         elm_layout_file_set(item, full_path, "best_time");
587
588         evas_object_size_hint_weight_set(item, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
589         evas_object_size_hint_align_set(item, EVAS_HINT_FILL, EVAS_HINT_FILL);
590         evas_object_event_callback_add(item, EVAS_CALLBACK_DEL, _item_best_time_del_cb, NULL);
591
592         elm_object_part_text_set(item, "city", "Best time");
593
594         evas_object_data_set(item, DATA_KEY_BEST_TIME, (void *) 1);
595         evas_object_show(item);
596
597         if (start >= end) {
598                 elm_object_part_text_set(item, "time", "No matched time");
599                 goto out;
600         }
601
602         tmp = start;
603         if (tmp == start) half = 0.0f;
604         else half = 0.5f;
605
606         if (tmp) tmp %= 24;
607         start = ((double) tmp) + half;
608
609         tmp = end;
610         if (tmp == end) half = 0.0f;
611         else half = 0.5f;
612
613         if (tmp) tmp %= 24;
614         end = ((double) tmp) + half;
615
616         _D("HELLO, Best,%f:%f", start, end);
617
618         int start_hour = start;
619         int start_minute = (start_hour == start)? 0 : 30;
620         int end_hour = end;
621         int end_minute = (end_hour == end)? 0 : 30;
622
623         snprintf(time_str, sizeof(time_str), "%d:%02d - %d:%02d", start_hour, start_minute, end_hour, end_minute);
624         elm_object_part_text_set(item, "time",  time_str);
625         if (set_time_range(item, 5, start, end, 0.0f, 0.0f) == EINA_FALSE)
626                 _E("cannot set time range");
627
628 out:
629         return item;
630 }
631
632 void item_destroy_best_time(Evas_Object *item)
633 {
634         ret_if(!item);
635         evas_object_event_callback_del(item, EVAS_CALLBACK_DEL, _item_best_time_del_cb);
636         evas_object_data_del(item, DATA_KEY_BEST_TIME);
637         evas_object_del(item);
638 }
639