Fixed UI issues after code restructre.
[apps/native/telegram-tizen.git] / tg-engine-service / tg_engine / tg_engine.c
1 /*
2     This file is part of Telegram application for tizen
3
4     This library is free software; you can redistribute it and/or
5     modify it under the terms of the GNU Lesser General Public
6     License as published by the Free Software Foundation; either
7     version 2.1 of the License, or (at your option) any later version.
8
9     This library is distributed in the hope that it will be useful,
10     but WITHOUT ANY WARRANTY; without even the implied warranty of
11     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12     Lesser General Public License for more details.
13
14     You should have received a copy of the GNU Lesser General Public
15     License along with this library; if not, write to the Free Software
16     Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
17 */
18
19 #include "tg_engine.h"
20 #include "server_response.h"
21 #include <pthread.h>
22 #include <Ecore.h>
23 #include "tg_db_wrapper.h"
24 #include "tgl-fetch.h"
25 #include <mime_type.h>
26 #include "device_contacts_manager.h"
27 #include "tg-engine-service.h"
28 #include "logger.h"
29
30 #define DC_SERIALIZED_MAGIC 0x868aa81d
31 #define STATE_FILE_MAGIC 0x28949a93
32 #define SECRET_CHAT_FILE_MAGIC 0x37a1988a
33
34 static struct _tg_engine {
35         int verbosity;
36         int msg_num_mode;
37         char *default_username;
38         char *config_filename;
39         char *prefix;
40         char *auth_file_name;
41         char *state_file_name;
42         char *secret_chat_file_name;
43         char *downloads_directory;
44         char *config_directory;
45         char *binlog_file_name;
46         char *lua_file;
47         int binlog_enabled;
48         int log_level;
49         int sync_from_start;
50         int allow_weak_random;
51         int disable_colors;
52         int readline_disabled;
53         int disable_output;
54         int reset_authorization;
55         int port;
56         int use_ids;
57         int ipv6_enabled;
58         char *start_command;
59         char *rsa_file_name;
60         char *config_full_path;
61         int need_dc_list_update;
62         struct tgl_state *TLS;
63 } s_info;
64
65 static void on_chat_info_received(struct tgl_state *TLS, void *callback_extra, int success, struct tgl_chat *chat_info);
66 static void on_buddy_info_loaded(struct tgl_state *TLS, void *callback_extra, int success, struct tgl_user *U);
67 static void on_chat_pic_loaded(struct tgl_state *TLS, void *callback_extra, int success, char *filename);
68 static void on_document_download_completed(struct tgl_state *TLS, void *callback_extra, int success, char *filename);
69 static void on_buddy_pic_loaded(struct tgl_state *TLS, void *callback_extra, int success, char *filename);
70 static void on_new_buddy_info_loaded(struct tgl_state *TLS, void *callback_extra, int success, struct tgl_user *U);
71 extern void delete_all_messages_from_chat(int buddy_id, int type_of_chat);
72
73 void tgl_engine_var_init(void)
74 {
75         s_info.default_username = NULL;
76         s_info.config_filename = NULL;
77         s_info.auth_file_name = NULL;
78         s_info.state_file_name = NULL;
79         s_info.secret_chat_file_name = NULL;
80         s_info.downloads_directory = NULL;
81         s_info.config_directory = NULL;
82         s_info.binlog_file_name = NULL;
83         s_info.lua_file = NULL;
84 }
85
86 void tgl_engine_var_free(void)
87 {
88         if (s_info.default_username) {
89                 free(s_info.default_username);
90                 s_info.default_username = NULL;
91         }
92         if (s_info.config_filename) {
93                 free(s_info.config_filename);
94                 s_info.config_filename = NULL;
95         }
96         if (s_info.auth_file_name) {
97                 free(s_info.auth_file_name);
98                 s_info.auth_file_name = NULL;
99         }
100         if (s_info.state_file_name) {
101                 free(s_info.state_file_name);
102                 s_info.state_file_name = NULL;
103         }
104         if (s_info.secret_chat_file_name) {
105                 free(s_info.secret_chat_file_name);
106                 s_info.secret_chat_file_name = NULL;
107         }
108         if (s_info.downloads_directory) {
109                 free(s_info.downloads_directory);
110                 s_info.downloads_directory = NULL;
111         }
112         if (s_info.config_directory) {
113                 free(s_info.config_directory);
114                 s_info.config_directory = NULL;
115         }
116         if (s_info.binlog_file_name) {
117                 free(s_info.binlog_file_name);
118                 s_info.binlog_file_name = NULL;
119         }
120         if (s_info.lua_file) {
121                 free(s_info.lua_file);
122                 s_info.lua_file = NULL;
123         }
124         if (s_info.TLS) {
125                 tgl_state_free(s_info.TLS);
126                 tgl_free_all(s_info.TLS);
127                 s_info.TLS = NULL;
128         }
129 }
130
131 char *tgl_engine_get_auth_key_filename(void)
132 {
133   return s_info.auth_file_name;
134 }
135
136 char *tgl_engine_get_state_filename(void)
137 {
138   return s_info.state_file_name;
139 }
140
141 char *tgl_engine_get_secret_chat_filename(void)
142 {
143   return s_info.secret_chat_file_name;
144 }
145
146 char *tgl_engine_get_downloads_directory(void)
147 {
148   return s_info.downloads_directory;
149 }
150
151 void write_dc(struct tgl_dc *DC, void *extra)
152 {
153         int auth_file_fd = *(int *)extra;
154         int x;
155
156         x = !!DC;
157
158         if (!x) {
159                 assert(write(auth_file_fd, &x, 4) == 4);
160                 return;
161         }
162
163         assert(write(auth_file_fd, &x, 4) == 4);
164         assert(DC->has_auth);
165         assert(write(auth_file_fd, &DC->port, 4) == 4);
166         int l = strlen(DC->ip);
167         assert(write(auth_file_fd, &l, 4) == 4);
168         assert(write(auth_file_fd, DC->ip, l) == l);
169         assert(write(auth_file_fd, &DC->auth_key_id, 8) == 8);
170         assert(write(auth_file_fd, DC->auth_key, 256) == 256);
171 }
172
173 void write_secret_chat(tgl_peer_t *_P, void *extra)
174 {
175         struct tgl_secret_chat *P = (void *)_P;
176
177         if (tgl_get_peer_type(P->id) != TGL_PEER_ENCR_CHAT) {
178                 return;
179         }
180
181         if (P->state != sc_ok) {
182                 return;
183         }
184
185         int *a = extra;
186         int fd = a[0];
187         a[1]++;
188
189         int id = tgl_get_peer_id(P->id);
190         assert(write(fd, &id, 4) == 4);
191         //assert(write(fd, &P->flags, 4) == 4);
192         int l = strlen(P->print_name);
193         assert(write(fd, &l, 4) == 4);
194         assert(write(fd, P->print_name, l) == l);
195         assert(write(fd, &P->user_id, 4) == 4);
196         assert(write(fd, &P->admin_id, 4) == 4);
197         assert(write(fd, &P->date, 4) == 4);
198         assert(write(fd, &P->ttl, 4) == 4);
199         assert(write(fd, &P->layer, 4) == 4);
200         assert(write(fd, &P->access_hash, 8) == 8);
201         assert(write(fd, &P->state, 4) == 4);
202         assert(write(fd, &P->key_fingerprint, 8) == 8);
203         assert(write(fd, &P->key, 256) == 256);
204         assert(write(fd, &P->first_key_sha, 20) == 20);
205         assert(write(fd, &P->in_seq_no, 4) == 4);
206         assert(write(fd, &P->last_in_seq_no, 4) == 4);
207         assert(write(fd, &P->out_seq_no, 4) == 4);
208 }
209
210 void write_secret_chat_file(void)
211 {
212         if (s_info.binlog_enabled) {
213                 return;
214         }
215         int secret_chat_fd = open(tgl_engine_get_secret_chat_filename(), O_CREAT | O_RDWR, 0600);
216         assert(secret_chat_fd >= 0);
217         int x = SECRET_CHAT_FILE_MAGIC;
218         assert(write(secret_chat_fd, &x, 4) == 4);
219         x = 2;
220         assert(write(secret_chat_fd, &x, 4) == 4); // version
221         assert(write(secret_chat_fd, &x, 4) == 4); // num
222
223         int y[2];
224         y[0] = secret_chat_fd;
225         y[1] = 0;
226
227         tgl_peer_iterator_ex(s_info.TLS, write_secret_chat, y);
228
229         lseek(secret_chat_fd, 8, SEEK_SET);
230         assert(write(secret_chat_fd, &y[1], 4) == 4);
231         close(secret_chat_fd);
232 }
233
234 void write_auth_file(void)
235 {
236         if (s_info.binlog_enabled) {
237                 return;
238         }
239
240         int auth_file_fd = open(tgl_engine_get_auth_key_filename(), O_CREAT | O_RDWR, 0600);
241
242         assert(auth_file_fd >= 0);
243         int x = DC_SERIALIZED_MAGIC;
244         assert(write(auth_file_fd, &x, 4) == 4);
245         assert(write(auth_file_fd, &s_info.TLS->max_dc_num, 4) == 4);
246         assert(write(auth_file_fd, &s_info.TLS->dc_working_num, 4) == 4);
247         tgl_dc_iterator_ex(s_info.TLS, write_dc, &auth_file_fd);
248         assert(write(auth_file_fd, &s_info.TLS->our_id, 4) == 4);
249         close(auth_file_fd);
250 }
251
252 void read_dc(int auth_file_fd, int id, unsigned ver)
253 {
254         int port = 0;
255         assert(read(auth_file_fd, &port, 4) == 4);
256         int l = 0;
257         assert(read(auth_file_fd, &l, 4) == 4);
258         assert(l >= 0 && l < 100);
259         char ip[100];
260         assert(read(auth_file_fd, ip, l) == l);
261         ip[l] = 0;
262
263         long long auth_key_id;
264         static unsigned char auth_key[256];
265         assert(read(auth_file_fd, &auth_key_id, 8) == 8);
266         assert(read(auth_file_fd, auth_key, 256) == 256);
267
268         //bl_do_add_dc(id, ip, l, port, auth_key_id, auth_key);
269         bl_do_dc_option(s_info.TLS, id, 2, "DC", l, ip, port);
270         bl_do_set_auth_key_id(s_info.TLS, id, auth_key);
271         bl_do_dc_signed(s_info.TLS, id);
272 }
273
274 void empty_auth_file(void)
275 {
276         if (s_info.TLS->test_mode) {
277                 bl_do_dc_option(s_info.TLS, 1, 0, "", strlen(TG_SERVER_TEST_1), TG_SERVER_TEST_1, 443);
278                 bl_do_dc_option(s_info.TLS, 2, 0, "", strlen(TG_SERVER_TEST_2), TG_SERVER_TEST_2, 443);
279                 bl_do_dc_option(s_info.TLS, 3, 0, "", strlen(TG_SERVER_TEST_3), TG_SERVER_TEST_3, 443);
280                 bl_do_set_working_dc(s_info.TLS, 2);
281         } else {
282                 bl_do_dc_option(s_info.TLS, 1, 0, "", strlen(TG_SERVER_1), TG_SERVER_1, 443);
283                 bl_do_dc_option(s_info.TLS, 2, 0, "", strlen(TG_SERVER_2), TG_SERVER_2, 443);
284                 bl_do_dc_option(s_info.TLS, 3, 0, "", strlen(TG_SERVER_3), TG_SERVER_3, 443);
285                 bl_do_dc_option(s_info.TLS, 4, 0, "", strlen(TG_SERVER_4), TG_SERVER_4, 443);
286                 bl_do_dc_option(s_info.TLS, 5, 0, "", strlen(TG_SERVER_5), TG_SERVER_5, 443);
287                 bl_do_set_working_dc(s_info.TLS, 4);
288         }
289 }
290
291 void read_secret_chat(int fd, int v)
292 {
293         int id, l, user_id, admin_id, date, ttl, layer, state;
294         long long access_hash, key_fingerprint;
295         static char s[1000];
296         static unsigned char key[256];
297         static unsigned char sha[20];
298         assert(read(fd, &id, 4) == 4);
299         //assert(read(fd, &flags, 4) == 4);
300         assert(read(fd, &l, 4) == 4);
301         assert(l > 0 && l < 1000);
302         assert(read(fd, s, l) == l);
303         assert(read(fd, &user_id, 4) == 4);
304         assert(read(fd, &admin_id, 4) == 4);
305         assert(read(fd, &date, 4) == 4);
306         assert(read(fd, &ttl, 4) == 4);
307         assert(read(fd, &layer, 4) == 4);
308         assert(read(fd, &access_hash, 8) == 8);
309         assert(read(fd, &state, 4) == 4);
310         assert(read(fd, &key_fingerprint, 8) == 8);
311         assert(read(fd, &key, 256) == 256);
312         if (v >= 2) {
313                 assert(read(fd, sha, 20) == 20);
314         }
315         int in_seq_no = 0, out_seq_no = 0, last_in_seq_no = 0;
316         if (v >= 1) {
317                 assert(read(fd, &in_seq_no, 4) == 4);
318                 assert(read(fd, &last_in_seq_no, 4) == 4);
319                 assert(read(fd, &out_seq_no, 4) == 4);
320         }
321
322         bl_do_encr_chat_create(s_info.TLS, id, user_id, admin_id, s, l);
323         struct tgl_secret_chat *P = (void *)tgl_peer_get(s_info.TLS, TGL_MK_ENCR_CHAT(id));
324         assert(P && (P->flags & FLAG_CREATED));
325         bl_do_encr_chat_set_date(s_info.TLS, P, date);
326         bl_do_encr_chat_set_ttl(s_info.TLS, P, ttl);
327         bl_do_encr_chat_set_layer(s_info.TLS , P, layer);
328         bl_do_encr_chat_set_access_hash(s_info.TLS, P, access_hash);
329         bl_do_encr_chat_set_state(s_info.TLS, P, state);
330         bl_do_encr_chat_set_key(s_info.TLS, P, key, key_fingerprint);
331         if (v >= 2) {
332                 bl_do_encr_chat_set_sha(s_info.TLS, P, sha);
333         } else {
334                 SHA1((void *)key, 256, sha);
335                 bl_do_encr_chat_set_sha(s_info.TLS, P, sha);
336         }
337         if (v >= 1) {
338                 bl_do_encr_chat_set_seq(s_info.TLS, P, in_seq_no, last_in_seq_no, out_seq_no);
339         }
340 }
341
342 void read_secret_chat_file(void)
343 {
344         if (s_info.binlog_enabled) {
345                 return;
346         }
347
348         int secret_chat_fd = open(tgl_engine_get_secret_chat_filename(), O_RDWR, 0600);
349
350         if (secret_chat_fd < 0) {
351                 return;
352         }
353         //assert(secret_chat_fd >= 0);
354         int x;
355         if (read(secret_chat_fd, &x, 4) < 4) { close(secret_chat_fd); return; }
356         if (x != SECRET_CHAT_FILE_MAGIC) { close(secret_chat_fd); return; }
357         int v = 0;
358         assert(read(secret_chat_fd, &v, 4) == 4);
359         assert(v == 0 || v == 1 || v == 2); // version
360         assert(read(secret_chat_fd, &x, 4) == 4);
361         assert(x >= 0);
362         while (x --> 0) {
363                 read_secret_chat(secret_chat_fd, v);
364         }
365         close(secret_chat_fd);
366 }
367
368 void read_state_file(void)
369 {
370         if (s_info.binlog_enabled) {
371                 return;
372         }
373         int state_file_fd = open(tgl_engine_get_state_filename(), O_CREAT | O_RDWR, 0600);
374         if (state_file_fd < 0)
375                 return;
376
377         int version, magic;
378
379         if (read(state_file_fd, &magic, 4) < 4) {
380                 close(state_file_fd);
381                 return;
382         }
383
384         if (magic != (int)STATE_FILE_MAGIC) {
385                 close(state_file_fd);
386                 return;
387         }
388
389         if (read(state_file_fd, &version, 4) < 4) {
390                 close(state_file_fd);
391                 return;
392         }
393
394         assert(version >= 0);
395         int x[4];
396
397         if (read(state_file_fd, x, 16) < 16) {
398                 close(state_file_fd);
399                 return;
400         }
401
402         int pts = x[0];
403         int qts = x[1];
404         int seq = x[2];
405         int date = x[3];
406         close(state_file_fd);
407         bl_do_set_seq(s_info.TLS, seq);
408         bl_do_set_pts(s_info.TLS, pts);
409         bl_do_set_qts(s_info.TLS, qts);
410         bl_do_set_date(s_info.TLS, date);
411 }
412
413 void read_auth_file(void)
414 {
415         if (s_info.binlog_enabled) {
416                 return;
417         }
418         int auth_file_fd;
419
420         auth_file_fd = open(tgl_engine_get_auth_key_filename(), O_CREAT | O_RDWR, 0600);
421         if (auth_file_fd < 0) {
422                 /**
423                  * Logging this for handling exceptional cases.
424                  */
425                 empty_auth_file();
426                 return;
427         }
428
429         assert(auth_file_fd >= 0);
430         unsigned x;
431         unsigned m;
432
433         if (read(auth_file_fd, &m, 4) < 4 || (m != DC_SERIALIZED_MAGIC)) {
434                 close(auth_file_fd);
435                 empty_auth_file();
436                 return;
437         }
438
439         assert(read(auth_file_fd, &x, 4) == 4);
440         assert(x > 0);
441         int dc_working_num;
442         assert(read(auth_file_fd, &dc_working_num, 4) == 4);
443
444         int i;
445         for (i = 0; i <= (int)x; i++) {
446                 int y;
447                 assert(read(auth_file_fd, &y, 4) == 4);
448                 if (y) {
449                         read_dc(auth_file_fd, i, m);
450                 }
451         }
452
453         bl_do_set_working_dc(s_info.TLS, dc_working_num);
454         int our_id;
455         int l = read(auth_file_fd, &our_id, 4);
456
457         if (l < 4) {
458                 assert(!l);
459         }
460         if (our_id) {
461                 bl_do_set_our_id(s_info.TLS, our_id);
462         }
463         close(auth_file_fd);
464 }
465
466 void tg_new_msg(struct tgl_state *TLS, struct tgl_message *M)
467 {
468         struct tgl_message *temp_msg = tgl_message_get(TLS, M->id);
469         if (!temp_msg)
470                 LOGE("memory allocation failed!!! for tgl_message_get");
471 }
472
473 void tg_marked_read(struct tgl_state *TLS, int num, struct tgl_message *list[])
474 {
475         for (int i = 0; i < num; i++) {
476                 //struct tgl_message
477                 struct tgl_message* message = list[i];
478                 int identifier = -1;
479                 tgl_peer_t* UC;
480                 UC = tgl_peer_get(TLS, message->to_id);
481                 struct tgl_user* buddy;
482                 buddy = &(UC->user);
483                 char *phone = NULL;
484                 if (buddy && buddy->phone && strlen(buddy->phone) > 0) {
485                         phone = buddy->phone;
486                 }
487
488                 message->msg_state = TG_MESSAGE_STATE_READ;
489
490                 char *tb_name = get_table_name_from_number(message->to_id.id);
491                 update_msg_into_db(message, tb_name, identifier);
492                 if (message->media.type == tgl_message_media_photo) {
493                         update_sent_media_info_in_db(message, (long long)message->media.photo.id);
494                 }
495                 send_message_read_by_buddy_response(TLS->callback_data, message->to_id.id, message->id, tb_name, phone, tgl_get_peer_type(message->to_id));
496                 free(tb_name);
497         }
498
499 }
500
501 void on_code_via_phone_result(struct tgl_state *TLS, void *callback_extra, int success)
502 {
503         /*
504         if (success) {
505                 printf("success");
506         }
507         */
508 }
509
510 void request_for_code_via_call(struct tgl_state *TLS, char* phone_no, Eina_Bool trough_sms)
511 {
512         tg_engine_data_s *tg_data;
513         tg_data = TLS->callback_data;
514         if (tg_data && tg_data->phone_number && tg_data->mhash) {
515                 tgl_do_phone_call(TLS, tg_data->phone_number, tg_data->mhash, on_code_via_phone_result, TLS);
516         }
517 }
518
519 void tg_get_string(struct tgl_state *TLS, const char *prompt, int flags, void(*callback)(struct tgl_state *TLS, char *string, void *arg), void *arg)
520 {
521         tg_engine_data_s *tg_data;
522
523         tg_data = TLS->callback_data;
524
525         tg_data->get_string = callback;
526         tg_data->callback_arg = arg;
527         if (strcmp(prompt, "phone number:") == 0) {
528
529                 if (tg_data->tg_state == TG_ENGINE_STATE_REGISTRATION) {
530                         send_request_phone_num_again(tg_data);
531                 } else {
532                         //tg_data->is_first_time_registration = EINA_TRUE;
533                         tg_data->tg_state = TG_ENGINE_STATE_REGISTRATION;
534                         if (tg_data && tg_data->phone_number) {
535                                 tg_data->get_string(TLS, tg_data->phone_number, tg_data->callback_arg);
536                                 //tg_data->code_response_timer = ecore_timer_add(60, on_code_request_timer_expired, tg_data);
537                         }
538                 }
539         } else if (strcmp(prompt, "code('call' for phone call):") == 0) {
540
541 /*              if (tg_data->code_response_timer) {
542                         ecore_timer_del(tg_data->code_response_timer);
543                         tg_data->code_response_timer = NULL;
544                 }*/
545
546                 void **T = arg;
547                 tg_data->mhash = strdup(T[1]);
548
549                 if (tg_data->tg_state == TG_ENGINE_STATE_CODE_REQUEST) {
550                         send_request_code_again(tg_data);
551                 } else {
552                         tg_data->tg_state = TG_ENGINE_STATE_CODE_REQUEST;
553                         send_registration_response(tg_data, EINA_TRUE);
554                 }
555
556         } else if (strcmp(prompt, "register [Y/n]:") == 0) {
557
558                 tg_data->tg_state = TG_ENGINE_STATE_PROFILE_REGISTRATION;
559                 tg_data->get_string(TLS, "Y", tg_data->callback_arg);
560
561         } else if (strcmp(prompt, "First name:") == 0) {
562
563                 tg_data->tg_state = TG_ENGINE_STATE_PROFILE_FIRST_NAME_REGISTRATION;
564                 tg_data->is_first_time_registration = EINA_TRUE;
565
566                 if (tg_data->first_name) {
567                         tg_data->get_string(TLS, tg_data->first_name, tg_data->callback_arg);
568                 } else {
569                         send_name_registration_response(tg_data);
570                 }
571
572         } else if (strcmp(prompt, "Last name:") == 0) {
573
574                 tg_data->tg_state = TG_ENGINE_STATE_PROFILE_LAST_NAME_REGISTRATION;
575
576                 if (tg_data->last_name) {
577                         tg_data->get_string(TLS, tg_data->last_name, tg_data->callback_arg);
578                 }
579
580         } else {
581
582                 // to be checked
583
584         }
585 }
586
587 void tg_logged_in(struct tgl_state *TLS)
588 {
589         tg_engine_data_s *tg_data;
590         tg_data = TLS->callback_data;
591         write_auth_file();
592         int offline_mode = 0;
593         tgl_peer_id_t t_id;
594         t_id.id = TLS->our_id;
595         t_id.type = TGL_PEER_USER;
596         //tg_data->is_first_time_registration = EINA_TRUE;
597         create_data_base_tables();
598         tgl_do_get_user_info(TLS, t_id, offline_mode, &on_user_info_loaded, NULL);
599 }
600
601 static Eina_Bool on_send_media_message_requested(void *data)
602 {
603         sent_media_data_s *media_info = (sent_media_data_s*)data;
604         if (media_info) {
605                 int buddy_id = atoi(media_info->buddy_id);
606                 int message_id = atoi(media_info->message_id);
607                 int media_id = atoi(media_info->media_id);
608                 int msg_type = atoi(media_info->message_type);
609                 int type_of_chat = atoi(media_info->type_of_chat);
610
611                 process_send_media_command(buddy_id, message_id, media_id, msg_type, media_info->file_path, type_of_chat);
612
613                 if (media_info->app_name) {
614                         free(media_info->app_name);
615                         media_info->app_name = NULL;
616                 }
617                 if (media_info->command) {
618                         free(media_info->command);
619                         media_info->command = NULL;
620                 }
621                 if (media_info->buddy_id) {
622                         free(media_info->buddy_id);
623                         media_info->buddy_id = NULL;
624                 }
625                 if (media_info->message_id) {
626                         free(media_info->message_id);
627                         media_info->message_id = NULL;
628                 }
629                 if (media_info->media_id) {
630                         free(media_info->media_id);
631                         media_info->media_id = NULL;
632                 }
633
634                 if (media_info->message_type) {
635                         free(media_info->message_type);
636                         media_info->message_type = NULL;
637                 }
638                 if (media_info->file_path) {
639                         free(media_info->file_path);
640                         media_info->file_path = NULL;
641                 }
642                 if (media_info->type_of_chat) {
643                         free(media_info->type_of_chat);
644                         media_info->type_of_chat = NULL;
645                 }
646                 free(media_info);
647         }
648         return ECORE_CALLBACK_CANCEL;
649 }
650 static Eina_Bool on_load_offline_messages(void *data);
651 static Eina_Bool on_send_unsent_messages_requested(void *data)
652 {
653         struct tgl_state *TLS = data;
654         if (!TLS) {
655                 return ECORE_CALLBACK_CANCEL;
656         }
657         //tg_engine_data_s *tg_data = TLS->callback_data;
658
659         Eina_List *unset_text_msgs = get_all_unsent_text_messages();
660         sent_message_data_s* msg_info = NULL;
661         EINA_LIST_FREE(unset_text_msgs, msg_info) {
662                 int buddy_id = atoi(msg_info->buddy_id);
663                 int message_id = atoi(msg_info->message_id);
664                 int msg_type = atoi(msg_info->message_type);
665                 int type_of_chat = atoi(msg_info->type_of_chat);
666                 process_send_message_command(buddy_id, message_id, msg_type, msg_info->message_data, type_of_chat);
667
668                 if (msg_info->app_name) {
669                         free(msg_info->app_name);
670                         msg_info->app_name = NULL;
671                 }
672                 if (msg_info->command) {
673                         free(msg_info->command);
674                         msg_info->command = NULL;
675                 }
676                 if (msg_info->buddy_id) {
677                         free(msg_info->buddy_id);
678                         msg_info->buddy_id = NULL;
679                 }
680                 if (msg_info->message_id) {
681                         free(msg_info->message_id);
682                         msg_info->message_id = NULL;
683                 }
684
685                 if (msg_info->message_type) {
686                         free(msg_info->message_type);
687                         msg_info->message_type = NULL;
688                 }
689                 if (msg_info->message_data) {
690                         free(msg_info->message_data);
691                         msg_info->message_data = NULL;
692                 }
693                 if (msg_info->type_of_chat) {
694                         free(msg_info->type_of_chat);
695                         msg_info->type_of_chat = NULL;
696                 }
697                 free(msg_info);
698         }
699
700         Eina_List *unset_media_msgs = get_all_unsent_media_messages();
701         int init_time = 5;
702         sent_media_data_s* media_info = NULL;
703         EINA_LIST_FREE(unset_media_msgs, media_info) {
704                 sent_media_data_s* new_media_info = (sent_media_data_s*)malloc(sizeof(sent_media_data_s));
705                 new_media_info->app_name = strdup(media_info->app_name);
706                 new_media_info->command = strdup(media_info->command);
707                 new_media_info->buddy_id = strdup(media_info->buddy_id);
708                 new_media_info->message_id = strdup(media_info->message_id);
709                 new_media_info->media_id = strdup(media_info->media_id);
710                 new_media_info->message_type = strdup(media_info->message_type);
711                 new_media_info->file_path = strdup(media_info->file_path);
712                 new_media_info->type_of_chat = strdup(media_info->type_of_chat);
713
714                 ecore_timer_add(init_time, on_send_media_message_requested, new_media_info);
715
716                 if (media_info->app_name) {
717                         free(media_info->app_name);
718                         media_info->app_name = NULL;
719                 }
720                 if (media_info->command) {
721                         free(media_info->command);
722                         media_info->command = NULL;
723                 }
724                 if (media_info->buddy_id) {
725                         free(media_info->buddy_id);
726                         media_info->buddy_id = NULL;
727                 }
728                 if (media_info->message_id) {
729                         free(media_info->message_id);
730                         media_info->message_id = NULL;
731                 }
732                 if (media_info->media_id) {
733                         free(media_info->media_id);
734                         media_info->media_id = NULL;
735                 }
736
737                 if (media_info->message_type) {
738                         free(media_info->message_type);
739                         media_info->message_type = NULL;
740                 }
741                 if (media_info->file_path) {
742                         free(media_info->file_path);
743                         media_info->file_path = NULL;
744                 }
745                 if (media_info->type_of_chat) {
746                         free(media_info->type_of_chat);
747                         media_info->type_of_chat = NULL;
748                 }
749                 free(media_info);
750         }
751         ecore_timer_add(1, on_load_offline_messages, TLS);
752         return ECORE_CALLBACK_CANCEL;
753 }
754
755 void tg_started(struct tgl_state *TLS)
756 {
757         tg_engine_data_s *tg_data = TLS->callback_data;
758         tg_data->is_login_activated = EINA_TRUE;
759 }
760
761 void tg_type_notification(struct tgl_state *TLS, struct tgl_user* buddy, enum tgl_typing_status status)
762 {
763         char *name_of_buddy = NULL;
764
765         if (buddy->first_name && buddy->last_name) {
766                 name_of_buddy = (char *)malloc(strlen(buddy->first_name) + strlen(buddy->last_name) + 1);
767                 strcpy(name_of_buddy, buddy->first_name);
768                 strcat(name_of_buddy, buddy->last_name);
769         } else if (buddy->first_name) {
770                 name_of_buddy = (char *)malloc(strlen(buddy->first_name) + 1);
771                 strcpy(name_of_buddy, buddy->first_name);
772         } else {
773                 name_of_buddy = (char *)malloc(strlen(" ") + 1);
774                 strcpy(name_of_buddy, " ");
775         }
776
777         send_buddy_type_notification_response(TLS->callback_data, buddy->id.id, name_of_buddy, status);
778
779         if (name_of_buddy) {
780                 free(name_of_buddy);
781                 name_of_buddy = NULL;
782         }
783 }
784
785 void tg_type_in_chat_notification(struct tgl_state *TLS, struct tgl_user *U, struct tgl_chat *C, enum tgl_typing_status status)
786 {
787
788 }
789
790 void tg_type_in_secret_chat_notification(struct tgl_state *TLS, struct tgl_secret_chat *E)
791 {
792
793 }
794
795 void tg_status_notification(struct tgl_state *TLS, struct tgl_user *buddy)
796 {
797         if (!buddy) {
798                 return;
799         }
800
801         update_buddy_into_db(BUDDY_INFO_TABLE_NAME, buddy);
802
803         char *name_of_buddy = NULL;
804         if (buddy->first_name && buddy->last_name) {
805                 name_of_buddy = (char *)malloc(strlen(buddy->first_name) + strlen(buddy->last_name) + 1);
806                 strcpy(name_of_buddy, buddy->first_name);
807                 strcat(name_of_buddy, buddy->last_name);
808         } else if (buddy->first_name) {
809                 name_of_buddy = (char *)malloc(strlen(buddy->first_name) + 1);
810                 strcpy(name_of_buddy, buddy->first_name);
811         } else {
812                 name_of_buddy = (char *)malloc(strlen(" ") + 1);
813                 strcpy(name_of_buddy, " ");
814         }
815
816         send_buddy_status_notification_response(TLS->callback_data, buddy->id.id, name_of_buddy, buddy->status.online);
817
818         if (name_of_buddy) {
819                 free(name_of_buddy);
820                 name_of_buddy = NULL;
821         }
822 }
823
824 void tg_user_registered(struct tgl_state *TLS, struct tgl_user *U)
825 {
826
827 }
828
829 void tg_user_activated(struct tgl_state *TLS, struct tgl_user *U)
830 {
831
832 }
833
834 void tg_new_authorization(struct tgl_state *TLS, const char *device, const char *location)
835 {
836
837 }
838
839 void tg_chat_update(struct tgl_state *TLS, struct tgl_chat* chat_info, unsigned flags)
840 {
841         tg_engine_data_s *tg_data;
842         tg_data = TLS->callback_data;
843
844         if (chat_info && chat_info->flags == 144) {
845                 return;
846         }
847
848         if (flags == TGL_GROUP_CHAT_CREATED) {
849 #if 0
850                 insert_chat_info_to_db(chat_info, NULL);
851                 tgl_peer_t* UC = tgl_peer_get(TLS, chat_info->id);
852                 insert_peer_into_database(UC, 0, 0);
853 #endif
854                 //if (tg_data->is_loading_completed) {
855                         tgl_do_get_chat_info(TLS, chat_info->id, 0, &on_chat_info_received, NULL);
856                 //}
857         }
858
859         if (!(flags & TGL_UPDATE_CREATED)) {
860
861                 if (!(flags & TGL_UPDATE_DELETED)) {
862                         //printf("updated");
863                 } else {
864                         //printf("deleted");
865                 }
866         }
867
868 }
869
870 static inline void send_message(tg_engine_data_s *tg_data, struct tgl_user *buddy, const char *str, const char *name_of_buddy, int name_of_buddy_len)
871 {
872         char *update_msg;
873         int len;
874
875         /**
876          * "%s phone number updated" will be changed to IDS_STRING for i18n.
877          */
878         len = name_of_buddy_len + strlen(str);
879         update_msg = (char *)malloc(len + 1);
880         if (!update_msg) {
881                 return;
882         }
883
884         snprintf(update_msg, len, str, name_of_buddy);
885         send_contact_updated_response(tg_data, buddy->id.id, update_msg);
886         free(update_msg);
887 }
888
889 void tg_user_update(struct tgl_state *TLS, struct tgl_user *buddy, unsigned flags)
890 {
891         char *name_of_buddy;
892         int name_of_buddy_len;
893         static const char *NO_NAME = " ";
894
895         if (flags & TGL_UPDATE_CREATED) {
896                 return;
897         }
898
899         if (buddy->first_name && buddy->last_name) {
900                 int first_len = strlen(buddy->first_name);
901                 int last_len = strlen(buddy->last_name);
902
903                 name_of_buddy_len = first_len + last_len;
904
905                 name_of_buddy = (char *)malloc(name_of_buddy_len + 1);
906
907                 strcpy(name_of_buddy, buddy->first_name);
908                 strcpy(name_of_buddy + first_len, buddy->last_name);
909         } else if (buddy->first_name) {
910                 name_of_buddy = strdup(buddy->first_name);
911                 name_of_buddy_len = strlen(name_of_buddy);
912         } else {
913                 name_of_buddy = (char *)NO_NAME;
914                 name_of_buddy_len = strlen(NO_NAME);
915         }
916
917         if (!name_of_buddy) {
918                 /**
919                  * @note
920                  * Unable to allocate heap for buddy name
921                  */
922                 name_of_buddy = (char *)NO_NAME;
923                 name_of_buddy_len = strlen(NO_NAME);
924         }
925
926         if (!(flags & TGL_UPDATE_DELETED)) {
927                 update_buddy_into_db(BUDDY_INFO_TABLE_NAME, buddy);
928
929                 if (flags & TGL_UPDATE_PHONE) {
930                         send_message(TLS->callback_data, buddy, "%s phone number updated.", name_of_buddy, name_of_buddy_len);
931                 }
932                 if (flags & TGL_UPDATE_CONTACT) {
933                         send_message(TLS->callback_data, buddy, "%s contact updated.", name_of_buddy, name_of_buddy_len);
934                 }
935                 if (flags & TGL_UPDATE_PHOTO) {
936                         send_message(TLS->callback_data, buddy, "%s photo updated.", name_of_buddy, name_of_buddy_len);
937                         //tgl_do_get_user_info(TLS, buddy->id, 0, &on_buddy_info_loaded, NULL);
938                 }
939                 if (flags & TGL_UPDATE_BLOCKED) {
940                         send_message(TLS->callback_data, buddy, "%s contact blocked.", name_of_buddy, name_of_buddy_len);
941                 }
942                 if (flags & TGL_UPDATE_REAL_NAME) {
943                         send_message(TLS->callback_data, buddy, "%s name updated.", name_of_buddy, name_of_buddy_len);
944                 }
945                 if (flags & TGL_UPDATE_NAME) {
946                         send_message(TLS->callback_data, buddy, "%s contact name updated.", name_of_buddy, name_of_buddy_len);
947                 }
948                 if (flags & TGL_UPDATE_REQUESTED) {
949                         send_message(TLS->callback_data, buddy, "%s status updated.", name_of_buddy, name_of_buddy_len);
950                 }
951                 if (flags & TGL_UPDATE_WORKING) {
952                         send_message(TLS->callback_data, buddy, "%s status updated.", name_of_buddy, name_of_buddy_len);
953                 }
954                 if (flags & TGL_UPDATE_FLAGS) {
955                         send_message(TLS->callback_data, buddy, "%s flags updated.", name_of_buddy, name_of_buddy_len);
956                 }
957                 if (flags & TGL_UPDATE_TITLE) {
958                         send_message(TLS->callback_data, buddy, "%s title updated.", name_of_buddy, name_of_buddy_len);
959                 }
960                 if (flags & TGL_UPDATE_ADMIN) {
961                         send_message(TLS->callback_data, buddy, "%s admin updated.", name_of_buddy, name_of_buddy_len);
962                 }
963                 if (flags & TGL_UPDATE_MEMBERS) {
964                         send_message(TLS->callback_data, buddy, "%s memgers updated.", name_of_buddy, name_of_buddy_len);
965                 }
966                 if (flags & TGL_UPDATE_ACCESS_HASH) {
967                         send_message(TLS->callback_data, buddy, "%s access hash updated.", name_of_buddy, name_of_buddy_len);
968                 }
969                 if (flags & TGL_UPDATE_USERNAME) {
970                         send_message(TLS->callback_data, buddy, "%s username updated.", name_of_buddy, name_of_buddy_len);
971                 }
972         } else {
973                 send_message(TLS->callback_data, buddy, "%s contact deleted.", name_of_buddy, name_of_buddy_len);
974         }
975
976         if (name_of_buddy != NO_NAME) {
977                 free(name_of_buddy);
978                 name_of_buddy = NULL;
979         }
980 }
981
982 void tg_secret_chat_update(struct tgl_state *TLS, struct tgl_secret_chat *C, unsigned flags)
983 {
984
985 }
986
987 void on_new_chat_info_received(struct tgl_state *TLS, void *callback_extra, int success, struct tgl_chat *chat_info)
988 {
989         tg_engine_data_s *tg_data;
990
991         struct tgl_message *M = callback_extra;
992
993         if (!chat_info) {
994                 return;
995         }
996
997         if (chat_info->user_list) {
998                 for (int i = 0; i < chat_info->user_list_size; i++) {
999                         int user_id = chat_info->user_list[i].user_id;
1000                         Eina_Bool is_present_in_db = is_user_present_buddy_table(user_id);
1001                         char* tb_name = get_table_name_from_number(user_id);
1002                         create_buddy_msg_table(tb_name);
1003                         if (!is_present_in_db) {
1004                                 // add to buddy table
1005                                 tgl_peer_id_t from_id;
1006                                 from_id.id = user_id;
1007                                 from_id.type = TGL_PEER_USER;
1008                                 tgl_do_get_user_info(TLS, from_id, 0, on_new_buddy_info_loaded, NULL);
1009                         }
1010                         free(tb_name);
1011                 }
1012         }
1013
1014         tg_data = TLS->callback_data;
1015
1016         tgl_peer_t* UC = tgl_peer_get(TLS, M->from_id);
1017         int msg_len = strlen(UC->user.first_name) + strlen(" created the group") + 1;
1018         char* creator_name = (char*)malloc(msg_len);
1019         strcpy(creator_name, UC->user.first_name);
1020         strcat(creator_name, " created the group");
1021
1022         int cur_time = time(NULL);
1023         M->id = chat_info->id.id;
1024         M->message = creator_name;
1025         M->message_len = msg_len;
1026         M->unread = 1;
1027         M->date = cur_time;
1028         insert_buddy_msg_to_db(M);
1029         free(creator_name);
1030
1031         tgl_peer_t* chat_UC = tgl_peer_get(TLS, chat_info->id);
1032         insert_chat_info_to_db(chat_info, NULL);
1033         chat_UC->last = M;
1034         insert_peer_into_database(chat_UC, 0, 0, 0);
1035
1036         send_new_group_added_response(tg_data, chat_info->id.id);
1037
1038 }
1039
1040 void on_group_chat_info_updated(struct tgl_state *TLS, void *callback_extra, int success, struct tgl_chat *chat_info)
1041 {
1042         tg_engine_data_s *tg_data;
1043
1044         if (!chat_info) {
1045                 return;
1046         }
1047
1048         tg_data = TLS->callback_data;
1049         char *type_of_change = callback_extra;
1050
1051         if (!type_of_change) {
1052                 type_of_change = strdup("");
1053         }
1054
1055         tgl_peer_t* chat_UC = tgl_peer_get(TLS, chat_info->id);
1056         insert_chat_info_to_db(chat_info, NULL);
1057         insert_peer_into_database(chat_UC, 0, 0, 0);
1058         send_group_chat_updated_response(tg_data, chat_info->id.id, type_of_change);
1059         free(type_of_change);
1060 }
1061
1062 void on_new_chat_pic_loaded(struct tgl_state *TLS, void *callback_extra, int success, char *filename)
1063 {
1064         struct tgl_message *M = callback_extra;
1065
1066
1067         if (filename) {
1068
1069                 tgl_peer_t* peer = tgl_peer_get(TLS, M->from_id);
1070                 int msg_len = strlen(peer->user.first_name) + strlen(" changed group icon") + 1;
1071                 char* creator_name = (char*)malloc(msg_len);
1072                 strcpy(creator_name, peer->user.first_name);
1073                 strcat(creator_name, " changed group icon");
1074
1075                 int cur_time = time(NULL);
1076                 M->id = cur_time;
1077                 M->message = creator_name;
1078                 M->message_len = msg_len;
1079                 M->date = cur_time;
1080                 M->unread = 1;
1081                 insert_buddy_msg_to_db(M);
1082                 free(creator_name);
1083                 send_message_received_response(TLS->callback_data, M->from_id.id, M->to_id.id, M->id, tgl_get_peer_type(M->to_id));
1084
1085
1086                 tgl_peer_t* UC = tgl_peer_get(TLS, M->to_id);
1087                 struct tgl_chat *chat_info = &(UC->chat);
1088                 update_chat_info_to_db(chat_info, filename);
1089                 update_peer_info_database(UC, 0);
1090                 update_buddy_pic_db(filename, PEER_INFO_TABLE_NAME, chat_info->id.id);
1091                 send_buddy_profile_pic_updated_response(TLS->callback_data, chat_info->id.id, filename);
1092         }
1093 }
1094
1095 void on_media_sticker_loaded(struct tgl_state *TLS, void *callback_extra, int success, char *filename)
1096 {
1097         struct tgl_message *M = (struct tgl_message*)callback_extra;
1098         if (success && filename) {
1099                 // update in db and send info to app...
1100                 long long media_id = M->media.document.id;
1101                 update_receive_media_info_in_db(media_id, filename);
1102                 tg_engine_data_s *tg_data = TLS->callback_data;
1103                 if (M->from_id.id == tg_data->id.id) {
1104
1105                 } else {
1106                         send_message_received_response(TLS->callback_data, M->from_id.id, M->to_id.id, M->id, tgl_get_peer_type(M->to_id));
1107                 }
1108         }
1109 }
1110
1111 void on_video_thumb_loaded(struct tgl_state *TLS, void *callback_extra, int success, char *filename)
1112 {
1113         struct tgl_message *M = (struct tgl_message*)callback_extra;
1114         if (success && filename) {
1115                 // update in db and send info to app...
1116                 long long media_id = M->media.document.id;
1117                 update_video_thumb_in_db(media_id, filename);
1118                 tg_engine_data_s *tg_data = TLS->callback_data;
1119                 if (M->from_id.id == tg_data->id.id) {
1120                         send_video_thumb_download_completed_response(tg_data, M->from_id.id, M->to_id.id, media_id, filename, NULL);
1121                 } else {
1122                         send_message_received_response(TLS->callback_data, M->from_id.id, M->to_id.id, M->id, tgl_get_peer_type(M->to_id));
1123                 }
1124         }
1125 }
1126
1127 struct tg_temp_msg_data {
1128         Ecore_Timer* send_timer;
1129         struct tgl_state *TLS;
1130         struct tgl_message *M;
1131 };
1132
1133 static Eina_Bool on_msg_received_cb(void *data)
1134 {
1135         struct tg_temp_msg_data *msg_data = data;
1136         insert_buddy_msg_to_db(msg_data->M);
1137         if (msg_data->M->media.type != tgl_message_media_none) {
1138                 insert_media_info_to_db(msg_data->M, NULL);
1139                 if (msg_data->M->media.type != tgl_message_media_none && (msg_data->M->media.document.flags & FLAG_DOCUMENT_VIDEO)) {
1140                         tgl_do_load_document_thumb(msg_data->TLS, &(msg_data->M->media.document), on_video_thumb_loaded, msg_data->M);
1141                         if (msg_data->send_timer) {
1142                                 ecore_timer_del(msg_data->send_timer);
1143                         }
1144                         free(msg_data);
1145                         return ECORE_CALLBACK_CANCEL;
1146                 }
1147         }
1148         // inform to application
1149         send_message_received_response(msg_data->TLS->callback_data, msg_data->M->from_id.id, msg_data->M->to_id.id, msg_data->M->id, tgl_get_peer_type(msg_data->M->to_id));
1150         if (msg_data->send_timer) {
1151                 ecore_timer_del(msg_data->send_timer);
1152         }
1153         free(msg_data);
1154         return ECORE_CALLBACK_CANCEL;
1155 }
1156
1157 void on_requested_chat_info_received(struct tgl_state *TLS, void *callback_extra, int success, struct tgl_chat *chat_info)
1158 {
1159         tg_engine_data_s *tg_data;
1160
1161         struct tgl_message *M = callback_extra;
1162
1163         char *msg_table;
1164
1165
1166         if (!chat_info) {
1167                 return;
1168         }
1169         if (!chat_info->user_list) {
1170                 tgl_do_get_chat_info(TLS, chat_info->id, 0, &on_requested_chat_info_received, callback_extra);
1171                 return;
1172         }
1173
1174         tg_data = TLS->callback_data;
1175
1176         msg_table = get_table_name_from_number(chat_info->id.id);
1177
1178         create_buddy_msg_table(msg_table);
1179
1180         insert_chat_info_to_db(chat_info, NULL);
1181         struct tgl_photo *pic = &(chat_info->photo);
1182         if (pic) {
1183                 tgl_do_load_photo(TLS, pic, &on_chat_pic_loaded, chat_info);
1184         }
1185
1186         // send message
1187         int msg_id = insert_current_date_to_table(msg_table);
1188         if (msg_id > 0) {
1189                 send_message_received_response(TLS->callback_data, M->from_id.id, M->to_id.id, msg_id, tgl_get_peer_type(M->to_id));
1190                 struct tg_temp_msg_data *msg_data = (struct tg_temp_msg_data*)malloc(sizeof(struct tg_temp_msg_data));
1191                 msg_data->M = M;
1192                 msg_data->TLS = TLS;
1193                 msg_data->send_timer = ecore_timer_add(1, on_msg_received_cb, msg_data);
1194         } else {
1195                 if (M->media.type != tgl_message_media_none && (M->media.document.flags & FLAG_DOCUMENT_AUDIO)) {
1196                         M->message = strdup("Audio");
1197                         M->message_len = strlen("Audio");
1198                 } else if (M->media.type != tgl_message_media_none && (M->media.document.flags & FLAG_DOCUMENT_VIDEO)) {
1199                         M->message = strdup("Video");
1200                         M->message_len = strlen("Video");
1201                 }
1202                 insert_buddy_msg_to_db(M);
1203                 if (M->media.type != tgl_message_media_none) {
1204                         insert_media_info_to_db(M, NULL);
1205                         if (M->media.type != tgl_message_media_none && (M->media.document.flags & FLAG_DOCUMENT_VIDEO)) {
1206                                 tgl_do_load_document_thumb(TLS, &(M->media.document), on_video_thumb_loaded, M);
1207                                 return;
1208                         }
1209                 }
1210                 // inform to application
1211                 send_message_received_response(TLS->callback_data, M->from_id.id, M->to_id.id, M->id, tgl_get_peer_type(M->to_id));
1212         }
1213
1214         free(msg_table);
1215 }
1216
1217
1218 void on_requested_update_chat_received(struct tgl_state *TLS, void *callback_extra, int success, struct tgl_chat *chat_info)
1219 {
1220         tg_engine_data_s *tg_data;
1221         char *msg_table;
1222         msg_table = get_table_name_from_number(chat_info->id.id);
1223         create_buddy_msg_table(msg_table);
1224
1225         if (!chat_info) {
1226                 return;
1227         }
1228
1229         if (chat_info->flags == 144) {
1230                 return;
1231         }
1232         int msg_count = get_number_of_messages(msg_table);
1233         if (msg_count <= 0) {
1234                 if (chat_info->admin_id > 0) {
1235                         set_date_item_to_table(msg_table, chat_info->date);
1236                         tgl_peer_id_t admin_id;
1237                         admin_id.id = chat_info->admin_id;
1238                         admin_id.type = TGL_PEER_USER;
1239
1240                         tgl_peer_t* UC = tgl_peer_get(TLS, admin_id);
1241                         int msg_len = strlen(UC->user.first_name) + strlen(" created the group") + 1;
1242                         char* creator_name = (char*)malloc(msg_len);
1243                         strcpy(creator_name, UC->user.first_name);
1244                         strcat(creator_name, " created the group");
1245                         struct tgl_message msg;
1246                         int cur_time = chat_info->date;
1247                         msg.to_id = chat_info->id;
1248                         msg.from_id = admin_id;
1249                         msg.id = chat_info->id.id;
1250                         msg.message = creator_name;
1251                         msg.message_len = msg_len;
1252                         msg.unread = 0;
1253                         msg.date = cur_time;
1254                         msg.media.type = tgl_message_media_none;
1255                         msg.service = 1;
1256                         msg.out = 0;
1257
1258                         insert_buddy_msg_to_db(&msg);
1259                         free(creator_name);
1260                         //send_message_received_response(TLS->callback_data, msg.from_id.id, msg.to_id.id, msg.id, tgl_get_peer_type(msg.to_id));
1261                 }
1262
1263         }
1264
1265         free(msg_table);
1266
1267         if (!chat_info->user_list) {
1268                 tgl_do_get_chat_info(TLS, chat_info->id, 0, &on_chat_info_received, NULL);
1269                 return;
1270         }
1271
1272         tg_data = TLS->callback_data;
1273
1274         insert_chat_info_to_db(chat_info, NULL);
1275         struct tgl_photo *pic = &(chat_info->photo);
1276         if (pic) {
1277                 tgl_do_load_photo(TLS, pic, &on_chat_pic_loaded, chat_info);
1278         }
1279         //char *type_of_change = strdup("add_user");
1280         tgl_peer_t* chat_UC = tgl_peer_get(TLS, chat_info->id);
1281         insert_chat_info_to_db(chat_info, NULL);
1282         insert_peer_into_database(chat_UC, 0, 0, 0);
1283         send_response_to_group_chat_updated_response(tg_data, chat_info->id.id);
1284         //free(type_of_change);
1285 }
1286
1287 void do_update_chat_info(int chat_id)
1288 {
1289         tgl_peer_id_t to_id;
1290         to_id.id = chat_id;
1291         to_id.type = TGL_PEER_CHAT;
1292         tgl_do_get_chat_info(s_info.TLS, to_id, 0, &on_requested_update_chat_received, NULL);
1293 }
1294
1295 void on_new_buddy_info_loaded(struct tgl_state *TLS, void *callback_extra, int success, struct tgl_user *U)
1296 {
1297         if (!U) {
1298                 return;
1299         }
1300         tg_engine_data_s *tg_data = TLS->callback_data;
1301         struct tgl_message *M = callback_extra;
1302         if (U->id.id == tg_data->id.id) {
1303                 return;
1304         }
1305         tgl_peer_t* UC = tgl_peer_get(TLS, U->id);
1306         insert_peer_into_database(UC, 0, 0, 1);
1307         U->is_unknown = 1;
1308         init_insert_buddy_into_db(BUDDY_INFO_TABLE_NAME, U);
1309         struct tgl_photo* pic = &(U->photo);
1310         if (pic) {
1311                 tgl_do_load_photo(TLS, pic, &on_buddy_pic_loaded, U);
1312         }
1313
1314         send_new_buddy_added_response(tg_data, U->id.id);
1315
1316         if (M) {
1317                 char* tb_name = get_table_name_from_number(U->id.id);
1318                 int msg_id = insert_current_date_to_table(tb_name);
1319                 free(tb_name);
1320                 if (msg_id > 0) {
1321                         send_message_received_response(TLS->callback_data, M->from_id.id, M->to_id.id, msg_id, tgl_get_peer_type(M->to_id));
1322
1323                         struct tg_temp_msg_data *msg_data = (struct tg_temp_msg_data*)malloc(sizeof(struct tg_temp_msg_data));
1324                         msg_data->M = M;
1325                         msg_data->TLS = TLS;
1326                         msg_data->send_timer = ecore_timer_add(3, on_msg_received_cb, msg_data);
1327                 } else {
1328                         if (M->media.type != tgl_message_media_none && (M->media.document.flags & FLAG_DOCUMENT_AUDIO)) {
1329                                 M->message = strdup("Audio");
1330                                 M->message_len = strlen("Audio");
1331                         } else if (M->media.type != tgl_message_media_none && (M->media.document.flags & FLAG_DOCUMENT_VIDEO)) {
1332                                 M->message = strdup("Video");
1333                                 M->message_len = strlen("Video");
1334                         }
1335                         insert_buddy_msg_to_db(M);
1336                         if (M->media.type != tgl_message_media_none) {
1337                                 insert_media_info_to_db(M, NULL);
1338                                 if (M->media.type != tgl_message_media_none && (M->media.document.flags & FLAG_DOCUMENT_VIDEO)) {
1339                                         tgl_do_load_document_thumb(TLS, &(M->media.document), on_video_thumb_loaded, M);
1340                                         return;
1341                                 } else if (M->media.type != tgl_message_media_none && (M->media.document.flags & FLAG_DOCUMENT_AUDIO)) {
1342
1343                                 }
1344                         }
1345                         // inform to application
1346                         send_message_received_response(TLS->callback_data, M->from_id.id, M->to_id.id, M->id, tgl_get_peer_type(M->to_id));
1347                 }
1348         }
1349 }
1350
1351 void tg_msg_receive(struct tgl_state *TLS, struct tgl_message *M)
1352 {
1353         if (M && TLS->started) {
1354
1355                 if (M->flags & (FLAG_MESSAGE_EMPTY | FLAG_DELETED)) {
1356                         return;
1357                 }
1358                 if (!(M->flags & FLAG_CREATED)) {
1359                         return;
1360                 }
1361                 if (M->service) {
1362                         // this is service message. to be handled in telegram.
1363                         if (tgl_get_peer_id(M->from_id) != TLS->our_id) {
1364                                 char *type_of_change = NULL;
1365                                 if (M->action.type == tgl_message_action_chat_create) {
1366
1367                                         char* msg_table = get_table_name_from_number(M->to_id.id);
1368                                         create_buddy_msg_table(msg_table);
1369                                         free(msg_table);
1370
1371                                         tgl_do_get_chat_info(TLS, M->to_id, 0, &on_new_chat_info_received, M);
1372
1373                                 } else if (M->action.type == tgl_message_action_chat_edit_title) {
1374                                         type_of_change = strdup("edit_title");
1375                                         tgl_peer_t* UC = tgl_peer_get(TLS, M->from_id);
1376                                         int msg_len = strlen(UC->user.first_name) + strlen(" changed the chat title") + 1;
1377                                         char* creator_name = (char*)malloc(msg_len);
1378                                         strcpy(creator_name, UC->user.first_name);
1379                                         strcat(creator_name, " changed the chat title");
1380
1381                                         int cur_time = time(NULL);
1382                                         M->id = cur_time;
1383                                         M->message = creator_name;
1384                                         M->message_len = msg_len;
1385                                         M->unread = 1;
1386                                         M->date = cur_time;
1387                                         insert_buddy_msg_to_db(M);
1388                                         free(creator_name);
1389                                         send_message_received_response(TLS->callback_data, M->from_id.id, M->to_id.id, M->id, tgl_get_peer_type(M->to_id));
1390                                         tgl_do_get_chat_info(TLS, M->to_id, 0, &on_group_chat_info_updated, type_of_change);
1391                                 } else if (M->action.type == tgl_message_action_chat_edit_photo) {
1392
1393                                         char* msg_table = get_table_name_from_number(M->to_id.id);
1394                                         create_buddy_msg_table(msg_table);
1395                                         int msg_id = insert_current_date_to_table(msg_table);
1396                                         free(msg_table);
1397                                         struct tgl_photo *pic = &(M->action.photo);
1398                                         if (pic) {
1399                                                 tgl_do_load_photo(TLS, pic, &on_new_chat_pic_loaded, M);
1400                                         }
1401
1402                                 } else if (M->action.type == tgl_message_action_chat_delete_photo) {
1403                                         type_of_change = strdup("delete_photo");
1404                                         tgl_peer_t* UC = tgl_peer_get(TLS,  M->from_id);
1405                                         int msg_len = strlen(UC->user.first_name) + strlen(" deleted the profile photo") + 1;
1406                                         char* creator_name = (char*)malloc(msg_len);
1407                                         strcpy(creator_name, UC->user.first_name);
1408                                         strcat(creator_name, " deleted the profile photo");
1409
1410                                         int cur_time = time(NULL);
1411                                         M->id = cur_time;
1412                                         M->message = creator_name;
1413                                         M->message_len = msg_len;
1414                                         M->unread = 1;
1415                                         M->date = cur_time;
1416                                         insert_buddy_msg_to_db(M);
1417                                         free(creator_name);
1418                                         send_message_received_response(TLS->callback_data, M->from_id.id, M->to_id.id, M->id, tgl_get_peer_type(M->to_id));
1419
1420
1421                                         char *filename = "";
1422                                         tgl_peer_t* lUC = tgl_peer_get(TLS, M->to_id);
1423                                         struct tgl_chat *chat_info = &(lUC->chat);
1424                                         update_chat_info_to_db(chat_info, filename);
1425                                         update_peer_info_database(lUC, 0);
1426                                         update_buddy_pic_db(filename, PEER_INFO_TABLE_NAME, chat_info->id.id);
1427                                         send_buddy_profile_pic_updated_response(TLS->callback_data, chat_info->id.id, filename);
1428
1429
1430                                 } else if (M->action.type == tgl_message_action_chat_add_user) {
1431                                         type_of_change = strdup("add_user");
1432                                         tgl_peer_t* UC = tgl_peer_get(TLS,  M->from_id);
1433                                         int msg_len = strlen(UC->user.first_name) + strlen(" added to the group") + 1;
1434                                         char* creator_name = (char*)malloc(msg_len);
1435                                         strcpy(creator_name, UC->user.first_name);
1436                                         strcat(creator_name, " added to the group");
1437
1438                                         int cur_time = time(NULL);
1439                                         M->id = cur_time;
1440                                         M->message = creator_name;
1441                                         M->message_len = msg_len;
1442                                         M->unread = 1;
1443                                         M->date = cur_time;
1444                                         insert_buddy_msg_to_db(M);
1445                                         free(creator_name);
1446                                         send_message_received_response(TLS->callback_data, M->from_id.id, M->to_id.id, M->id, tgl_get_peer_type(M->to_id));
1447                                         tgl_do_get_chat_info(TLS, M->to_id, 0, &on_group_chat_info_updated, type_of_change);
1448                                 } else if (M->action.type == tgl_message_action_chat_delete_user) {
1449                                         type_of_change = strdup("delete_user");
1450                                         tgl_peer_t* UC = tgl_peer_get(TLS,  M->from_id);
1451                                         int msg_len = strlen(UC->user.first_name) + strlen(" left the group") + 1;
1452                                         char* creator_name = (char*)malloc(msg_len);
1453                                         strcpy(creator_name, UC->user.first_name);
1454                                         strcat(creator_name, " left the group");
1455
1456                                         int cur_time = time(NULL);
1457                                         M->id = cur_time;
1458                                         M->message = creator_name;
1459                                         M->message_len = msg_len;
1460                                         M->unread = 1;
1461                                         M->date = cur_time;
1462                                         insert_buddy_msg_to_db(M);
1463                                         free(creator_name);
1464                                         send_message_received_response(TLS->callback_data, M->from_id.id, M->to_id.id, M->id, tgl_get_peer_type(M->to_id));
1465                                         tgl_do_get_chat_info(TLS, M->to_id, 0, &on_group_chat_info_updated, type_of_change);
1466                                 }
1467                         }
1468                         return;
1469                 }
1470
1471                 if (!tgl_get_peer_type(M->to_id)) {
1472                         // bad message
1473                         return;
1474                 }
1475
1476                 if (tgl_get_peer_type(M->to_id) == TGL_PEER_USER) {
1477                         if (M->out) {
1478                                 if (M->unread) {
1479
1480                                 } else {
1481
1482                                 }
1483                         } else {
1484                                 if (M->media.type != tgl_message_media_none) {
1485                                         M->message = NULL;
1486                                         M->message_len = 0;
1487                                 }
1488
1489                                 if (M->from_id.id == 333000 || M->from_id.id == 777000)
1490                                         M->service = 0;
1491
1492                                 char* tb_name = get_table_name_from_number(M->from_id.id);
1493                                 Eina_Bool is_present_in_db = is_user_present_buddy_table(M->from_id.id);
1494                                 create_buddy_msg_table(tb_name);
1495                                 if (!is_present_in_db) {
1496                                         tgl_do_get_user_info(TLS, M->from_id, 0, on_new_buddy_info_loaded, M);
1497                                         free(tb_name);
1498                                         return;
1499                                 }
1500                                 int msg_id = update_current_date_to_table(tb_name, M->date);
1501                                 free(tb_name);
1502
1503
1504                                 if (M->media.type != tgl_message_media_none && (M->media.document.flags & FLAG_DOCUMENT_AUDIO)) {
1505                                         M->message = strdup("Audio");
1506                                         M->message_len = strlen("Audio");
1507                                 } else if (M->media.type != tgl_message_media_none && (M->media.document.flags & FLAG_DOCUMENT_VIDEO)) {
1508                                         M->message = strdup("Video");
1509                                         M->message_len = strlen("Video");
1510                                 } else if (M->media.type != tgl_message_media_none && (M->media.document.flags & FLAG_DOCUMENT_STICKER)) {
1511                                         M->message = strdup("Sticker");
1512                                         M->message_len = strlen("Sticker");
1513                                 }
1514                                 insert_buddy_msg_to_db(M);
1515                                 if (M->media.type != tgl_message_media_none) {
1516                                         insert_media_info_to_db(M, NULL);
1517                                         if (M->media.type != tgl_message_media_none && (M->media.document.flags & FLAG_DOCUMENT_VIDEO)) {
1518                                                 tgl_do_load_document_thumb(TLS, &(M->media.document), on_video_thumb_loaded, M);
1519                                                 return;
1520                                         } else if (M->media.type != tgl_message_media_none && (M->media.document.flags & FLAG_DOCUMENT_STICKER)) {
1521                                                 tgl_do_load_document(TLS, &(M->media.document), on_media_sticker_loaded, M);
1522                                                 return;
1523                                         }
1524                                 }
1525                                 // inform to application
1526
1527                                 if (msg_id > 0)
1528                                         send_message_with_date_received_response(TLS->callback_data, M->from_id.id, M->to_id.id, M->id, msg_id, tgl_get_peer_type(M->to_id));
1529                                 else
1530                                         send_message_received_response(TLS->callback_data, M->from_id.id, M->to_id.id, M->id, tgl_get_peer_type(M->to_id));
1531                         }
1532
1533                 } else if (tgl_get_peer_type(M->to_id) == TGL_PEER_ENCR_CHAT) {
1534                         /* TODO */
1535                 } else {
1536
1537                         if ((tgl_get_peer_type(M->from_id) == TGL_PEER_USER) && (tgl_get_peer_id(M->from_id) == TLS->our_id)) {
1538
1539                         } else {
1540                                 if (M->media.type != tgl_message_media_none) {
1541                                         M->message = NULL;
1542                                         M->message_len = 0;
1543                                 }
1544                                 int user_id = 0;
1545                                 if (tgl_get_peer_type(M->to_id) == TGL_PEER_USER) {
1546                                         user_id = M->from_id.id;
1547                                 } else if (tgl_get_peer_type(M->to_id) == TGL_PEER_CHAT) {
1548                                         user_id = M->to_id.id;
1549                                 }
1550
1551                                 // check whether user is present or not
1552 #if 0
1553                                 Eina_Bool is_present_in_peer_db = is_user_present_buddy_table(user_id);
1554                                 if (!is_present_in_peer_db) {
1555                                         tgl_do_get_chat_info(TLS, M->to_id, 0, &on_requested_chat_info_received, M);
1556                                         return;
1557                                 }
1558 #endif
1559
1560                                 Eina_Bool is_present_in_chat_db = is_user_present_chat_table(user_id);
1561                                 if (!is_present_in_chat_db) {
1562                                         //sandeep
1563                                         tgl_do_get_chat_info(TLS, M->to_id, 0, &on_requested_chat_info_received, M);
1564                                         return;
1565                                 }
1566
1567                                 char* tb_name = get_table_name_from_number(user_id);
1568                                 int msg_id = update_current_date_to_table(tb_name, M->date);
1569                                 free(tb_name);
1570
1571                                 if (M->media.type != tgl_message_media_none && (M->media.document.flags & FLAG_DOCUMENT_AUDIO)) {
1572                                         M->message = strdup("Audio");
1573                                         M->message_len = strlen("Audio");
1574                                 } else if (M->media.type != tgl_message_media_none && (M->media.document.flags & FLAG_DOCUMENT_VIDEO)) {
1575                                         M->message = strdup("Video");
1576                                         M->message_len = strlen("Video");
1577                                 }
1578                                 insert_buddy_msg_to_db(M);
1579                                 if (M->media.type != tgl_message_media_none) {
1580                                         insert_media_info_to_db(M, "");
1581                                         if (M->media.type != tgl_message_media_none && (M->media.document.flags & FLAG_DOCUMENT_VIDEO)) {
1582                                                 tgl_do_load_document_thumb(TLS, &(M->media.document), on_video_thumb_loaded, M);
1583                                                 return;
1584                                         }
1585                                 }
1586                                 // inform to application
1587
1588                                 if (msg_id > 0) {
1589                                         send_message_with_date_received_response(TLS->callback_data, M->from_id.id, M->to_id.id, M->id, msg_id, tgl_get_peer_type(M->to_id));
1590                                 } else {
1591                                         send_message_received_response(TLS->callback_data, M->from_id.id, M->to_id.id, M->id, tgl_get_peer_type(M->to_id));
1592                                 }
1593                         }
1594                 }
1595         }
1596 }
1597
1598 void tg_our_id(struct tgl_state *TLS, int id)
1599 {
1600
1601 }
1602
1603 void tg_notification(struct tgl_state *TLS, char *type, char *message)
1604 {
1605
1606 }
1607
1608 void tg_user_status_update(struct tgl_state *TLS, struct tgl_user *U)
1609 {
1610
1611         if (tgl_get_peer_type(U->id) != TGL_PEER_USER) {
1612                 return;
1613         }
1614
1615         if (!U) {
1616                 // unknown user
1617         } else {
1618                 if ((U->flags & FLAG_DELETED)) {
1619                         // deleted user
1620                 } else if (!(U->flags & FLAG_CREATED)) {
1621                         // newly created user
1622                 } else {
1623                         // existing user
1624
1625                 }
1626
1627                 if (U->flags & FLAG_USER_SELF) {
1628                         update_buddy_into_db(USER_INFO_TABLE_NAME, U);
1629                 } else if (U->flags & FLAG_USER_CONTACT) {
1630                         update_buddy_into_db(BUDDY_INFO_TABLE_NAME, U);
1631 #if 0
1632                         struct tgl_user_status *S = &(U->status);
1633
1634                         if (S->online > 0) {
1635                                 //online;
1636                         } else {
1637                                 if (S->online == 0) {
1638                                         //"offline
1639                                 } else if (S->online == -1) {
1640                                         //offline was online ");
1641                                 } else if (S->online == -2) {
1642                                         // offline (was online recently)
1643                                 } else if (S->online == -3) {
1644                                         //offline (was online last week)
1645                                 } else if (S->online == -4) {
1646                                         //offline (was online last month)
1647                                 }
1648                         }
1649 #endif
1650                         // update status to application.
1651                         send_buddy_status_updated_response(TLS->callback_data, U->id.id);
1652
1653                 } else {
1654
1655                 }
1656         }
1657
1658 }
1659
1660 char *tg_create_print_name(struct tgl_state *TLS, tgl_peer_id_t id, const char *a1, const char *a2, const char *a3, const char *a4)
1661 {
1662         return NULL;
1663 }
1664
1665 struct tgl_update_callback upd_cb = {
1666         .new_msg = tg_new_msg,
1667         .marked_read = tg_marked_read,
1668         .logprintf = tg_logprintf,
1669         .get_string = tg_get_string,
1670         .logged_in = tg_logged_in,
1671         .started = tg_started,
1672         .type_notification = tg_type_notification,
1673         .type_in_chat_notification = tg_type_in_chat_notification,
1674         .type_in_secret_chat_notification = tg_type_in_secret_chat_notification,
1675         //.status_notification = tg_status_notification,
1676         .status_notification = NULL,
1677         .user_registered = tg_user_registered,
1678         .user_activated = tg_user_activated,
1679         .new_authorization = tg_new_authorization,
1680         //.user_update = tg_user_update,
1681         .user_update = NULL,
1682         //.chat_update = tg_chat_update,
1683         .chat_update = NULL,
1684         .secret_chat_update = tg_secret_chat_update,
1685         .msg_receive = tg_msg_receive,
1686         .our_id = tg_our_id,
1687         .user_status_update = tg_user_status_update
1688 };
1689
1690 void on_chat_pic_loaded(struct tgl_state *TLS, void *callback_extra, int success, char *filename)
1691 {
1692         struct tgl_chat *chat_info = callback_extra;
1693
1694         if (filename) {
1695                 update_chat_info_to_db(chat_info, filename);
1696                 tgl_peer_t* UC = tgl_peer_get(TLS, chat_info->id);
1697                 update_peer_info_database(UC, 0);
1698                 update_buddy_pic_db(filename, PEER_INFO_TABLE_NAME, chat_info->id.id);
1699                 send_buddy_profile_pic_updated_response(TLS->callback_data, chat_info->id.id, filename);
1700         }
1701 }
1702
1703 void on_buddy_pic_loaded(struct tgl_state *TLS, void *callback_extra, int success, char *filename)
1704 {
1705         struct tgl_user *buddy = callback_extra;
1706         tg_engine_data_s *tg_data = TLS->callback_data;
1707
1708         if (buddy && buddy->id.id == tg_data->id.id) {
1709                 if (filename) {
1710                         update_buddy_pic_db(filename, USER_INFO_TABLE_NAME, buddy->id.id);
1711                         update_buddy_pic_db(filename, BUDDY_INFO_TABLE_NAME, buddy->id.id);
1712                         send_buddy_profile_pic_updated_response(TLS->callback_data, buddy->id.id, filename);
1713                 }
1714                 return;
1715         }
1716
1717         if (filename) {
1718                 update_buddy_pic_db(filename, BUDDY_INFO_TABLE_NAME, buddy->id.id);
1719                 update_buddy_pic_db(filename, PEER_INFO_TABLE_NAME, buddy->id.id);
1720                 send_buddy_profile_pic_updated_response(TLS->callback_data, buddy->id.id, filename);
1721         }
1722 }
1723
1724 #if 0
1725 void on_new_group_icon_loaded(struct tgl_state *TLS, void *callback_extra, int success, struct tgl_message *M)
1726 {
1727         struct tgl_chat *chat_info = callback_extra;
1728         tg_engine_data_s *tg_data;
1729
1730         tg_data = TLS->callback_data;
1731
1732         if (tg_data->new_group_icon) {
1733
1734                 char *msg_table = get_table_name_from_number(chat_info->id.id);
1735                 create_buddy_msg_table(msg_table);
1736
1737                 char *msg_data = "group icon changed.";
1738                 struct tgl_message msg;
1739                 msg.from_id.id = 0;
1740                 msg.from_id.type = 0;
1741                 msg.date = 0;
1742                 msg.flags = 0;
1743                 msg.fwd_date = 0;
1744                 msg.fwd_from_id.id = 0;
1745                 msg.fwd_from_id.type = 0;
1746                 msg.id = 0;
1747                 msg.message = msg_data;
1748                 msg.message_len = strlen(msg_data);
1749                 msg.out = 0;
1750                 msg.service = 0;
1751                 msg.to_id.id = 0;
1752                 msg.to_id.type = tg_data->id.type;
1753                 msg.unread = 0;
1754                 msg.media.type = -1;
1755                 msg.is_marked_for_delete = 0;
1756                 int t = time(NULL);
1757                 insert_msg_into_db(&msg, msg_table, t);
1758                 free(msg_table);
1759
1760                 update_chat_info_to_db(chat_info, tg_data->new_group_icon);
1761                 update_buddy_pic_db(tg_data->new_group_icon, PEER_INFO_TABLE_NAME, chat_info->id.id);
1762                 send_buddy_profile_pic_updated_response(TLS->callback_data, chat_info->id.id, tg_data->new_group_icon);
1763
1764                 free(tg_data->new_group_icon);
1765                 tg_data->new_group_icon = NULL;
1766         }
1767 }
1768 #endif
1769
1770 void on_chat_info_received(struct tgl_state *TLS, void *callback_extra, int success, struct tgl_chat *chat_info)
1771 {
1772         tg_engine_data_s *tg_data;
1773         char *msg_table;
1774
1775         if (!chat_info) {
1776                 return;
1777         }
1778         if (chat_info->flags == 144) {
1779                 return;
1780         }
1781         msg_table = get_table_name_from_number(chat_info->id.id);
1782         create_buddy_msg_table(msg_table);
1783
1784         int msg_count = get_number_of_messages(msg_table);
1785         if (msg_count <= 0) {
1786                 if (chat_info->admin_id > 0) {
1787                         set_date_item_to_table(msg_table, chat_info->date);
1788                         tgl_peer_id_t admin_id;
1789                         admin_id.id = chat_info->admin_id;
1790                         admin_id.type = TGL_PEER_USER;
1791
1792                         tgl_peer_t* UC = tgl_peer_get(TLS, admin_id);
1793                         int msg_len = strlen(UC->user.first_name) + strlen(" created the group") + 1;
1794                         char* creator_name = (char*)malloc(msg_len);
1795                         strcpy(creator_name, UC->user.first_name);
1796                         strcat(creator_name, " created the group");
1797                         struct tgl_message msg;
1798                         int cur_time = chat_info->date;
1799                         msg.to_id = chat_info->id;
1800                         msg.from_id = admin_id;
1801                         msg.id = chat_info->id.id;
1802                         msg.message = creator_name;
1803                         msg.message_len = msg_len;
1804                         msg.unread = 0;
1805                         msg.date = cur_time;
1806                         msg.media.type = tgl_message_media_none;
1807                         msg.service = 1;
1808                         msg.out = 0;
1809
1810                         insert_buddy_msg_to_db(&msg);
1811                         free(creator_name);
1812                         send_message_received_response(TLS->callback_data, msg.from_id.id, msg.to_id.id, msg.id, tgl_get_peer_type(msg.to_id));
1813                 }
1814
1815         }
1816
1817         free(msg_table);
1818         if (!chat_info->user_list) {
1819                 tgl_do_get_chat_info(TLS, chat_info->id, 0, &on_chat_info_received, NULL);
1820                 return;
1821         } else {
1822                 for (int i = 0; i < chat_info->user_list_size; i++) {
1823                         int user_id = chat_info->user_list[i].user_id;
1824                         Eina_Bool is_present_in_db = is_user_present_buddy_table(user_id);
1825                         char* tb_name = get_table_name_from_number(user_id);
1826                         create_buddy_msg_table(tb_name);
1827                         if (!is_present_in_db) {
1828                                 // add to buddy table
1829                                 tgl_peer_id_t from_id;
1830                                 from_id.id = user_id;
1831                                 from_id.type = TGL_PEER_USER;
1832                                 tgl_do_get_user_info(TLS, from_id, 0, on_new_buddy_info_loaded, NULL);
1833                         }
1834                         free(tb_name);
1835                 }
1836         }
1837
1838         tg_data = TLS->callback_data;
1839
1840         insert_chat_info_to_db(chat_info, NULL);
1841         struct tgl_photo *pic = &(chat_info->photo);
1842         if (pic) {
1843                 tgl_do_load_photo(TLS, pic, &on_chat_pic_loaded, chat_info);
1844         }
1845 }
1846
1847 void on_buddy_info_loaded(struct tgl_state *TLS, void *callback_extra, int success, struct tgl_user *U)
1848 {
1849         if (!U) {
1850                 return;
1851         }
1852         tg_engine_data_s *tg_data = TLS->callback_data;
1853         if (U->id.id == tg_data->id.id) {
1854                 return;
1855         }
1856
1857         //update_buddy_into_db(BUDDY_INFO_TABLE_NAME, U);
1858         struct tgl_photo* pic = &(U->photo);
1859         if (pic) {
1860                 tgl_do_load_photo(TLS, pic, &on_buddy_pic_loaded, U);
1861         }
1862 }
1863
1864 void delete_pending_group_chats(tg_engine_data_s *tg_data)
1865 {
1866         Eina_List* id_list = get_chat_ids_to_be_deleted();
1867         if (id_list && eina_list_count(id_list) > 0) {
1868                 for (int i = 0; i < eina_list_count(id_list); i++) {
1869                         int chat_id_val = (int)eina_list_nth(id_list, i);
1870                         if (chat_id_val > 0) {
1871                                 tgl_peer_id_t chat_id;
1872                                 chat_id.id = chat_id_val;
1873                                 chat_id.type = TGL_PEER_CHAT;
1874
1875                                 tgl_peer_id_t self_id = tg_data->id;
1876
1877                                 tgl_do_del_user_from_chat(s_info.TLS, chat_id, self_id, NULL, NULL);
1878                         }
1879                 }
1880         }
1881 }
1882
1883 void on_offline_chat_received(struct tgl_state *TLS, void *callback_extra, int success, int size, struct tgl_message *list[])
1884 {
1885         tg_engine_data_s *tg_data = TLS->callback_data;
1886         for (int i = size - 1; i >= 0; i--) {
1887                 struct tgl_message* message = list[i];
1888                 if (message->service || message->from_id.id == tg_data->id.id) {
1889                         continue;
1890                 }
1891                 tg_msg_receive(s_info.TLS, message);
1892         }
1893         Eina_Bool is_offline_msg_requested = EINA_FALSE;
1894         tg_data->current_offline_buddy_index = tg_data->current_offline_buddy_index + 1;
1895         if (tg_data->current_offline_buddy_index < eina_list_count(tg_data->peer_list)) {
1896
1897                 for (int i = tg_data->current_offline_buddy_index; i < eina_list_count(tg_data->peer_list); i++) {
1898
1899                         tg_data->current_offline_buddy_index = i;
1900
1901                         tgl_peer_t* UC = eina_list_nth(tg_data->peer_list, i);
1902
1903                         struct tgl_message *last_msg = UC->last;
1904                         if (last_msg) {
1905                                 // check last message in message table
1906                                 char* msg_table = get_table_name_from_number(UC->id.id);
1907                                 struct tgl_message* org_last_msg = get_message_from_message_tableby_message_id(msg_table, last_msg->id);
1908                                 if (!org_last_msg) {
1909                                         tgl_do_get_history(s_info.TLS, UC->id, 10, 0, on_offline_chat_received, UC);
1910                                         is_offline_msg_requested = EINA_TRUE;
1911                                         break;
1912                                 } else {
1913                                         if (org_last_msg->message) {
1914                                                 free(org_last_msg->message);
1915                                         }
1916                                         free(org_last_msg);
1917                                 }
1918                                 free(msg_table);
1919                         }
1920                 }
1921         }
1922         if (!is_offline_msg_requested) {
1923                 delete_pending_group_chats(tg_data);
1924                 send_contacts_and_chats_load_done_response(TLS->callback_data, EINA_TRUE);
1925         }
1926 }
1927
1928 static Eina_Bool on_load_offline_messages(void *data)
1929 {
1930         struct tgl_state *TLS = data;
1931         if (!TLS) {
1932                 return ECORE_CALLBACK_CANCEL;
1933         }
1934         tg_engine_data_s *tg_data = TLS->callback_data;
1935         if(!tg_data) {
1936                 return ECORE_CALLBACK_CANCEL;
1937         }
1938
1939         if (tg_data->peer_list && eina_list_count(tg_data->peer_list) > 0) {
1940                 for (int i = 0; i < eina_list_count(tg_data->peer_list); i++) {
1941                         tgl_peer_t* UC = eina_list_nth(tg_data->peer_list, i);
1942                         char* msg_table = get_table_name_from_number(UC->id.id);
1943                         create_buddy_msg_table(msg_table);
1944                         delete_all_messages_from_chat(UC->id.id, UC->id.type);
1945                         free(msg_table);
1946                 }
1947         }
1948
1949         Eina_Bool is_offline_msg_requested = EINA_FALSE;
1950
1951         if (tg_data->peer_list && eina_list_count(tg_data->peer_list) > 0) {
1952                 for (int i = 0; i < eina_list_count(tg_data->peer_list); i++) {
1953
1954                         tg_data->current_offline_buddy_index = i;
1955
1956                         tgl_peer_t* UC = eina_list_nth(tg_data->peer_list, i);
1957
1958                         struct tgl_message *last_msg = UC->last;
1959                         if (last_msg) {
1960                                 // check last message in message table
1961                                 char* msg_table = get_table_name_from_number(UC->id.id);
1962                                 struct tgl_message* org_last_msg = get_message_from_message_tableby_message_id(msg_table, last_msg->id);
1963                                 if (!org_last_msg) {
1964                                         tgl_do_get_history(s_info.TLS, UC->id, 10, 0, on_offline_chat_received, UC);
1965                                         is_offline_msg_requested = EINA_TRUE;
1966                                         break;
1967                                 } else {
1968                                         if (org_last_msg->message) {
1969                                                 free(org_last_msg->message);
1970                                         }
1971                                         free(org_last_msg);
1972                                 }
1973                                 free(msg_table);
1974                         }
1975                 }
1976         }
1977
1978         if (!is_offline_msg_requested) {
1979                 delete_pending_group_chats(tg_data);
1980                 send_contacts_and_chats_load_done_response(TLS->callback_data, EINA_TRUE);
1981         }
1982
1983         return ECORE_CALLBACK_CANCEL;
1984 }
1985
1986
1987 extern void on_peer_chat_info_received(struct tgl_state *TLS, void *callback_extra, int success, struct tgl_chat *chat_info);
1988
1989 static Eina_Bool on_async_peer_info_requested(void *data)
1990 {
1991         struct tgl_state *TLS = data;
1992         if (!TLS)
1993                 return ECORE_CALLBACK_CANCEL;
1994
1995         tg_engine_data_s *tg_data = TLS->callback_data;
1996         if (!tg_data)
1997                 return ECORE_CALLBACK_CANCEL;
1998
1999         tg_data->current_chat_index = tg_data->current_chat_index + 1;
2000         if (tg_data->current_chat_index < eina_list_count(tg_data->chat_list)) {
2001                 tgl_peer_t* UC = eina_list_nth(tg_data->chat_list, tg_data->current_chat_index);
2002                 if (!UC)
2003                         return ECORE_CALLBACK_CANCEL;
2004
2005                 tgl_do_get_chat_info(TLS, UC->id, 0, &on_peer_chat_info_received, NULL);
2006         } else {
2007                 //send_contacts_and_chats_load_done_response(TLS->callback_data, EINA_TRUE);
2008                 ecore_timer_add(1, on_send_unsent_messages_requested, TLS);
2009         }
2010
2011         return ECORE_CALLBACK_CANCEL;
2012 }
2013
2014 void on_peer_chat_info_received(struct tgl_state *TLS, void *callback_extra, int success, struct tgl_chat *chat_info)
2015 {
2016         char *msg_table;
2017
2018         if (!chat_info) {
2019                 // go for next chat
2020                 goto end;
2021         }
2022         if (chat_info->flags == 144) {
2023                 // go for next chat
2024                 goto end;
2025         }
2026         msg_table = get_table_name_from_number(chat_info->id.id);
2027         create_buddy_msg_table(msg_table);
2028
2029         if (chat_info->admin_id > 0) {
2030                 set_date_item_to_table(msg_table, chat_info->date);
2031                 tgl_peer_id_t admin_id;
2032                 admin_id.id = chat_info->admin_id;
2033                 admin_id.type = TGL_PEER_USER;
2034
2035                 tgl_peer_t* UC = tgl_peer_get(TLS, admin_id);
2036                 int msg_len = strlen(UC->user.first_name) + strlen(" created the group") + 1;
2037                 char* creator_name = (char*)malloc(msg_len);
2038                 strcpy(creator_name, UC->user.first_name);
2039                 strcat(creator_name, " created the group");
2040                 struct tgl_message msg;
2041
2042                 msg.to_id = chat_info->id;
2043                 msg.from_id = admin_id;
2044                 msg.id = chat_info->id.id;
2045                 msg.message = creator_name;
2046                 msg.message_len = msg_len;
2047                 msg.unread = 0;
2048                 msg.date = chat_info->date;
2049                 msg.media.type = tgl_message_media_none;
2050                 msg.service = 1;
2051                 msg.out = 0;
2052
2053                 insert_buddy_msg_to_db(&msg);
2054                 free(creator_name);
2055         }
2056
2057         free(msg_table);
2058         if (chat_info->user_list) {
2059                 for (int i = 0; i < chat_info->user_list_size; i++) {
2060                         int user_id = chat_info->user_list[i].user_id;
2061                         Eina_Bool is_present_in_db = is_user_present_buddy_table(user_id);
2062                         char* tb_name = get_table_name_from_number(user_id);
2063                         create_buddy_msg_table(tb_name);
2064                         if (!is_present_in_db) {
2065                                 // add to buddy table
2066                                 tgl_peer_id_t from_id;
2067                                 from_id.id = user_id;
2068                                 from_id.type = TGL_PEER_USER;
2069                                 tgl_do_get_user_info(TLS, from_id, 0, on_new_buddy_info_loaded, NULL);
2070                         }
2071                         free(tb_name);
2072                 }
2073         } else {
2074
2075         }
2076
2077         insert_chat_info_to_db(chat_info, NULL);
2078
2079         struct tgl_photo *pic = &(chat_info->photo);
2080         if (pic) {
2081                 tgl_do_load_photo(TLS, pic, &on_chat_pic_loaded, chat_info);
2082         }
2083
2084 end:
2085         ecore_timer_add(1, on_async_peer_info_requested, TLS);
2086         return;
2087 }
2088
2089
2090 void on_contacts_and_chats_loaded(struct tgl_state *TLS, void *callback_extra, int success, int size, tgl_peer_id_t peers[], int last_msg_id[], int unread_count[])
2091 {
2092         tg_engine_data_s *tg_data = TLS->callback_data;
2093         if (tg_data->chat_list) {
2094                 eina_list_free(tg_data->chat_list);
2095                 tg_data->chat_list = NULL;
2096         }
2097         if (tg_data->buddy_list) {
2098                 eina_list_free(tg_data->buddy_list);
2099                 tg_data->buddy_list = NULL;
2100         }
2101         if (tg_data->peer_list) {
2102                 eina_list_free(tg_data->peer_list);
2103                 tg_data->peer_list = NULL;
2104         }
2105         for (int i = size - 1; i >= 0; i--) {
2106                 tgl_peer_t* UC = tgl_peer_get(TLS, peers[i]);
2107         // user exited from chat
2108                 if (UC->flags == 144) {
2109                         continue;
2110                 }
2111                 tg_data->peer_list = eina_list_append(tg_data->peer_list, UC);
2112                 // insert into peer table
2113                 switch (tgl_get_peer_type(peers[i])) {
2114                         case TGL_PEER_USER:
2115                                 tg_data->buddy_list = eina_list_append(tg_data->buddy_list, UC);
2116
2117                                 // check peer exists in peer table / buddy table
2118                                 Eina_Bool is_buddy_present = is_user_present_buddy_table(UC->id.id);
2119                                 if (!is_buddy_present) {
2120                                         struct tgl_user* buddy = &(UC->user);
2121                                         if (buddy) {
2122                                                 char* msg_table = get_table_name_from_number(buddy->id.id);
2123                                                 create_buddy_msg_table(msg_table);
2124                                                 free(msg_table);
2125
2126                                                 if (buddy->id.id == 333000 || buddy->id.id == 777000)
2127                                                         buddy->is_unknown = 0;
2128                                                 else
2129                                                         buddy->is_unknown = 1;
2130
2131                                                 init_insert_buddy_into_db(BUDDY_INFO_TABLE_NAME, buddy);
2132                                                 insert_peer_into_database(UC, last_msg_id[i], unread_count[i], 1);
2133                                                 tgl_do_get_user_info(TLS, buddy->id, 0, on_buddy_info_loaded, NULL);
2134                                         }
2135                                 }
2136                                 break;
2137                         case TGL_PEER_CHAT:
2138
2139                                 tg_data->chat_list = eina_list_append(tg_data->chat_list, UC);
2140                                 insert_peer_into_database(UC, last_msg_id[i], unread_count[i], 0);
2141
2142                                 break;
2143                         case TGL_PEER_ENCR_CHAT:
2144                                 // To-Do
2145                                 break;
2146                         default:
2147                                 break;
2148                 }
2149         }
2150
2151         if ((tg_data->chat_list == NULL) || (eina_list_count(tg_data->chat_list) <= 0)) {
2152                 //send_contacts_and_chats_load_done_response(TLS->callback_data, EINA_TRUE);
2153                 ecore_timer_add(1, on_send_unsent_messages_requested, TLS);
2154         } else {
2155                 // load chat info one by one.
2156                 tg_data->current_chat_index = 0;
2157                 tgl_peer_t* UC = eina_list_nth(tg_data->chat_list, tg_data->current_chat_index);
2158                 if (UC)
2159                         tgl_do_get_chat_info(TLS, UC->id, 0, &on_peer_chat_info_received, NULL);
2160         }
2161 }
2162
2163 void on_contacts_received(struct tgl_state *TLS, void *callback_extra, int success, int size, struct tgl_user *contacts[])
2164 {
2165         //tg_engine_data_s *tg_data = TLS->callback_data;
2166         for (int i = size - 1; i >= 0; i--) {
2167                 struct tgl_user *buddy = contacts[i];
2168                 char* msg_table = get_table_name_from_number(buddy->id.id);
2169                 create_buddy_msg_table(msg_table);
2170                 free(msg_table);
2171
2172                 buddy->is_unknown = 0;
2173                 init_insert_buddy_into_db(BUDDY_INFO_TABLE_NAME, buddy);
2174                 tgl_peer_t* UC = tgl_peer_get(TLS, buddy->id);
2175                 if (UC)
2176                         insert_peer_into_database(UC, 0, 0, 0);
2177         }
2178
2179         // inform client that contact loading is done.
2180         for (int i = size - 1; i >= 0; i--) {
2181                 struct tgl_user *buddy = contacts[i];
2182                 tgl_do_get_user_info(TLS, buddy->id, 0, on_buddy_info_loaded, NULL);
2183         }
2184
2185         tgl_do_get_dialog_list(TLS, on_contacts_and_chats_loaded, NULL);
2186
2187 }
2188
2189 void add_contacts_to_account(struct tgl_state *TLS)
2190 {
2191         tg_engine_data_s *tg_data = TLS->callback_data;
2192         if (sc_db_utils_connect()) {
2193                 Eina_List* contact_list = get_contact_list_from_device_db();
2194                 sc_db_utils_disconnect();
2195
2196                 if (!contact_list || eina_list_count(contact_list) <= 0) {
2197                         // no contacts avilable. empty contact list.
2198                         //tgl_do_get_dialog_list(TLS, on_contacts_and_chats_loaded, NULL);
2199                         // sandeep
2200                         tgl_do_update_contact_list(TLS, on_contacts_received, NULL);
2201                         if (contact_list) {
2202                                 eina_list_free(contact_list);
2203                         }
2204                         return;
2205                 }
2206                 int size = eina_list_count(contact_list);
2207                 if (size > 0) {
2208                         add_contacts_to_user(tg_data, size, contact_list);
2209                 } else {
2210                         eina_list_free(contact_list);
2211                         // sandeep
2212                         //tgl_do_get_dialog_list(TLS, on_contacts_and_chats_loaded, NULL);
2213                         tgl_do_update_contact_list(TLS, on_contacts_received, NULL);
2214                 }
2215         }
2216 }
2217
2218 void on_user_info_loaded(struct tgl_state *TLS, void *extra, int success, struct tgl_user *buddy)
2219 {
2220         tg_engine_data_s *tg_data = TLS->callback_data;
2221
2222         tg_data->id.id = buddy->id.id;
2223         tg_data->id.type = buddy->id.type;
2224
2225         struct tgl_photo* pic = &(buddy->photo);
2226         if (pic) {
2227                 tgl_do_load_photo(TLS, pic, &on_buddy_pic_loaded, buddy);
2228         }
2229
2230         buddy->is_unknown = 0;
2231         init_insert_buddy_into_db(USER_INFO_TABLE_NAME, buddy);
2232
2233 #if 0
2234         if (tg_data->is_first_time_registration) {
2235                 // send contact list to add friends.
2236                 //send_add_contacts_request(tg_data);
2237                 add_contacts_to_account(TLS);
2238         } else {
2239                 // sandeep
2240                 //tgl_do_get_dialog_list(TLS, on_contacts_and_chats_loaded, NULL);
2241                 tgl_do_update_contact_list(TLS, on_contacts_received, NULL);
2242         }
2243 #else
2244         add_contacts_to_account(TLS);
2245 #endif
2246 }
2247
2248 void on_message_sent_to_buddy(struct tgl_state *TLS, void *callback_extra, int success, struct tgl_message *message)
2249 {
2250         tg_engine_data_s *tg_data;
2251         struct tgl_message* org_msg = (struct tgl_message*)callback_extra;
2252         tg_data = TLS->callback_data;
2253
2254         if (success && message) {
2255                 tgl_peer_t* UC = tgl_peer_get(TLS, message->to_id);
2256                 if (UC) {
2257                         message->msg_state = TG_MESSAGE_STATE_SENT;
2258                         char* tb_name = get_table_name_from_number(message->to_id.id);
2259                         update_msg_into_db(message, tb_name, org_msg->id);
2260
2261                         // delete message from unsent db
2262                         delete_message_from_unsent_db(org_msg->id);
2263                         delete_media_from_unsent_db(org_msg->id);
2264
2265                         if (message->media.type == tgl_message_media_photo || message->media.type == tgl_message_media_document || message->media.type == tgl_message_media_geo) {
2266                                 update_sent_media_info_in_db(message, (long long)org_msg->id);
2267                         }
2268                         send_message_sent_to_buddy_response(tg_data, message->to_id.id, message->id, tb_name, EINA_TRUE, tgl_get_peer_type(message->to_id));
2269                         free(tb_name);
2270
2271                         if (message->media.type != tgl_message_media_none && (message->media.document.flags & FLAG_DOCUMENT_VIDEO)) {
2272                                 //tgl_do_load_document_thumb(TLS, &(message->media.document), on_video_thumb_loaded, message);
2273                         }
2274
2275                 }
2276         } else {
2277                 if (org_msg) {
2278                         org_msg->msg_state = TG_MESSAGE_STATE_FAILED;
2279                         char* tb_name = get_table_name_from_number(org_msg->to_id.id);
2280                         update_msg_into_db(org_msg, tb_name, org_msg->id);
2281                         if (org_msg->media.type == tgl_message_media_photo || org_msg->media.type == tgl_message_media_document || message->media.type == tgl_message_media_geo) {
2282                                 if (org_msg->media.type == tgl_message_media_photo) {
2283                                         org_msg->media.photo.sizes_num = 0;
2284                                         org_msg->media.photo.sizes = NULL;
2285                                 }
2286                                 update_sent_media_info_in_db(org_msg, (long long)org_msg->id);
2287                         }
2288                         send_message_sent_to_buddy_response(tg_data, org_msg->to_id.id, org_msg->id, tb_name, EINA_FALSE, tgl_get_peer_type(org_msg->to_id));
2289                         free(tb_name);
2290                 }
2291         }
2292         if (org_msg) {
2293                 if (org_msg->message) {
2294                         free(org_msg->message);
2295                 }
2296                 free(org_msg);
2297         }
2298 }
2299
2300 void on_image_download_completed(struct tgl_state *TLS, void *callback_extra, int success, char *filename)
2301 {
2302         tg_engine_data_s *tg_data = TLS->callback_data;
2303         struct tgl_photo* photo_prop = (struct tgl_photo*)callback_extra;
2304         long long media_id = photo_prop->id;
2305         int buddy_id = photo_prop->user_id;
2306         int to_id = photo_prop->to_peer_id;
2307         if (success) {
2308                 if (photo_prop && filename) {
2309                         update_receive_media_info_in_db(media_id, filename);
2310                         //send response to application
2311                         send_media_download_completed_response(tg_data, buddy_id, to_id, media_id, filename, photo_prop->caption);
2312                         free(photo_prop);
2313                 }
2314         } else {
2315                 send_media_download_completed_response(tg_data, buddy_id, to_id, media_id, NULL, NULL);
2316         }
2317 }
2318
2319 void on_document_download_completed(struct tgl_state *TLS, void *callback_extra, int success, char *filename)
2320 {
2321         tg_engine_data_s *tg_data = TLS->callback_data;
2322         struct tgl_document* doc_prop = (struct tgl_document*)callback_extra;
2323         long long media_id = doc_prop->id;
2324         int buddy_id = doc_prop->user_id;
2325         int to_id = doc_prop->to_peer_id;
2326         if (success) {
2327                 if (doc_prop && filename) {
2328                         update_receive_media_info_in_db(media_id, filename);
2329                         //send response to application
2330                         send_media_download_completed_response(tg_data, buddy_id, to_id, media_id, filename, doc_prop->caption);
2331                 }
2332         } else {
2333                 send_media_download_completed_response(tg_data, buddy_id, to_id, media_id, NULL, NULL);
2334         }
2335
2336         if (doc_prop) {
2337                 if (doc_prop->caption) {
2338                         free(doc_prop->caption);
2339                 }
2340                 free(doc_prop);
2341         }
2342
2343 }
2344
2345 void free_contact_data(Eina_List *contact_data)
2346 {
2347         contact_data_s* contact = NULL;
2348         EINA_LIST_FREE(contact_data, contact) {
2349                 if (contact->display_name) {
2350                         free(contact->display_name);
2351                         contact->display_name = NULL;
2352                 }
2353                 if (contact->first_name) {
2354                         free(contact->first_name);
2355                         contact->first_name = NULL;
2356                 }
2357                 if (contact->last_name) {
2358                         free(contact->last_name);
2359                         contact->last_name = NULL;
2360                 }
2361                 if (contact->phone_number) {
2362                         free(contact->phone_number);
2363                         contact->phone_number = NULL;
2364                 }
2365                 free(contact);
2366         }
2367 }
2368
2369 void on_contact_added(struct tgl_state *TLS, void *callback_extra, int success, int size, struct tgl_user *users[])
2370 {
2371         tg_engine_data_s* data = callback_extra;
2372
2373         data->current_index++;
2374
2375         if (data->current_index < eina_list_count(data->contact_list_to_add)) {
2376                 contact_data_s* contact = eina_list_nth(data->contact_list_to_add, data->current_index);
2377
2378                 if (!contact)
2379                         return;
2380
2381                 char *first_name = contact->first_name;
2382                 char *last_name = contact->last_name;
2383                 char *phone_number = contact->phone_number;
2384
2385                 if (!first_name) {
2386                         first_name = contact->display_name;
2387                         if (!first_name) {
2388                                 first_name = "";
2389                         }
2390                 }
2391
2392                 if (!last_name)
2393                         last_name = "";
2394
2395                 if (first_name && last_name && phone_number)
2396                         tgl_do_add_contact(tgl_engine_get_TLS(), phone_number, first_name, last_name, 0, on_contact_added, data);
2397                 else
2398                         on_contact_added(tgl_engine_get_TLS(), data, 0, 0, NULL);
2399
2400         } else {
2401                 tgl_do_update_contact_list(TLS, on_contacts_received, NULL);
2402                 free_contact_data(data->contact_list_to_add);
2403                 data->contact_list_to_add = NULL;
2404         }
2405 }
2406
2407 void on_new_group_icon_loaded(struct tgl_state *TLS, void *callback_extra, int success, struct tgl_message *M)
2408 {
2409         if (!success) {
2410                 /* TODO  send fail notification */
2411                 return;
2412         }
2413
2414         // send success notofication
2415         if (M) {
2416                 if (M->action.type == tgl_message_action_chat_create) {
2417
2418                 } else if (M->action.type == tgl_message_action_chat_edit_title) {
2419
2420                 } else if (M->action.type == tgl_message_action_chat_edit_photo) {
2421
2422                         char* msg_table = get_table_name_from_number(M->to_id.id);
2423                         create_buddy_msg_table(msg_table);
2424                         int msg_id = insert_current_date_to_table(msg_table);
2425
2426                         tgl_peer_t* UC = tgl_peer_get(TLS, M->from_id);
2427                         int msg_len = strlen(UC->user.first_name) + strlen(" changed profile photo") + 1;
2428                         char* creator_name = (char*)malloc(msg_len);
2429                         strcpy(creator_name, UC->user.first_name);
2430                         strcat(creator_name, " changed profile photo");
2431
2432
2433                         //send_message_received_response(TLS->callback_data, M->from_id.id, M->to_id.id,msg_id, tgl_get_peer_type(M->to_id));
2434                         int cur_time = time(NULL);
2435                         M->id = cur_time;
2436                         M->message = creator_name;
2437                         M->message_len = msg_len;
2438                         M->unread = 1;
2439                         M->date = cur_time;
2440                         insert_buddy_msg_to_db(M);
2441                         free(creator_name);
2442                         free(msg_table);
2443                         struct tgl_photo *pic = &(M->action.photo);
2444                         if (pic) {
2445                                 tgl_peer_t* UC = tgl_peer_get(TLS, M->to_id);
2446                                 struct tgl_chat *chat_info = &(UC->chat);
2447                                 tgl_do_load_photo(TLS, pic, &on_chat_pic_loaded, chat_info);
2448                         }
2449
2450
2451                 } else if (M->action.type == tgl_message_action_chat_delete_photo) {
2452
2453                 } else if (M->action.type == tgl_message_action_chat_add_user) {
2454
2455                 } else if (M->action.type == tgl_message_action_chat_delete_user) {
2456
2457                 }
2458                 send_message_received_response(TLS->callback_data, M->from_id.id, M->to_id.id, M->id, tgl_get_peer_type(M->to_id));
2459         }
2460 }
2461
2462 void on_new_group_created(struct tgl_state *TLS, void *callback_extra, int success, struct tgl_message *M)
2463 {
2464         tg_engine_data_s *tg_data = TLS->callback_data;
2465         if (!success) {
2466                 // send fail notification
2467         } else {
2468                 // send success notofication
2469                 if (M) {
2470                         if (M->action.type == tgl_message_action_chat_create) {
2471                                 char* msg_table = get_table_name_from_number(M->to_id.id);
2472                                 create_buddy_msg_table(msg_table);
2473
2474
2475                                 int msg_id = insert_current_date_to_table(msg_table);
2476                                 //send_message_received_response(TLS->callback_data, M->from_id.id, M->to_id.id,msg_id, tgl_get_peer_type(M->to_id));
2477
2478
2479                                 tgl_peer_t* UC = tgl_peer_get(TLS, M->from_id);
2480                                 int msg_len = strlen(UC->user.first_name) + strlen(" created the group") + 1;
2481                                 char* creator_name = (char*)malloc(msg_len);
2482                                 strcpy(creator_name, UC->user.first_name);
2483                                 strcat(creator_name, " created the group");
2484
2485
2486
2487                                 int cur_time = time(NULL);
2488                                 M->id = M->to_id.id;
2489                                 M->message = creator_name;
2490                                 M->message_len = msg_len;
2491                                 M->unread = 1;
2492                                 M->date = cur_time;
2493
2494                                 insert_buddy_msg_to_db(M);
2495                                 free(creator_name);
2496                                 free(msg_table);
2497                                 tgl_peer_t* chat_UC = tgl_peer_get(TLS, M->to_id);
2498                                 chat_UC->chat.date = M->date;
2499                                 insert_chat_info_to_db(&(chat_UC->chat), NULL);
2500                                 chat_UC->last = M;
2501                                 insert_peer_into_database(chat_UC, 0, 0, 0);
2502
2503                                 if (tg_data->new_group_icon) {
2504                                         tgl_peer_t* UC = tgl_peer_get(TLS, M->to_id);
2505                                         struct tgl_chat *chat_info = &(UC->chat);
2506                                         tgl_do_set_chat_photo(TLS, chat_info->id, tg_data->new_group_icon, on_new_group_icon_loaded, chat_info);
2507                                 }
2508
2509
2510                         } else if (M->action.type == tgl_message_action_chat_edit_title) {
2511
2512                         } else if (M->action.type == tgl_message_action_chat_edit_photo) {
2513
2514                         } else if (M->action.type == tgl_message_action_chat_delete_photo) {
2515
2516                         } else if (M->action.type == tgl_message_action_chat_add_user) {
2517
2518                         } else if (M->action.type == tgl_message_action_chat_delete_user) {
2519
2520                         }
2521                         send_new_group_added_response(tg_data, M->to_id.id);
2522                 }
2523         }
2524 }
2525
2526 void on_set_profile_picture_response_received(struct tgl_state *TLS, void *callback_extra, int success)
2527 {
2528         tg_engine_data_s *tg_data = TLS->callback_data;
2529         char *file_path = callback_extra;
2530         if (success) {
2531                 // update db
2532                 update_buddy_pic_db(file_path, USER_INFO_TABLE_NAME, tg_data->id.id);
2533                 update_buddy_pic_db(file_path, BUDDY_INFO_TABLE_NAME, tg_data->id.id);
2534                 send_self_profile_picture_updated_response(tg_data, file_path, EINA_TRUE);
2535         } else {
2536                 send_self_profile_picture_updated_response(tg_data, file_path, EINA_FALSE);
2537         }
2538         if (file_path) {
2539                 free(file_path);
2540         }
2541 }
2542 void set_profile_picture(tg_engine_data_s *tg_data, int buddy_id, const char *file_path)
2543 {
2544         if (file_path) {
2545                 char *org_path = strdup(file_path);
2546                 tgl_do_set_profile_photo(tgl_engine_get_TLS(), (char*)file_path, on_set_profile_picture_response_received, org_path);
2547         }
2548 }
2549
2550 void on_set_new_chat_title_response_received(struct tgl_state *TLS, void *callback_extra, int success, struct tgl_message *M)
2551 {
2552         if (success) {
2553                 char *type_of_change = NULL;
2554                 if (M && M->action.type == tgl_message_action_chat_edit_title) {
2555                         type_of_change = strdup("edit_title");
2556                         tgl_peer_t* UC = tgl_peer_get(TLS, M->from_id);
2557                         int msg_len = strlen(UC->user.first_name) + strlen(" changed the chat title") + 1;
2558                         char* creator_name = (char*)malloc(msg_len);
2559                         strcpy(creator_name, UC->user.first_name);
2560                         strcat(creator_name, " changed the chat title");
2561
2562                         int cur_time = time(NULL);
2563                         M->id = cur_time;
2564                         M->message = creator_name;
2565                         M->message_len = msg_len;
2566                         M->unread = 1;
2567                         M->date = cur_time;
2568                         insert_buddy_msg_to_db(M);
2569                         free(creator_name);
2570                         send_message_received_response(TLS->callback_data, M->from_id.id, M->to_id.id, M->id, tgl_get_peer_type(M->to_id));
2571                         tgl_do_get_chat_info(TLS, M->to_id, 0, &on_group_chat_info_updated, type_of_change);
2572                 }
2573         } else {
2574                 tg_engine_data_s *tg_data = TLS->callback_data;
2575                 struct tgl_chat *chat_info = (struct tgl_chat*)callback_extra;
2576                 send_group_chat_rename_response(tg_data, chat_info->id.id, EINA_FALSE);
2577         }
2578 }
2579
2580 void set_group_chat_new_title(tg_engine_data_s *tg_data, int buddy_id, const char *new_title)
2581 {
2582         if (new_title) {
2583                 tgl_peer_id_t peer_id;
2584                 peer_id.id = buddy_id;
2585                 peer_id.type = TGL_PEER_CHAT;
2586
2587                 tgl_peer_t* UC = tgl_peer_get(tgl_engine_get_TLS(), peer_id);
2588                 struct tgl_chat *chat_info = &(UC->chat);
2589                 tgl_do_rename_chat(tgl_engine_get_TLS(), chat_info->id, (char*)new_title, on_set_new_chat_title_response_received, chat_info);
2590         }
2591 }
2592
2593 void on_new_buddy_added_to_chat_response_received(struct tgl_state *TLS, void *callback_extra, int success, struct tgl_message *M)
2594 {
2595         if (success) {
2596                 char *type_of_change = NULL;
2597                 if (M && M->action.type == tgl_message_action_chat_add_user) {
2598                         type_of_change = strdup("add_user");
2599                         tgl_peer_t* UC = tgl_peer_get(TLS,  M->from_id);
2600
2601                         tgl_peer_id_t added_id;
2602                         added_id.id = M->action.user;
2603                         added_id.type = TGL_PEER_USER;
2604
2605                         tgl_peer_t* added_UC = tgl_peer_get(TLS, added_id);
2606                         char* new_user_name = replace(added_UC->print_name, '_', " ");
2607                         int msg_len = strlen(UC->user.first_name) + strlen(" added ") + strlen(new_user_name) + 1;
2608                         char* creator_name = (char*)malloc(msg_len);
2609                         strcpy(creator_name, UC->user.first_name);
2610                         strcat(creator_name, " added ");
2611                         strcat(creator_name, new_user_name);
2612                         free(new_user_name);
2613
2614                         int cur_time = time(NULL);
2615                         M->id = cur_time;
2616                         M->message = creator_name;
2617                         M->message_len = msg_len;
2618                         M->unread = 1;
2619                         M->date = cur_time;
2620                         insert_buddy_msg_to_db(M);
2621                         free(creator_name);
2622                         send_message_received_response(TLS->callback_data, M->from_id.id, M->to_id.id, M->id, tgl_get_peer_type(M->to_id));
2623                         tgl_do_get_chat_info(TLS, M->to_id, 0, &on_group_chat_info_updated, type_of_change);
2624                 }
2625         } else {
2626                 tg_engine_data_s *tg_data = TLS->callback_data;
2627                 struct tgl_chat *chat_info = (struct tgl_chat*)callback_extra;
2628                 send_group_chat_new_buddy_response(tg_data, chat_info->id.id, EINA_FALSE);
2629         }
2630 }
2631
2632 void set_group_chat_add_new_buddy(tg_engine_data_s *tg_data, int s_buddy_id, int s_chat_id)
2633 {
2634         tgl_peer_id_t chat_id;
2635         chat_id.id = s_chat_id;
2636         chat_id.type = TGL_PEER_CHAT;
2637
2638         tgl_peer_id_t buddy_id;
2639         buddy_id.id = s_buddy_id;
2640         buddy_id.type = TGL_PEER_USER;
2641
2642         tgl_peer_t* UC = tgl_peer_get(tgl_engine_get_TLS(), chat_id);
2643         struct tgl_chat *chat_info = &(UC->chat);
2644         tgl_do_add_user_to_chat(tgl_engine_get_TLS(), chat_id, buddy_id, 100, on_new_buddy_added_to_chat_response_received, chat_info);
2645 }
2646
2647
2648 void on_buddy_removed_from_chat_response_received(struct tgl_state *TLS, void *callback_extra, int success, struct tgl_message *M)
2649 {
2650         if (success) {
2651                 char *type_of_change = NULL;
2652                 if (M && M->action.type == tgl_message_action_chat_delete_user) {
2653                         type_of_change = strdup("delete_user");
2654                         tgl_peer_t* UC = tgl_peer_get(TLS,  M->from_id);
2655                         tgl_peer_id_t added_id;
2656                         added_id.id = M->action.user;
2657                         added_id.type = TGL_PEER_USER;
2658
2659                         tgl_peer_t* added_UC = tgl_peer_get(TLS, added_id);
2660                         char* new_user_name = replace(added_UC->print_name, '_', " ");
2661                         int msg_len = strlen(UC->user.first_name) + strlen(" removed ") + strlen(new_user_name) + 1;
2662                         char* creator_name = (char*)malloc(msg_len);
2663                         strcpy(creator_name, UC->user.first_name);
2664                         strcat(creator_name, " removed ");
2665                         strcat(creator_name, new_user_name);
2666                         free(new_user_name);
2667                         int cur_time = time(NULL);
2668                         M->id = cur_time;
2669                         M->message = creator_name;
2670                         M->message_len = msg_len;
2671                         M->unread = 1;
2672                         M->date = cur_time;
2673                         insert_buddy_msg_to_db(M);
2674                         free(creator_name);
2675                         send_message_received_response(TLS->callback_data, M->from_id.id, M->to_id.id, M->id, tgl_get_peer_type(M->to_id));
2676                         tgl_do_get_chat_info(TLS, M->to_id, 0, &on_group_chat_info_updated, type_of_change);
2677                 }
2678         } else {
2679                 tg_engine_data_s *tg_data = TLS->callback_data;
2680                 struct tgl_chat *chat_info = (struct tgl_chat*)callback_extra;
2681                 send_group_chat_delete_buddy_response(tg_data, chat_info->id.id, EINA_FALSE);
2682         }
2683 }
2684
2685 void set_group_chat_remove_buddy(tg_engine_data_s *tg_data, int s_buddy_id, int s_chat_id)
2686 {
2687         tgl_peer_id_t chat_id;
2688         chat_id.id = s_chat_id;
2689         chat_id.type = TGL_PEER_CHAT;
2690
2691         tgl_peer_id_t buddy_id;
2692         buddy_id.id = s_buddy_id;
2693         buddy_id.type = TGL_PEER_USER;
2694
2695         tgl_peer_t* UC = tgl_peer_get(tgl_engine_get_TLS(), chat_id);
2696         struct tgl_chat *chat_info = &(UC->chat);
2697         tgl_do_del_user_from_chat(tgl_engine_get_TLS(), chat_id, buddy_id, on_buddy_removed_from_chat_response_received, chat_info);
2698 }
2699
2700 void set_group_chat_profile_picture(tg_engine_data_s *tg_data, int buddy_id, const char *file_path)
2701 {
2702         if (file_path) {
2703                 tgl_peer_id_t peer_id;
2704                 peer_id.id = buddy_id;
2705                 peer_id.type = TGL_PEER_CHAT;
2706
2707                 tgl_peer_t* UC = tgl_peer_get(tgl_engine_get_TLS(), peer_id);
2708                 struct tgl_chat *chat_info = &(UC->chat);
2709                 tgl_do_set_chat_photo(tgl_engine_get_TLS(), chat_info->id, (char*)file_path, on_new_group_icon_loaded, chat_info);
2710         }
2711 }
2712
2713 void on_set_username_response_received(struct tgl_state *TLS, void *callback_extra, int success, struct tgl_user *buddy)
2714 {
2715         tg_engine_data_s *tg_data = TLS->callback_data;
2716         char *org_username = callback_extra;
2717         if (success) {
2718                 // update db
2719                 update_buddy_into_db(USER_INFO_TABLE_NAME, buddy);
2720                 update_buddy_into_db(BUDDY_INFO_TABLE_NAME, buddy);
2721                 send_self_user_name_updated_response(tg_data, org_username, EINA_TRUE);
2722         } else {
2723                 send_self_user_name_updated_response(tg_data, org_username, EINA_FALSE);
2724         }
2725         if (org_username) {
2726                 free(org_username);
2727         }
2728 }
2729
2730 void set_user_name(tg_engine_data_s *tg_data, int buddy_id, const char *username)
2731 {
2732         if (username) {
2733                 char *org_username = strdup(username);
2734                 tgl_do_set_username(tgl_engine_get_TLS(), username, on_set_username_response_received, org_username);
2735         }
2736 }
2737
2738 void on_profile_name_changed(struct tgl_state *TLS, void *callback_extra, int success, struct tgl_user *buddy)
2739 {
2740         tg_engine_data_s *tg_data = callback_extra;
2741         if (success) {
2742                 // update db
2743                 update_buddy_into_db(USER_INFO_TABLE_NAME, buddy);
2744                 update_buddy_into_db(BUDDY_INFO_TABLE_NAME, buddy);
2745                 send_self_profile_name_updated_response(tg_data, buddy->first_name, buddy->last_name, EINA_TRUE);
2746         } else {
2747                 send_self_profile_name_updated_response(tg_data, "", "", EINA_FALSE);
2748         }
2749 }
2750
2751 void update_user_display_name(tg_engine_data_s *tg_data, int buddy_id, const char *first_name, const char *last_name)
2752 {
2753         if (first_name && last_name) {
2754                 tgl_do_set_profile_name(tgl_engine_get_TLS(),
2755                                 first_name, last_name, on_profile_name_changed, tg_data);
2756         }
2757 }
2758
2759 void create_new_group(tg_engine_data_s *tg_data, Eina_List* buddy_ids, const char *group_name, const char *group_icon)
2760 {
2761         if (!buddy_ids || ! group_name) {
2762                 return;
2763         }
2764         int users_num = eina_list_count(buddy_ids);
2765         static tgl_peer_id_t ids[1024];
2766         static char _group_icon[1024];
2767         int i;
2768         Eina_Bool is_added = EINA_FALSE;
2769         for (i = 0; i < users_num; i++) {
2770                 char *buddy_id_str = (char *)eina_list_nth(buddy_ids, i);
2771                 if(!buddy_id_str)
2772                         continue;
2773                 int buddy_id = atoi(buddy_id_str);
2774                 ids[i].id = buddy_id;
2775                 ids[i].type = TGL_PEER_USER;
2776                 is_added = EINA_TRUE;
2777         }
2778
2779         if(!is_added)
2780                 return;
2781
2782         strncpy(_group_icon, group_icon, sizeof(_group_icon));
2783
2784         tgl_do_create_group_chat_ex(tgl_engine_get_TLS(), users_num, ids, group_name, on_new_group_created, (void *)_group_icon);
2785         tg_data->is_group_creation_requested = EINA_TRUE;
2786
2787         if (tg_data->new_group_icon) {
2788                 free(tg_data->new_group_icon);
2789         }
2790
2791         if (group_icon && strlen(group_icon) > 0) {
2792                 tg_data->new_group_icon = strdup(group_icon);
2793         } else {
2794                 tg_data->new_group_icon = NULL;
2795         }
2796
2797 }
2798
2799 void add_contacts_to_user(tg_engine_data_s *tg_data, int size, Eina_List* contact_list)
2800 {
2801         tg_data->contact_list_to_add = contact_list;
2802         contact_data_s* contact = eina_list_nth(contact_list, 0);
2803         if (contact) {
2804                 char *first_name = contact->first_name;
2805                 char *last_name = contact->last_name;
2806                 char *phone_number = contact->phone_number;
2807
2808                 tg_data->current_index = 0;
2809
2810                 if (!first_name) {
2811                         first_name = contact->display_name;
2812                         if (!first_name) {
2813                                 first_name = "";
2814                         }
2815                 }
2816
2817                 if (!last_name) {
2818                         last_name = "";
2819                 }
2820
2821                 if (first_name && last_name && phone_number) {
2822                         tgl_do_add_contact(tgl_engine_get_TLS(), phone_number, first_name, last_name, 0, on_contact_added, tg_data);
2823                 } else {
2824                         on_contact_added(tgl_engine_get_TLS(), tg_data, 0, 0, NULL);
2825                 }
2826         }
2827 }
2828
2829 void media_download_request(tg_engine_data_s *tg_data, int buddy_id, long long media_id)
2830 {
2831         // get media details by mediaid
2832         struct tgl_media* img_details = get_media_details_from_db(media_id);
2833
2834         if (!img_details) {
2835                 send_media_download_completed_response(tg_data, -1, buddy_id, media_id, NULL, NULL);
2836                 return;
2837         } else {
2838
2839                 if (img_details->media_type == tgl_message_media_none) {
2840
2841                 } else if (img_details->media_type == tgl_message_media_photo) {
2842
2843                         struct tgl_photo* photo_prop = (struct tgl_photo*)malloc(sizeof(struct tgl_photo));
2844                         photo_prop->id = img_details->media_id;
2845                         photo_prop->access_hash = img_details->access_hash;
2846                         photo_prop->user_id = img_details->user_id;
2847                         photo_prop->date = img_details->date;
2848                         photo_prop->caption = img_details->caption;
2849                         photo_prop->geo.latitude = atof(img_details->latitude);
2850                         photo_prop->geo.longitude = atof(img_details->longitude);
2851                         photo_prop->sizes_num = img_details->sizes;
2852
2853                         photo_prop->sizes = talloc(sizeof(struct tgl_photo_size) * photo_prop->sizes_num);
2854                         int i;
2855                         for (i = 0; i < photo_prop->sizes_num; i++) {
2856
2857                                 if (i == 0) {
2858                                         photo_prop->sizes[i].w = img_details->photo_width1;
2859                                         photo_prop->sizes[i].h = img_details->photo_height1;
2860                                         photo_prop->sizes[i].size = img_details->photo_size1;
2861                                         if (img_details->photo_data1) {
2862                                                 photo_prop->sizes[i].data = strdup(img_details->photo_data1);
2863                                         }
2864                                         if (img_details->photo_type1) {
2865                                                 photo_prop->sizes[i].type = strdup(img_details->photo_type1);
2866                                         }
2867                                         photo_prop->sizes[i].loc.dc = img_details->photo_loc_dc1;
2868                                         photo_prop->sizes[i].loc.local_id = img_details->photo_loc_id1;
2869                                         photo_prop->sizes[i].loc.secret = img_details->photo_loc_sec1;
2870                                         photo_prop->sizes[i].loc.volume = img_details->photo_loc_vol1;
2871                                 } else if (i == 1) {
2872
2873                                         photo_prop->sizes[i].w = img_details->photo_width2;
2874                                         photo_prop->sizes[i].h = img_details->photo_height2;
2875                                         photo_prop->sizes[i].size = img_details->photo_size2;
2876                                         if (img_details->photo_data2) {
2877                                                 photo_prop->sizes[i].data = strdup(img_details->photo_data2);
2878                                         }
2879                                         if (img_details->photo_type2) {
2880                                                 photo_prop->sizes[i].type = strdup(img_details->photo_type2);
2881                                         }
2882                                         photo_prop->sizes[i].loc.dc = img_details->photo_loc_dc2;
2883                                         photo_prop->sizes[i].loc.local_id = img_details->photo_loc_id2;
2884                                         photo_prop->sizes[i].loc.secret = img_details->photo_loc_sec2;
2885                                         photo_prop->sizes[i].loc.volume = img_details->photo_loc_vol2;
2886
2887                                 } else if (i == 2) {
2888
2889                                         photo_prop->sizes[i].w = img_details->photo_width3;
2890                                         photo_prop->sizes[i].h = img_details->photo_height3;
2891                                         photo_prop->sizes[i].size = img_details->photo_size3;
2892                                         if (img_details->photo_data3) {
2893                                                 photo_prop->sizes[i].data = strdup(img_details->photo_data3);
2894                                         }
2895                                         if (img_details->photo_type3) {
2896                                                 photo_prop->sizes[i].type = strdup(img_details->photo_type3);
2897                                         }
2898                                         photo_prop->sizes[i].loc.dc = img_details->photo_loc_dc3;
2899                                         photo_prop->sizes[i].loc.local_id = img_details->photo_loc_id3;
2900                                         photo_prop->sizes[i].loc.secret = img_details->photo_loc_sec3;
2901                                         photo_prop->sizes[i].loc.volume = img_details->photo_loc_vol3;
2902
2903                                 } else if (i == 3) {
2904
2905                                         photo_prop->sizes[i].w = img_details->photo_width4;
2906                                         photo_prop->sizes[i].h = img_details->photo_height4;
2907                                         photo_prop->sizes[i].size = img_details->photo_size4;
2908                                         if (img_details->photo_data4) {
2909                                                 photo_prop->sizes[i].data = strdup(img_details->photo_data4);
2910                                         }
2911                                         if (img_details->photo_type4) {
2912                                                 photo_prop->sizes[i].type = strdup(img_details->photo_type4);
2913                                         }
2914                                         photo_prop->sizes[i].loc.dc = img_details->photo_loc_dc4;
2915                                         photo_prop->sizes[i].loc.local_id = img_details->photo_loc_id4;
2916                                         photo_prop->sizes[i].loc.secret = img_details->photo_loc_sec4;
2917                                         photo_prop->sizes[i].loc.volume = img_details->photo_loc_vol4;
2918
2919                                 } else {
2920
2921                                 }
2922                         }
2923
2924                         photo_prop->to_peer_id = buddy_id;
2925                         tgl_do_load_photo(s_info.TLS, photo_prop, &on_image_download_completed, photo_prop);
2926
2927                 } else if (img_details->media_type == tgl_message_media_document) {
2928                         struct tgl_document* doc_prop = (struct tgl_document*)malloc(sizeof(struct tgl_document));
2929                         doc_prop->id = img_details->media_id;;
2930                         doc_prop->access_hash = img_details->access_hash;
2931                         doc_prop->user_id = img_details->user_id;
2932                         doc_prop->date = img_details->date;
2933                         doc_prop->size = img_details->sizes;
2934                         doc_prop->mime_type = NULL;
2935                         doc_prop->dc_id = img_details->doc_dc;
2936                         doc_prop->to_peer_id = buddy_id;
2937
2938                         if (img_details->caption) {
2939                                 doc_prop->caption = strdup(img_details->caption);
2940                         } else {
2941                                 doc_prop->caption = NULL;
2942                         }
2943
2944
2945                         if (!(img_details->mime_type) || strlen(img_details->mime_type) <= 0) {
2946
2947                                 if (img_details->doc_type && strlen(img_details->doc_type) > 0) {
2948                                         if (img_details->doc_type && strstr(img_details->doc_type, "video") != NULL) {
2949                                                 doc_prop->mime_type = strdup("video/mp4");
2950                                         } else if (img_details->doc_type && strstr(img_details->doc_type, "audio") != NULL) {
2951                                                 doc_prop->mime_type = strdup("audio/wav");
2952                                         } else if (img_details->doc_type && strstr(img_details->doc_type, "image/gif") != NULL) {
2953                                                 doc_prop->mime_type = strdup("image/gif");
2954                                         }
2955                                 }
2956                         } else {
2957                                 doc_prop->mime_type = img_details->mime_type;
2958                         }
2959
2960                         if (img_details->doc_type && strstr(img_details->doc_type, "video") != NULL) {
2961                                 doc_prop->flags =  FLAG_DOCUMENT_VIDEO;
2962                         } else if (img_details->doc_type && strstr(img_details->doc_type, "audio") != NULL) {
2963                                 doc_prop->flags =  FLAG_DOCUMENT_AUDIO;
2964                         } else if (img_details->doc_type && strstr(img_details->doc_type, "image") != NULL) {
2965                                 doc_prop->flags =  FLAG_DOCUMENT_ANIMATED;
2966                         }
2967
2968                         tgl_do_load_document(s_info.TLS, doc_prop, on_document_download_completed, doc_prop);
2969
2970
2971                 } else {
2972
2973                 }
2974
2975                 // delete image details
2976
2977                 if (img_details->caption) {
2978                         free(img_details->caption);
2979                 }
2980                 if (img_details->longitude) {
2981                         free(img_details->longitude);
2982                 }
2983                 if (img_details->latitude) {
2984                         free(img_details->latitude);
2985                 }
2986                 if (img_details->phone_no) {
2987                         free(img_details->phone_no);
2988                 }
2989                 if (img_details->first_name) {
2990                         free(img_details->first_name);
2991                 }
2992                 if (img_details->last_name) {
2993                         free(img_details->last_name);
2994                 }
2995                 if (img_details->file_path) {
2996                         free(img_details->file_path);
2997                 }
2998                 if (img_details->photo_type1) {
2999                         free(img_details->photo_type1);
3000                 }
3001                 if (img_details->photo_data1) {
3002                         free(img_details->photo_data1);
3003                 }
3004                 if (img_details->photo_type2) {
3005                         free(img_details->photo_type2);
3006                 }
3007                 if (img_details->photo_data2) {
3008                         free(img_details->photo_data2);
3009                 }
3010                 if (img_details->photo_type3) {
3011                         free(img_details->photo_type3);
3012                 }
3013                 if (img_details->photo_data3) {
3014                         free(img_details->photo_data3);
3015                 }
3016                 if (img_details->photo_type4) {
3017                         free(img_details->photo_type4);
3018                 }
3019                 if (img_details->photo_data4) {
3020                         free(img_details->photo_data4);
3021                 }
3022                 if (img_details->mime_type) {
3023                         free(img_details->mime_type);
3024                 }
3025                 if (img_details->doc_type) {
3026                         free(img_details->doc_type);
3027                 }
3028                 if (img_details->doc_thumb_path) {
3029                         free(img_details->doc_thumb_path);
3030                 }
3031
3032         }
3033 }
3034
3035 void on_mark_read_callback(struct tgl_state *TLS, void *callback_extra, int success)
3036 {
3037         // message read sent successfully. update to UI if needed.
3038 }
3039
3040
3041 void on_message_deleted_from_message_list(struct tgl_state *TLS, void *callback_extra, int success)
3042 {
3043         msg_list_container_s *msg_list_container = (msg_list_container_s*)callback_extra;
3044         /* tg_engine_data_s *tg_data = TLS->callback_data; */
3045
3046         if (success && msg_list_container) {
3047                 // delete message from message table
3048                 char* tb_name = get_table_name_from_number(msg_list_container->buddy_id);
3049                 delete_message_from_table(tb_name, msg_list_container->current_message_id);
3050                 free(tb_name);
3051         }
3052
3053         if (msg_list_container && msg_list_container->message_ids) {
3054                 if (msg_list_container->current_index < eina_list_count(msg_list_container->message_ids)) {
3055                         msg_list_container->current_index = msg_list_container->current_index + 1;
3056                         msg_list_container->current_message_id = (int)eina_list_nth(msg_list_container->message_ids, msg_list_container->current_index);
3057                         tgl_do_delete_msg(s_info.TLS, msg_list_container->current_message_id, &on_message_deleted_from_message_list , (void*)(msg_list_container));
3058                 } else {
3059                         eina_list_free(msg_list_container->message_ids);
3060                         free(msg_list_container);
3061                 }
3062         }
3063 }
3064
3065 void delete_all_messages_from_chat(int buddy_id, int type_of_chat)
3066 {
3067         tgl_peer_id_t chat_id;
3068         chat_id.id = buddy_id;
3069         chat_id.type = type_of_chat;
3070
3071         char* tb_name = get_table_name_from_number(buddy_id);
3072         //get all message ids from table.
3073         Eina_List *msg_ids = get_all_message_ids_from_table(tb_name);
3074         free(tb_name);
3075
3076         if (msg_ids && eina_list_count(msg_ids) > 0) {
3077                 msg_list_container_s *msg_list_container = (msg_list_container_s*)malloc(sizeof(msg_list_container_s));
3078                 msg_list_container->message_ids = msg_ids;
3079                 msg_list_container->buddy_id = buddy_id;
3080                 msg_list_container->current_index = 0;
3081                 msg_list_container->current_message_id = (int)eina_list_nth(msg_list_container->message_ids, msg_list_container->current_index);
3082
3083                 tgl_do_delete_msg(s_info.TLS, msg_list_container->current_message_id, &on_message_deleted_from_message_list , (void*)(msg_list_container));
3084         }
3085
3086 }
3087
3088
3089 void send_do_mark_read_messages(int buddy_id, int type_of_chat)
3090 {
3091         tgl_peer_id_t chat_id;
3092         chat_id.id = buddy_id;
3093         chat_id.type = type_of_chat;
3094
3095         tgl_do_mark_read(s_info.TLS, chat_id, &on_mark_read_callback , (void*)(&chat_id));
3096 }
3097
3098
3099 void on_user_block_response(struct tgl_state *TLS, void *callback_extra, int success)
3100 {
3101         int buddy_id = (int)callback_extra;
3102         tg_engine_data_s *tg_data = TLS->callback_data;
3103         if (success) {
3104                 // update database
3105                 int blocked = 1;
3106                 update_buddy_block_db(BUDDY_INFO_TABLE_NAME, buddy_id, blocked);
3107                 send_buddy_blocked_response(tg_data, buddy_id, EINA_TRUE);
3108         } else {
3109                 send_buddy_blocked_response(tg_data, buddy_id, EINA_FALSE);
3110         }
3111 }
3112
3113 void on_user_unblock_response(struct tgl_state *TLS, void *callback_extra, int success)
3114 {
3115         int buddy_id = (int)callback_extra;
3116         tg_engine_data_s *tg_data = TLS->callback_data;
3117         if (success) {
3118                 int blocked = 0;
3119                 update_buddy_block_db(BUDDY_INFO_TABLE_NAME, buddy_id, blocked);
3120                 send_buddy_unblocked_response(tg_data, buddy_id, EINA_TRUE);
3121         } else {
3122                 send_buddy_unblocked_response(tg_data, buddy_id, EINA_FALSE);
3123         }
3124 }
3125
3126 void on_user_delete_response(struct tgl_state *TLS, void *callback_extra, int success)
3127 {
3128         int buddy_id = (int)callback_extra;
3129         tg_engine_data_s *tg_data = TLS->callback_data;
3130         if (success) {
3131                 // update database
3132                 // delete from peer table
3133                 // delete from buddy table
3134                 // delete chat items
3135 #if 0
3136                 //delete_chat_from_db(buddy_id);
3137                 //delete_buddy_from_db(buddy_id);
3138                 //char* msg_table = get_table_name_from_number(buddy_id);
3139                 //drop_table(msg_table);
3140                 //free(msg_table);
3141 #endif
3142                 int deleted = 1;
3143                 update_buddy_delete_db(BUDDY_INFO_TABLE_NAME, buddy_id, deleted);
3144                 update_buddy_delete_db(PEER_INFO_TABLE_NAME, buddy_id, deleted);
3145                 send_buddy_deleted_response(tg_data, buddy_id, EINA_TRUE);
3146         } else {
3147                 send_buddy_deleted_response(tg_data, buddy_id, EINA_FALSE);
3148         }
3149 }
3150
3151
3152 void on_buddy_readded(struct tgl_state *TLS, void *callback_extra, int success, int size, struct tgl_user *users[])
3153 {
3154         int buddy_id = (int)callback_extra;
3155         tg_engine_data_s *tg_data = TLS->callback_data;
3156         if (success) {
3157                 int deleted = 0;
3158                 update_buddy_delete_db(BUDDY_INFO_TABLE_NAME, buddy_id, deleted);
3159                 send_buddy_readded_response(tg_data, buddy_id, EINA_TRUE);
3160         } else {
3161                 send_buddy_readded_response(tg_data, buddy_id, EINA_FALSE);
3162         }
3163 }
3164
3165 void on_new_buddy_added(struct tgl_state *TLS, void *callback_extra, int success, int size, struct tgl_user *users[])
3166 {
3167         tg_engine_data_s *tg_data = TLS->callback_data;
3168         if (success && size > 0) {
3169                 struct tgl_user *buddy = users[0];
3170                 if (buddy) {
3171                         char* msg_table = get_table_name_from_number(buddy->id.id);
3172                         create_buddy_msg_table(msg_table);
3173                         free(msg_table);
3174                         buddy->is_unknown = 0;
3175                         init_insert_buddy_into_db(BUDDY_INFO_TABLE_NAME, buddy);
3176                         tgl_peer_t* UC = tgl_peer_get(TLS, buddy->id);
3177                         if (UC) {
3178                                 insert_peer_into_database(UC, 0, 0, 0);
3179                         }
3180                         tgl_do_get_user_info(TLS, buddy->id, 0, on_buddy_info_loaded, NULL);
3181
3182                         // send response to application
3183                         send_new_contact_added_response(tg_data, buddy->id.id, EINA_TRUE);
3184                 } else {
3185                         send_new_contact_added_response(tg_data, -1, EINA_FALSE);
3186                 }
3187
3188         } else {
3189                 send_new_contact_added_response(tg_data, -1, EINA_FALSE);
3190         }
3191 }
3192
3193 void do_add_buddy(int buddy_id, char *first_name, char *last_name, char *phone_num)
3194 {
3195         if (!first_name) {
3196                 first_name = "";
3197         }
3198         if (!last_name) {
3199                 last_name = "";
3200         }
3201         if (!phone_num) {
3202                 phone_num = "";
3203         }
3204
3205         if (first_name && last_name && phone_num) {
3206                 if (buddy_id == -1) {
3207                         tgl_do_add_contact(s_info.TLS, phone_num, first_name, last_name, 0, on_new_buddy_added, (void*)(buddy_id));
3208                 } else {
3209                         tgl_do_add_contact(s_info.TLS, phone_num, first_name, last_name, 0, on_buddy_readded, (void*)(buddy_id));
3210                 }
3211         }
3212 }
3213
3214
3215 void logout_telegram(tg_engine_data_s *tg_data)
3216 {
3217
3218 }
3219
3220 void on_secret_chat_request_sent(struct tgl_state *TLS, void *callback_extra, int success, struct tgl_secret_chat *E)
3221 {
3222         /*
3223         int buddy_id = (int)callback_extra;
3224         tg_engine_data_s *tg_data = TLS->callback_data;
3225         */
3226         if (success) {
3227
3228         } else {
3229
3230         }
3231 }
3232
3233 void request_for_secret_chat(int buddy_id)
3234 {
3235         tgl_peer_id_t peer_id;
3236         peer_id.id = buddy_id;
3237         peer_id.type = TGL_PEER_USER;
3238         tgl_do_create_secret_chat(s_info.TLS, peer_id, on_secret_chat_request_sent, (void*)(buddy_id));
3239 }
3240
3241 void do_delete_buddy(int buddy_id)
3242 {
3243         tgl_peer_id_t peer_id;
3244         peer_id.id = buddy_id;
3245         peer_id.type = TGL_PEER_USER;
3246         tgl_do_del_contact(s_info.TLS, peer_id, &on_user_delete_response , (void*)(buddy_id));
3247 }
3248
3249 void on_message_deleted(struct tgl_state *TLS, void *callback_extra, int success)
3250 {
3251         msg_container_s *msg_details = (msg_container_s*)callback_extra;
3252         tg_engine_data_s *tg_data = TLS->callback_data;
3253         if (success) {
3254                 // update database
3255                 send_message_deleted_response(tg_data, msg_details->buddy_id, msg_details->message_id, EINA_TRUE);
3256         } else {
3257                 send_message_deleted_response(tg_data, msg_details->buddy_id, msg_details->message_id, EINA_FALSE);
3258         }
3259 }
3260
3261 void do_delete_message(int buddy_id, int message_id)
3262 {
3263         msg_container_s *msg_details = (msg_container_s*)malloc(sizeof(msg_container_s));
3264         msg_details->buddy_id = buddy_id;
3265         msg_details->message_id = message_id;
3266         tgl_do_delete_msg(s_info.TLS, message_id, &on_message_deleted , (void*)(msg_details));
3267 }
3268
3269
3270 void do_block_buddy(int buddy_id)
3271 {
3272         tgl_peer_id_t peer_id;
3273         peer_id.id = buddy_id;
3274         peer_id.type = TGL_PEER_USER;
3275         tgl_do_block_user(s_info.TLS, peer_id, &on_user_block_response , (void*)(buddy_id));
3276 }
3277
3278 void do_unblock_buddy(int buddy_id)
3279 {
3280         tgl_peer_id_t peer_id;
3281         peer_id.id = buddy_id;
3282         peer_id.type = TGL_PEER_USER;
3283         tgl_do_unblock_user(s_info.TLS, peer_id, &on_user_unblock_response , (void*)(buddy_id));
3284 }
3285
3286 extern void on_selected_group_chats_delete_reponse(struct tgl_state *TLS, void *callback_extra, int success, struct tgl_message *M);
3287 static Eina_Bool on_async_chat_deletion_requested(void *data)
3288 {
3289         Eina_List *sel_grp_chats = data;
3290         if (sel_grp_chats) {
3291                 tg_engine_data_s *tg_data = tgl_engine_get_TLS()->callback_data;
3292                 tg_data->current_group_chat_index = tg_data->current_group_chat_index + 1;
3293
3294                 if (tg_data->current_group_chat_index < eina_list_count(sel_grp_chats)) {
3295                         int group_chat_id = (int)eina_list_nth(sel_grp_chats, tg_data->current_group_chat_index);
3296
3297                         tgl_peer_id_t chat_id;
3298                         chat_id.id = group_chat_id;
3299                         chat_id.type = TGL_PEER_CHAT;
3300
3301                         tgl_peer_id_t self_id = tg_data->id;
3302
3303                         tgl_do_del_user_from_chat(s_info.TLS, chat_id, self_id, on_selected_group_chats_delete_reponse, (void*)(sel_grp_chats));
3304                 } else {
3305                         send_selected_group_chats_deleted_response(tg_data);
3306                 }
3307         }
3308         return ECORE_CALLBACK_CANCEL;
3309 }
3310
3311
3312 void on_selected_group_chats_delete_reponse(struct tgl_state *TLS, void *callback_extra, int success, struct tgl_message *M)
3313 {
3314         Eina_List *sel_grp_chats = callback_extra;
3315         tg_engine_data_s *tg_data = TLS->callback_data;
3316         int chat_id = (int)eina_list_nth(sel_grp_chats, tg_data->current_group_chat_index);
3317
3318         if (success) {
3319                 delete_chat_from_db(chat_id);
3320                 char* msg_table = get_table_name_from_number(chat_id);
3321                 drop_table(msg_table);
3322                 free(msg_table);
3323         }
3324         ecore_timer_add(1, on_async_chat_deletion_requested, sel_grp_chats);
3325 }
3326
3327 void delete_selected_group_chat(tg_engine_data_s *tg_data, Eina_List *sel_grp_chats)
3328 {
3329         if (sel_grp_chats && eina_list_count(sel_grp_chats) > 0) {
3330
3331                 tg_data->current_group_chat_index = 0;
3332                 int group_chat_id = (int)eina_list_nth(sel_grp_chats, tg_data->current_group_chat_index);
3333
3334                 tgl_peer_id_t chat_id;
3335                 chat_id.id = group_chat_id;
3336                 chat_id.type = TGL_PEER_CHAT;
3337
3338                 tgl_peer_id_t self_id = tg_data->id;
3339
3340                 tgl_do_del_user_from_chat(s_info.TLS, chat_id, self_id, on_selected_group_chats_delete_reponse, (void*)(sel_grp_chats));
3341         }
3342 }
3343
3344 void on_group_chat_delete_reponse(struct tgl_state *TLS, void *callback_extra, int success, struct tgl_message *M)
3345 {
3346         int chat_id = (int)callback_extra;
3347         tg_engine_data_s *tg_data = TLS->callback_data;
3348         if (success) {
3349                 // update database
3350                 // delete from peer table
3351                 delete_chat_from_db(chat_id);
3352                 char* msg_table = get_table_name_from_number(chat_id);
3353                 drop_table(msg_table);
3354                 free(msg_table);
3355                 send_group_chat_deleted_response(tg_data, chat_id, EINA_TRUE);
3356         } else {
3357                 send_group_chat_deleted_response(tg_data, chat_id, EINA_FALSE);
3358         }
3359 }
3360
3361 void leave_group_chat(tg_engine_data_s *tg_data, int group_chat_id)
3362 {
3363         tgl_peer_id_t chat_id;
3364         chat_id.id = group_chat_id;
3365         chat_id.type = TGL_PEER_CHAT;
3366
3367         tgl_peer_id_t self_id = tg_data->id;
3368
3369         tgl_do_del_user_from_chat(s_info.TLS, chat_id, self_id, on_group_chat_delete_reponse, (void*)(group_chat_id));
3370 }
3371
3372 #if 0
3373 void on_new_msg_requested_chat_info_received(struct tgl_state *TLS, void *callback_extra, int success, struct tgl_chat *chat_info)
3374 {
3375         tg_engine_data_s *tg_data;
3376
3377         struct tgl_message *msg = callback_extra;
3378
3379         char *msg_table;
3380
3381         if (!chat_info) {
3382                 return;
3383         }
3384         if (!chat_info->user_list) {
3385                 tgl_do_get_chat_info(TLS, chat_info->id, 0, &on_requested_chat_info_received, callback_extra);
3386                 return;
3387         }
3388
3389         tg_data = TLS->callback_data;
3390
3391         msg_table = get_table_name_from_number(chat_info->id.id);
3392
3393         create_buddy_msg_table(msg_table);
3394
3395         insert_chat_info_to_db(chat_info, NULL);
3396         struct tgl_photo *pic = &(chat_info->photo);
3397         if (pic) {
3398                 tgl_do_load_photo(TLS, pic, &on_chat_pic_loaded, chat_info);
3399         }
3400
3401         tgl_do_send_message(s_info.TLS, msg->to_id, msg->message, strlen(msg->message), &on_message_sent_to_buddy, (void*)(msg));
3402
3403         char *type_of_change = strdup("add_user");
3404         tgl_do_get_chat_info(s_info.TLS, msg->to_id, 0, &on_group_chat_info_updated, type_of_change);
3405
3406         free(msg_table);
3407 }
3408 #endif
3409
3410 void forward_message_to_buddy(int to_id, int type_of_chat, int from_id, int message_id, int temp_message_id)
3411 {
3412         char *msg_table = get_table_name_from_number(from_id);
3413         struct tgl_message* msg = get_message_from_message_table(temp_message_id, msg_table);
3414
3415         if (msg) {
3416                 tgl_peer_id_t id_to_send;
3417                 id_to_send.id = type_of_chat;
3418                 tgl_do_forward_message(s_info.TLS, id_to_send, message_id, &on_message_sent_to_buddy, (void*)(msg));
3419         }
3420         free(msg_table);
3421 }
3422
3423 void send_typing_status_to_buddy(int buddy_id, int type_of_chat, int typing_status)
3424 {
3425         tgl_peer_id_t id_to_send;
3426         id_to_send.id = type_of_chat;
3427         tgl_do_send_typing(s_info.TLS, id_to_send, typing_status, NULL, NULL);
3428 }
3429
3430 void send_message_to_buddy(int buddy_id, int message_id, int msg_type, char *msg_data, int type_of_chat)
3431 {
3432         // get type of chat from buddy_id.
3433         char *msg_table = get_table_name_from_number(buddy_id);
3434         struct tgl_message* msg = get_message_from_message_table(message_id, msg_table);
3435
3436         if (msg) {
3437                 if (type_of_chat == TGL_PEER_USER) {
3438                         msg->from_id.type = TGL_PEER_USER;
3439                         msg->to_id.type = TGL_PEER_USER;
3440                         tgl_do_send_message(s_info.TLS, msg->to_id, msg->message, strlen(msg->message), &on_message_sent_to_buddy, (void*)(msg));
3441                 } else if (type_of_chat == TGL_PEER_CHAT) {
3442                         msg->from_id.type = TGL_PEER_CHAT;
3443                         msg->to_id.type = TGL_PEER_CHAT;
3444 #if 0
3445                         Eina_Bool is_present_in_chat_db = is_user_present_chat_table(msg->to_id.id);
3446                         if (!is_present_in_chat_db) {
3447                                 //sandeep
3448                                 tgl_do_get_chat_info(s_info.TLS, msg->to_id, 0, &on_new_msg_requested_chat_info_received, msg);
3449                                 return;
3450                         }
3451 #endif
3452                         tgl_do_send_message(s_info.TLS, msg->to_id, msg->message, strlen(msg->message), &on_message_sent_to_buddy, (void*)(msg));
3453                 } else if (type_of_chat == TGL_PEER_ENCR_CHAT) {
3454
3455                 } else {
3456
3457                 }
3458         }
3459         free(msg_table);
3460 }
3461
3462 void send_media_to_buddy(int buddy_id, int message_id, int media_id, int msg_type, char *file_path, int type_of_chat)
3463 {
3464         char *msg_table = get_table_name_from_number(buddy_id);
3465         struct tgl_message* msg = get_message_from_message_table(message_id, msg_table);
3466
3467         if (msg) {
3468                 if (type_of_chat == TGL_PEER_USER) {
3469
3470                         msg->from_id.type = TGL_PEER_USER;
3471                         msg->to_id.type = TGL_PEER_USER;
3472
3473                         if (msg->media.type == tgl_message_media_photo) {
3474                                 tgl_do_send_document(s_info.TLS, -1, msg->to_id, file_path, &on_message_sent_to_buddy, (void*) (msg));
3475                         } else if (msg->media.type == tgl_message_media_document) {
3476                                 char *extn = strrchr(file_path, '.');
3477                                 if (extn) {
3478                                         extn = replace(extn, '.', "");
3479                                 }
3480                                 char *mime_type = NULL;;
3481                                 if (extn) {
3482                                         mime_type_get_mime_type(extn, &mime_type);
3483                                 }
3484
3485                                 if (mime_type && strstr(mime_type, "video") != NULL) {
3486
3487                                         char* thumb_path = get_video_thumb_path_from_db(media_id);
3488                                         tgl_do_send_video(s_info.TLS, -2, msg->to_id, file_path, thumb_path, &on_message_sent_to_buddy, (void*) (msg));
3489                                         if (thumb_path) {
3490                                                 free(thumb_path);
3491                                                 thumb_path = NULL;
3492                                         }
3493                                 } else if (mime_type && strstr(mime_type, "audio") != NULL) {
3494                                         tgl_do_send_audio(s_info.TLS, msg->to_id, file_path, &on_message_sent_to_buddy, (void*) (msg));
3495                                 } else {
3496
3497                                 }
3498                         } else if (msg->media.type == tgl_message_media_geo) {
3499                                 char *latitude = NULL;
3500                                 char *longitude = NULL;
3501                                 get_geo_location_from_db(media_id, &latitude, &longitude);
3502                                 if (latitude && longitude) {
3503                                         tgl_do_send_location(s_info.TLS, msg->to_id, strtod(latitude, NULL), strtod(longitude, NULL), &on_message_sent_to_buddy, (void*) (msg));
3504                                 }
3505                         } else if (msg->media.type == tgl_message_media_contact) {
3506                                 char *first_name = NULL;
3507                                 char *last_name = NULL;
3508                                 char *phone_num = NULL;
3509                                 get_contact_details_from_db(media_id, &first_name, &last_name, &phone_num);
3510                                 if (first_name && last_name && phone_num) {
3511                                         tgl_do_send_contact(s_info.TLS, msg->to_id, first_name, strlen(first_name), last_name, strlen(last_name), phone_num, strlen(phone_num), &on_message_sent_to_buddy, (void*) (msg));
3512                                 }
3513                         }
3514
3515                 } else if (type_of_chat == TGL_PEER_CHAT) {
3516                         msg->from_id.type = TGL_PEER_CHAT;
3517                         msg->to_id.type = TGL_PEER_CHAT;
3518
3519                         if (msg->media.type == tgl_message_media_photo) {
3520                                 tgl_do_send_document(s_info.TLS, -1, msg->to_id, file_path, &on_message_sent_to_buddy, (void*) (msg));
3521                         } else if (msg->media.type == tgl_message_media_document) {
3522
3523
3524                                 char *extn = strrchr(file_path, '.');
3525                                 if (extn) {
3526                                         extn = replace(extn, '.', "");
3527                                 }
3528                                 char *mime_type = NULL;;
3529                                 if (extn) {
3530                                         mime_type_get_mime_type(extn, &mime_type);
3531                                 }
3532
3533                                 if (mime_type && strstr(mime_type, "video") != NULL) {
3534
3535                                         char* thumb_path = get_video_thumb_path_from_db(media_id);
3536                                         tgl_do_send_video(s_info.TLS, -2, msg->to_id, file_path, thumb_path, &on_message_sent_to_buddy, (void*) (msg));
3537                                         if (thumb_path) {
3538                                                 free(thumb_path);
3539                                                 thumb_path = NULL;
3540                                         }
3541                                 } else if (mime_type && strstr(mime_type, "audio") != NULL) {
3542                                         tgl_do_send_audio(s_info.TLS, msg->to_id, file_path, &on_message_sent_to_buddy, (void*) (msg));
3543                                 } else {
3544
3545                                 }
3546                         } else if (msg->media.type == tgl_message_media_geo) {
3547                                 char *latitude = NULL;
3548                                 char *longitude = NULL;
3549                                 get_geo_location_from_db(media_id, &latitude, &longitude);
3550                                 if (latitude && longitude) {
3551                                         tgl_do_send_location(s_info.TLS, msg->to_id, strtod(latitude, NULL), strtod(longitude, NULL), &on_message_sent_to_buddy, (void*) (msg));
3552                                 }
3553                         }
3554
3555
3556                 } else if (type_of_chat == TGL_PEER_ENCR_CHAT) {
3557
3558                 } else {
3559
3560                 }
3561
3562         }
3563         free(msg_table);
3564
3565 }
3566
3567 void check_type_sizes(void)
3568 {
3569         if (sizeof(int) != 4u) {
3570                 logprintf("sizeof(int) isn't equal 4.\n");
3571                 exit(1);
3572         }
3573         if (sizeof(char) != 1u) {
3574                 logprintf("sizeof(char) isn't equal 1.\n");
3575                 exit(1);
3576         }
3577 }
3578
3579 int str_empty(char *str)
3580 {
3581         return ((str == NULL) || (strlen(str) < 1));
3582 }
3583
3584 void parse_config(void)
3585 {
3586         if (!s_info.disable_output) {
3587                 //printf("libconfig not enabled\n");
3588         }
3589
3590         char *rsa_path = ui_utils_get_resource(DEFAULT_RSA_FILE_NAME);
3591         tasprintf(&s_info.rsa_file_name, "%s", rsa_path);
3592         tasprintf(&s_info.config_full_path, "%s%s", app_get_data_path(), CONFIG_DIRECTORY);
3593         struct stat st = { 0 };
3594         if (stat(s_info.config_full_path, &st) == -1) {
3595                 mkdir(s_info.config_full_path, S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH);
3596         }
3597
3598         if (remove(s_info.rsa_file_name) == 0) {
3599                 //printf("File successfully deleted\n");
3600         }
3601
3602         //tasprintf(&s_info.downloads_directory, "%s%s/%s", app_get_data_path(), CONFIG_DIRECTORY, DOWNLOADS_DIRECTORY);
3603         tasprintf(&s_info.downloads_directory, "%s/%s", app_get_shared_data_path(), DOWNLOADS_DIRECTORY);
3604
3605         if (s_info.binlog_enabled) {
3606                 tasprintf(&s_info.binlog_file_name, "%s%s/%s", app_get_data_path(), CONFIG_DIRECTORY, BINLOG_FILE);
3607                 tgl_set_binlog_mode(s_info.TLS, 1);
3608                 tgl_set_binlog_path(s_info.TLS, s_info.binlog_file_name);
3609         } else {
3610                 tgl_set_binlog_mode(s_info.TLS, 0);
3611                 //tgl_set_auth_file_path(auth_file_name;
3612                 tasprintf(&s_info.auth_file_name, "%s%s/%s", app_get_data_path(), CONFIG_DIRECTORY, AUTH_KEY_FILE);
3613                 tasprintf(&s_info.state_file_name, "%s%s/%s", app_get_data_path(), CONFIG_DIRECTORY, STATE_FILE);
3614                 tasprintf(&s_info.secret_chat_file_name, "%s%s/%s", app_get_data_path(), CONFIG_DIRECTORY, SECRET_CHAT_FILE);
3615         }
3616         tgl_set_download_directory(s_info.TLS, s_info.downloads_directory);
3617         if (!mkdir(s_info.downloads_directory, CONFIG_DIRECTORY_MODE)) {
3618                 if (!s_info.disable_output) {
3619                         //printf("[%s] created\n", downloads_directory);
3620                 }
3621         }
3622 }
3623
3624 void running_for_first_time(void)
3625 {
3626         check_type_sizes();
3627         if (!str_empty(s_info.config_filename)) {
3628                 return; // Do not create custom config file
3629         }
3630
3631         if (str_empty(s_info.config_directory)) {
3632                 s_info.config_directory = strdup(app_get_data_path()); // specific path for tizen application.
3633         }
3634
3635         struct stat st = {0};
3636         if (stat(s_info.config_directory, &st) == -1) {
3637                 mkdir(s_info.config_directory, S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH);
3638         }
3639
3640         tasprintf(&s_info.config_filename, "%s%s", s_info.config_directory, CONFIG_FILE);
3641
3642         int config_file_fd;
3643         // see if config file is there
3644         if (access(s_info.config_filename, R_OK) != 0) {
3645                 // config file missing, so touch it
3646                 config_file_fd = open(s_info.config_filename, O_CREAT | O_RDWR, 0600);
3647                 if (config_file_fd == -1)  {
3648                         perror("open[config_file]");
3649                         //printf("I: config_file=[%s]\n", config_filename);
3650                         exit(EXIT_FAILURE);
3651                 }
3652                 if (write(config_file_fd, DEFAULT_CONFIG_CONTENTS, strlen(DEFAULT_CONFIG_CONTENTS)) <= 0) {
3653                         perror("write[config_file]");
3654                         exit(EXIT_FAILURE);
3655                 }
3656                 close(config_file_fd);
3657         }
3658 }
3659
3660 void init_tl_engine(void *cbdata)
3661 {
3662         s_info.TLS = tgl_state_alloc();
3663         if (!s_info.TLS) {
3664                 ERR("memory allocation failed!! for tgl_state_alloc");
3665                 return;
3666         }
3667
3668         running_for_first_time();
3669
3670         parse_config();
3671
3672         tgl_set_rsa_key(s_info.TLS, s_info.rsa_file_name);
3673         tgl_set_callback(s_info.TLS, &upd_cb, cbdata);
3674         tgl_set_verbosity(s_info.TLS, E_DEBUG);
3675         tgl_set_net_methods(s_info.TLS, &tgl_conn_methods);
3676         tgl_set_timer_methods(s_info.TLS, &tgl_libevent_timers);
3677         assert(s_info.TLS->timer_methods);
3678         tgl_set_download_directory(s_info.TLS, tgl_engine_get_downloads_directory());
3679         tgl_register_app_id(s_info.TLS, TELEGRAM_CLI_APP_ID, TELEGRAM_CLI_APP_HASH);
3680         tgl_set_app_version(s_info.TLS, "Telegram-cli " TELEGRAM_CLI_VERSION);
3681         if (s_info.ipv6_enabled) {
3682                 tgl_enable_ipv6(s_info.TLS);
3683         }
3684         tgl_init(s_info.TLS);
3685
3686         if (s_info.binlog_enabled) {
3687                 double t = tglt_get_double_time();
3688                 if (s_info.verbosity >= E_DEBUG) {
3689                         logprintf("replay log start\n");
3690                 }
3691                 tgl_replay_log(s_info.TLS);
3692                 if (s_info.verbosity >= E_DEBUG) {
3693                         logprintf("replay log end in %lf seconds\n", tglt_get_double_time() - t);
3694                 }
3695                 tgl_reopen_binlog_for_writing(s_info.TLS);
3696         } else {
3697                 read_auth_file();
3698                 read_state_file();
3699                 read_secret_chat_file();
3700         }
3701 }
3702
3703 void tgl_engine_destroy_TLS(void)
3704 {
3705         if (!s_info.TLS) {
3706                 return;
3707         }
3708
3709         tgl_state_free(tgl_engine_get_TLS());
3710         s_info.TLS = NULL;
3711 }
3712
3713 struct tgl_state *tgl_engine_get_TLS(void)
3714 {
3715         return s_info.TLS;
3716 }