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