af0fede07a8381ba6aa57f0849251aa4889955ae
[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         _D("HELLO : local_time:%d, diff:%d, timezone:%f, final_hour:%d", local_time->tm_hour, local_time->tm_gmtoff / 3600l, city_info[city].timezone, hour);
251         if (hour < 0)
252                 hour += 24;
253
254         hour %= 24;
255
256         snprintf(time_result, sizeof(time_result), "%2d:%02d", hour, minute);
257         elm_object_part_text_set(item, part, time_result);
258 }
259
260 Evas_Object *item_create_selecting(Evas_Object *parent, int city, struct tm *local_time, main_view_s *main_view_info)
261 {
262         Evas_Object *item = NULL;
263         Evas_Object *btn = NULL;
264         city_s *city_info = NULL;
265         selecting_info_s *selecting_info = NULL;
266
267         char *path = NULL;
268         char full_path[PATH_LEN] = {0, };
269         char city_str[PATH_LEN] = {0, };
270         char gmt_str[PATH_LEN] = {0, };
271
272         retv_if(!parent, NULL);
273
274         city_info = city_get();
275         goto_if(!city_info, error);
276
277         int i = 0;
278         for (i = 0; i < MAXIMUM_SELECTED_CITY; i++) {
279                 if (color_index[i]) continue;
280
281                 if (EINA_FALSE == add_city_to_map(i, &city_info[city])) {
282                         _E("cannot add a city to the map");
283                         break;
284                 }
285                 break;
286         }
287
288         path = app_get_resource_path();
289         retv_if(!path, NULL);
290
291         snprintf(full_path, sizeof(full_path), "%s/edje/%s", path, ITEM2_EDJE);
292         free(path);
293
294         selecting_info = calloc(1, sizeof(selecting_info_s));
295         retv_if(!selecting_info, NULL);
296         selecting_info->city = city;
297         selecting_info->color = i;
298
299         item = elm_layout_add(parent);
300         retv_if(!item, NULL);
301
302         elm_layout_file_set(item, full_path, "item");
303
304         evas_object_size_hint_weight_set(item, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
305         evas_object_size_hint_align_set(item, EVAS_HINT_FILL, EVAS_HINT_FILL);
306         evas_object_data_set(item, DATA_KEY_MAIN_VIEW_INFO, main_view_info);
307         evas_object_data_set(item, DATA_KEY_SELECTING, selecting_info);
308         evas_object_event_callback_add(item, EVAS_CALLBACK_DEL, _item_selecting_del_cb, NULL);
309         evas_object_show(item);
310
311         btn = elm_button_add(item);
312         if (btn) {
313                 elm_object_style_set(btn, "transparent");
314                 elm_object_part_content_set(item, "delete_event", btn);
315                 evas_object_smart_callback_add(btn, "clicked", _delete_selecting_item_cb, item);
316                 evas_object_show(btn);
317         }
318
319         snprintf(city_str, sizeof(city_str), "%s, %s", city_info[city].name, city_info[city].nation);
320         elm_object_part_text_set(item, "city", city_str);
321
322         if (city_info[city].timezone > 0)
323                 snprintf(gmt_str, sizeof(gmt_str), "GMT +%.1f", city_info[city].timezone);
324         else 
325                 snprintf(gmt_str, sizeof(gmt_str), "GMT %.1f", city_info[city].timezone);
326
327         elm_object_part_text_set(item, "gmt", gmt_str);
328         _text_set_local_time(item, "time", city, local_time);
329
330         if (set_marker(item, i) == EINA_FALSE)
331                 _E("cannot set the marker");
332
333         color_index[i] = 1;
334
335         return item;
336
337 error:
338         if (item)
339                 evas_object_del(item);
340
341         if (selecting_info)
342                 free(selecting_info);
343
344         return NULL;
345 }
346
347 void item_destroy_selecting(Evas_Object *item)
348 {
349         selecting_info_s *selecting_info = NULL;
350
351         ret_if(!item);
352
353         evas_object_data_del(item, DATA_KEY_MAIN_VIEW_INFO);
354         selecting_info = evas_object_data_del(item, DATA_KEY_SELECTING);
355         if (selecting_info) {
356         _D("HELLO, REMOVE!!");
357                 if (EINA_FALSE == remove_city_from_map(selecting_info->color))
358                         _E("cannot remove the city");
359
360                 color_index[selecting_info->color] = 0;
361                 free(selecting_info);
362         }
363
364         evas_object_event_callback_del(item, EVAS_CALLBACK_DEL, _item_selecting_del_cb);
365         evas_object_del(item);
366 }
367
368 static void _item_group_del_cb(void *data, Evas *e, Evas_Object *obj, void *event_info)
369 {
370         item_destroy_group(obj);
371 }
372
373 static void _item_group_down_cb(void *data, Evas_Object *obj, const char *emission, const char *source)
374 {
375         _D("An item is down");
376 }
377
378 static Eina_Bool _item_group_up_timer_cb(void *data)
379 {
380         Evas_Object *item = data;
381         Evas_Object *selecting_item = NULL;
382         main_view_s *main_view_info = NULL;
383         group_info_s *group_info = NULL;
384         struct tm *local_time = NULL;
385         time_t t = 0;
386         int i = 0;
387
388         retv_if(!item, ECORE_CALLBACK_CANCEL);
389
390         main_view_info = evas_object_data_get(item, DATA_KEY_MAIN_VIEW_INFO);
391         retv_if(!main_view_info, ECORE_CALLBACK_CANCEL);
392         retv_if(!main_view_info->city_list, ECORE_CALLBACK_CANCEL);
393
394         group_info = evas_object_data_get(item, GROUP_INFO);
395         retv_if(!group_info, ECORE_CALLBACK_CANCEL);
396
397         time(&t);
398         local_time = localtime(&t);
399
400         for (i = 0; i < MAXIMUM_SELECTED_CITY; i++) {
401                 if (!group_info->city[i]) {
402                         _D("No city anymore");
403                         break;
404                 }
405                 selecting_item = item_create_selecting(main_view_info->city_list, group_info->city[i], local_time, main_view_info);
406                 break_if(!selecting_item);
407                 scroller_append_item(main_view_info->city_list, selecting_item);
408         }
409
410         main_view_go_result(main_view_info);
411
412         elm_object_signal_emit(main_view_info->main_view, "momentic,state,drawer,hide", "");
413         //elm_object_signal_emit(main_view_info->main_view, "momentic,state,drawer_btn,hide", "");
414         elm_object_signal_emit(main_view_info->main_view, "momentic,state,result,show", "");
415         elm_object_signal_emit(main_view_info->main_view, "momentic,state,add_description,hide", "");
416
417
418         return ECORE_CALLBACK_CANCEL;
419 }
420
421 static void _item_group_up_cb(void *data, Evas_Object *obj, const char *emission, const char *source)
422 {
423         main_view_s *main_view_info = data;
424         ret_if(!main_view_info);
425         ret_if(!main_view_info->city_list);
426
427         scroller_clear_item(main_view_info->city_list);
428
429         ecore_timer_add(0.4, _item_group_up_timer_cb, obj);
430 }
431
432 static void _delete_group_item_cb(void *data, Evas_Object *obj, void *event_info)
433 {
434         main_view_s *main_view_info = NULL;
435         Evas_Object *item = data;
436         group_info_s *group_info = NULL;
437         int count = 0;
438
439         _D("clicked, delete the group item");
440
441         ret_if(!item);
442
443         main_view_info = evas_object_data_get(item, DATA_KEY_MAIN_VIEW_INFO);
444         ret_if(!main_view_info);
445
446         group_info = evas_object_data_get(item, GROUP_INFO);
447         ret_if(!group_info);
448
449         db_delete_group(main_view_info->moment_info->db, group_info->id);
450         main_view_info->moment_info->group_list = eina_list_remove(main_view_info->moment_info->group_list, group_info);
451         group_info_destroy(group_info);
452
453         item_destroy_group(item);
454
455         count = scroller_count_item(main_view_info->group_scroller);
456         if (count < 1) {
457                 elm_object_signal_emit(main_view_info->main_view, "momentic,state,drawer,noresult,show", "");
458         }
459
460         
461 }
462
463 Evas_Object *item_create_group(Evas_Object *parent, group_info_s *group_info, main_view_s *main_view_info)
464 {
465         Evas_Object *item = NULL;
466         Evas_Object *btn = NULL;
467
468         char *path = NULL;
469         char full_path[PATH_LEN] = {0, };
470
471         retv_if(!parent, NULL);
472
473         path = app_get_resource_path();
474         retv_if(!path, NULL);
475
476         snprintf(full_path, sizeof(full_path), "%s/edje/%s", path, ITEM_EDJE);
477         free(path);
478
479         item = elm_layout_add(parent);
480         retv_if(!item, NULL);
481
482         elm_layout_file_set(item, full_path, "item_group");
483         evas_object_data_set(item, GROUP_INFO, group_info);
484         evas_object_data_set(item, DATA_KEY_MAIN_VIEW_INFO, main_view_info);
485
486         evas_object_size_hint_weight_set(item, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
487         evas_object_size_hint_align_set(item, EVAS_HINT_FILL, EVAS_HINT_FILL);
488         evas_object_event_callback_add(item, EVAS_CALLBACK_DEL, _item_group_del_cb, NULL);
489         elm_object_signal_callback_add(item, "down", "item", _item_group_down_cb, NULL);
490         elm_object_signal_callback_add(item, "up", "item", _item_group_up_cb, main_view_info);
491
492         evas_object_show(item);
493
494         btn = elm_button_add(item);
495         if (btn) {
496                 elm_object_style_set(btn, "transparent");
497                 elm_object_part_content_set(item, "delete_event", btn);
498                 evas_object_smart_callback_add(btn, "clicked", _delete_group_item_cb, item);
499                 evas_object_show(btn);
500         }
501
502         elm_object_part_text_set(item, "title", group_info->title);
503
504         return item;
505 }
506
507 void item_destroy_group(Evas_Object *item)
508 {
509         ret_if(!item);
510
511         evas_object_data_del(item, GROUP_INFO);
512         evas_object_data_del(item, DATA_KEY_MAIN_VIEW_INFO);
513         evas_object_event_callback_del(item, EVAS_CALLBACK_DEL, _item_group_del_cb);
514         elm_object_signal_callback_del(item, "down", "item", _item_group_down_cb);
515         elm_object_signal_callback_del(item, "up", "item", _item_group_up_cb);
516
517         evas_object_del(item);
518 }
519
520 static void _item_padding_del_cb(void *data, Evas *e, Evas_Object *obj, void *event_info)
521 {
522         item_destroy_padding(obj);
523 }
524
525 Evas_Object *item_create_padding(Evas_Object *parent)
526 {
527         Evas_Object *item = NULL;
528
529         char *path = NULL;
530         char full_path[PATH_LEN] = {0, };
531
532         retv_if(!parent, NULL);
533
534         path = app_get_resource_path();
535         retv_if(!path, NULL);
536
537         snprintf(full_path, sizeof(full_path), "%s/edje/%s", path, ITEM_EDJE);
538         free(path);
539
540         item = elm_layout_add(parent);
541         retv_if(!item, NULL);
542
543         elm_layout_file_set(item, full_path, "item_padding");
544
545         evas_object_size_hint_weight_set(item, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
546         evas_object_size_hint_align_set(item, EVAS_HINT_FILL, EVAS_HINT_FILL);
547         evas_object_event_callback_add(item, EVAS_CALLBACK_DEL, _item_padding_del_cb, NULL);
548
549         evas_object_show(item);
550
551         return item;
552 }
553
554 void item_destroy_padding(Evas_Object *item)
555 {
556         ret_if(!item);
557         evas_object_event_callback_del(item, EVAS_CALLBACK_DEL, _item_padding_del_cb);
558         evas_object_del(item);
559 }
560
561 static void _item_best_time_del_cb(void *data, Evas *e, Evas_Object *obj, void *event_info)
562 {
563         item_destroy_best_time(obj);
564 }
565
566 Evas_Object *item_create_best_time(Evas_Object *parent, double start, double end)
567 {
568         Evas_Object *item = NULL;
569
570         char *path = NULL;
571         char full_path[PATH_LEN] = {0, };
572         char time_str[PATH_LEN] = {0, };
573
574         double half;
575         int tmp = 0;
576
577         retv_if(!parent, NULL);
578
579         path = app_get_resource_path();
580         retv_if(!path, NULL);
581
582         snprintf(full_path, sizeof(full_path), "%s/edje/%s", path, BEST_TIME_EDJE);
583         free(path);
584
585         item = elm_layout_add(parent);
586         retv_if(!item, NULL);
587
588         elm_layout_file_set(item, full_path, "best_time");
589
590         evas_object_size_hint_weight_set(item, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
591         evas_object_size_hint_align_set(item, EVAS_HINT_FILL, EVAS_HINT_FILL);
592         evas_object_event_callback_add(item, EVAS_CALLBACK_DEL, _item_best_time_del_cb, NULL);
593
594         elm_object_part_text_set(item, "city", "Best time");
595
596         evas_object_show(item);
597
598         if (start >= end) {
599                 elm_object_part_text_set(item, "time", "No matched time");
600                 goto out;
601         }
602
603         tmp = start;
604         if (tmp == start) half = 0.0f;
605         else half = 0.5f;
606
607         if (tmp) tmp %= 24;
608         start = ((double) tmp) + half;
609
610         tmp = end;
611         if (tmp == end) half = 0.0f;
612         else half = 0.5f;
613
614         if (tmp) tmp %= 24;
615         end = ((double) tmp) + half;
616
617         _D("HELLO, Best,%f:%f", start, end);
618
619         int start_hour = start;
620         int start_minute = (start_hour == start)? 0 : 30;
621         int end_hour = end;
622         int end_minute = (end_hour == end)? 0 : 30;
623
624         snprintf(time_str, sizeof(time_str), "%d:%02d - %d:%02d", start_hour, start_minute, end_hour, end_minute);
625         elm_object_part_text_set(item, "time",  time_str);
626         if (set_time_range(item, 5, start, end, 0.0f, 0.0f) == EINA_FALSE)
627                 _E("cannot set time range");
628
629 out:
630         return item;
631 }
632
633 void item_destroy_best_time(Evas_Object *item)
634 {
635         ret_if(!item);
636         evas_object_event_callback_del(item, EVAS_CALLBACK_DEL, _item_best_time_del_cb);
637         evas_object_del(item);
638 }
639