8d068847b4a561950e1a39c3c588941c9939cd25
[apps/home/gallery.git] / src / util / gl-db-handler.c
1 /*
2   * Copyright 2012  Samsung Electronics Co., Ltd
3   *
4   * Licensed under the Flora License, Version 1.0 (the "License");
5   * you may not use this file except in compliance with the License.
6   * You may obtain a copy of the License at
7   *
8   *     http://www.tizenopensource.org/license
9   *
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS,
12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   * See the License for the specific language governing permissions and
14   * limitations under the License.
15   */
16
17 #include <vconf.h>
18 #include <vconf-keys.h>
19 #include <media-svc.h>
20 #include <appcore-efl.h>
21 #include "gl-db-handler.h"
22 #include "gl-controlbar.h"
23 #include "gallery.h"
24 #include "gl-debug.h"
25 #include "gl-util.h"
26 #include "gl-strings.h"
27
28 static bool
29 _gl_db_get_file_dir_names(const char *file_path,
30         char *filename, char *dir_name, char *dir_path)
31 {
32         gl_dbg("");
33         GL_CHECK_FALSE(file_path);
34         gint i = 0;
35         gint count = 0;
36         for (i = strlen(file_path); i >= 0; i--)
37         {
38                 if (file_path[i] != '\0')
39                 {
40                         count++;
41                 }
42                 if (file_path[i] == '/')
43                 {
44                         if (filename != NULL)
45                         {
46                                 memcpy(filename, &file_path[i + 1], --count);
47                                 *(filename + count) = '\0';
48                                 gl_dbg("File Name = %s", filename);
49                         }
50                         if (dir_path != NULL)
51                         {
52                                 memcpy(dir_path, &file_path[0], i);     // , i +1 changed to , i
53                                 *(dir_path + i) = '\0';
54                                 gl_dbg("Directory Name = %s", dir_path);
55                         }
56                         if (dir_name != NULL)
57                         {
58                                 count = 0;
59                                 for (--i; i >= 0; i--)
60                                 {
61                                         count++;
62                                         if (file_path[i] == '/')
63                                         {
64                                                 memcpy(dir_name, &file_path[i + 1], --count);
65                                                 *(dir_name + count) = '\0';
66                                                 gl_dbg("Directory Name = %s", dir_name);
67                                                 count = 0;
68                                                 return true;
69                                         }
70                                 }
71                         }
72                         return true;
73                 }
74         }
75
76         return false;
77 }
78
79 static int _gl_db_elist_ite_fn(Mitem *item, void *user_data)
80 {
81         Eina_List **list = (Eina_List **)user_data;
82         *list = eina_list_append(*list, item);
83
84         return 0;
85 }
86
87 static int _gl_db_cluster_elist_ite_fn(Mcluster *cluster, void *user_data)
88 {
89         Eina_List **list = (Eina_List **)user_data;
90         *list = eina_list_append(*list, cluster);
91
92         return 0;
93 }
94
95 /*
96 *  create a gl_item
97 */
98 static gl_item *
99 _gl_db_new_item(void)
100 {
101         // new a gl_item
102         gl_item *gitem = (gl_item *) malloc(sizeof(gl_item));
103         GL_CHECK_NULL(gitem);
104         memset(gitem, 0x00, sizeof(gl_item));
105
106         //initialize gitem
107         gitem->ad = NULL;
108         gitem->checked = false;
109         gitem->check_obj = NULL;
110         gitem->elm_item = NULL;
111         gitem->item = NULL;
112         gitem->_reserved = NULL;
113
114         return gitem;
115 }
116
117 /*
118 *   destroy a gl_item
119 */
120 static int
121 _gl_db_destroy_item(gl_item * gitem)
122 {
123         GL_CHECK_VAL(gitem, GL_DB_FAIL);
124         if (gitem->item)
125         {
126                 minfo_destroy_mtype_item(gitem->item);
127                 gitem->item = NULL;
128         }
129
130         if (gitem->_reserved)
131         {
132                 free(gitem->_reserved);
133                 gitem->_reserved = NULL;
134         }
135
136         gitem->checked = false;
137         gitem->check_obj = NULL;
138         gitem->elm_item = NULL;
139
140         free(gitem);
141         gitem = NULL;
142
143         return GL_DB_SUCCESS;
144 }
145
146 /* Clear eina_list got from DB */
147 static int _gl_db_clear_mtype_items_list(Eina_List **elist)
148 {
149         void *current = NULL;
150
151         if (elist && *elist) {
152                 gl_dbg("Clear Mtype items list.");
153                 EINA_LIST_FREE(*elist, current) {
154                         if (current) {
155                                 minfo_destroy_mtype_item(current);
156                                 current = NULL;
157                         }
158                 }
159
160                 *elist = NULL;
161         }
162
163         return GL_DB_SUCCESS;
164 }
165
166 static int
167 _gl_db_clear_item_list(void *data)
168 {
169         GL_CHECK_VAL(data, GL_DB_FAIL);
170         gl_appdata *ad = (gl_appdata *)data;
171         gl_item *current = NULL;
172         if (ad->maininfo.medias_elist)
173         {
174                 Eina_List *item_list = ad->maininfo.medias_elist;
175                 EINA_LIST_FREE(item_list, current)
176                 {
177                         _gl_db_destroy_item(current);
178                         current = NULL;
179                 }
180                 ad->maininfo.medias_elist = NULL;
181         }
182
183         return GL_DB_SUCCESS;
184 }
185
186 int
187 _gl_db_free_cluster_all(gl_cluster* gcluster)
188 {
189         GL_CHECK_VAL(gcluster, GL_DB_FAIL);
190         GL_CHECK_VAL(gcluster->cluster, GL_DB_FAIL);
191
192         if(gcluster->cluster->display_name)
193         {
194                 free(gcluster->cluster->display_name);
195                 gcluster->cluster->display_name = NULL;
196         }
197
198         if(gcluster->_reserved)
199         {
200                 free(gcluster->_reserved);
201                 gcluster->_reserved = NULL;
202         }
203
204         free(gcluster->cluster);
205         gcluster->cluster = NULL;
206         free(gcluster);
207         return GL_DB_SUCCESS;
208 }
209
210 int
211 _gl_db_free_cluster(gl_cluster * gcluster)
212 {
213         GL_CHECK_VAL(gcluster, GL_DB_FAIL);
214         if (gcluster->cluster)
215         {
216                 minfo_destroy_mtype_item(gcluster->cluster);
217                 gcluster->cluster = NULL;
218         }
219         if (gcluster->_reserved)
220         {
221                 free(gcluster->_reserved);
222                 gcluster->_reserved = NULL;
223         }
224         free(gcluster);
225         return GL_DB_SUCCESS;
226 }
227
228 static int
229 _gl_db_clear_cluster_list(void *data, bool b_force)
230 {
231         GL_CHECK_VAL(data, GL_DB_FAIL);
232         gl_appdata *ad = (gl_appdata *)data;
233         gl_cluster *current = NULL;
234         Eina_List *tmp_list = NULL;
235
236         // To reset current album when clear cluster list.
237         ad->albuminfo.current_album = NULL;
238
239         if (ad->albuminfo.cluster_list)
240         {
241                 if (ad->albuminfo.cluster_list->clist)
242                 {
243                         tmp_list = ad->albuminfo.cluster_list->clist;
244
245                         EINA_LIST_FREE(tmp_list, current)
246                         {
247                                 if (current)
248                                 {
249                                         gl_db_free_cluster(current);
250                                         current = NULL;
251                                 }
252                         }
253                         ad->albuminfo.cluster_list->clist = NULL;
254                 }
255
256                 if (b_force) {
257                         free(ad->albuminfo.cluster_list);
258                         ad->albuminfo.cluster_list = NULL;
259                 }
260         }
261
262         return GL_DB_SUCCESS;
263 }
264
265 static gl_cluster *_gl_db_new_cluster_all(void *data, int all_item_cnt)
266 {
267         gl_dbg("");
268         GL_CHECK_NULL(data);
269         gl_cluster *gcluster = NULL;
270         Mcluster *mcluster = NULL;
271
272         gcluster = gl_db_new_cluster();
273         GL_CHECK_NULL(gcluster);
274
275         mcluster = gl_db_new_mcluster(data, GL_NEW_RECORD_ID);
276         if (mcluster == NULL) {
277                 free(gcluster);
278                 gcluster = NULL;
279                 return NULL;
280         }
281         mcluster->uuid = strdup(GL_ALBUM_ALL_ID);
282         mcluster->count = all_item_cnt;
283         mcluster->display_name = strdup(GL_ALBUM_ALL_NAME);
284         gcluster->ad = data;
285         gcluster->cluster = mcluster;
286         return gcluster;
287 }
288
289
290
291 static gl_cluster_list *
292 _gl_db_new_cluster_list(void)
293 {
294         gl_cluster_list *clus_list = (gl_cluster_list *) malloc(sizeof(gl_cluster_list));
295         GL_CHECK_NULL(clus_list);
296         memset(clus_list, 0x00, sizeof(gl_cluster_list));
297         clus_list->clist = NULL;
298         clus_list->cur_pos = 0;
299
300         return clus_list;
301 }
302
303 static int _gl_db_get_selected_cluster_id_list(void *data, Eina_List **sel_id_list)
304 {
305         GL_CHECK_VAL(sel_id_list, -1);
306         GL_CHECK_VAL(data, -1);
307         gl_appdata *ad = (gl_appdata *)data;
308         gl_cluster *gcluster = NULL;
309         char *item_id = NULL;
310
311         if (ad->albuminfo.selected_albums_elist == NULL)
312                 return 0;
313
314         /* Save ID of selected clusters */
315         EINA_LIST_FREE(ad->albuminfo.selected_albums_elist, gcluster) {
316                 if (gcluster && gcluster->cluster && gcluster->cluster->uuid) {
317                         item_id = strdup(gcluster->cluster->uuid);
318                         *sel_id_list = eina_list_append(*sel_id_list,
319                                                         (void *)item_id);
320                 }
321         }
322         gl_db_finalize_albums_selected_list(ad);
323         return 0;
324 }
325
326 /**
327 * Some issue about using ecore_file_exists(gitem->item->file_url),
328 * if user rename file in Myfile, file_url changed.
329 */
330 static int _gl_db_get_selected_item_id_list(void *data, Eina_List **sel_id_list)
331 {
332         GL_CHECK_VAL(sel_id_list, -1);
333         GL_CHECK_VAL(data, -1);
334         gl_appdata *ad = (gl_appdata *)data;
335         GL_CHECK_VAL(ad->selectedinfo.medias_elist, -1);
336         gl_item *gitem = NULL;
337         char *item_id = NULL;
338
339         /* Save ID of selected items */
340         EINA_LIST_FREE(ad->selectedinfo.medias_elist, gitem) {
341                 if (gitem && gitem->item && gitem->item->uuid) {
342                         item_id = strdup(gitem->item->uuid);
343                         *sel_id_list = eina_list_append(*sel_id_list,
344                                                         (void *)item_id);
345                 }
346         }
347
348         gl_db_selected_list_finalize(ad);
349         return 0;
350 }
351
352 /* Check ID is in the list or not */
353 static bool _gl_db_check_selected_id(Eina_List **sel_id_list, const char *id)
354 {
355         GL_CHECK_FALSE(sel_id_list);
356         Eina_List *tmp_elist = NULL;
357         void *p_id = NULL;
358         GL_CHECK_FALSE(id);
359
360         if (eina_list_count(*sel_id_list) == 0) {
361                 gl_dbgE("sel_id_list is empty!");
362                 return false;
363         }
364
365         EINA_LIST_FOREACH(*sel_id_list, tmp_elist, p_id) {
366                 if (p_id == NULL) {
367                         gl_dbgE("Invalid p_id!");
368                         continue;
369                 }
370                 /* Get next one if they wasn't equal */
371                 if (g_strcmp0(id, (char *)p_id)) {
372                         p_id = NULL;
373                         continue;
374                 }
375                 *sel_id_list = eina_list_remove(*sel_id_list, p_id);
376                 free(p_id);
377                 p_id = NULL;
378                 return true;
379         }
380         return false;
381 }
382
383 /* Free list of selected IDs */
384 static int __gl_db_free_selected_id_list(Eina_List **sel_id_list)
385 {
386         GL_CHECK_VAL(sel_id_list, -1);
387         if (*sel_id_list == NULL) {
388                 gl_dbg("sel_id_list is empty!");
389                 return -1;
390         }
391
392         void *p_id = NULL;
393         EINA_LIST_FREE(*sel_id_list, p_id) {
394                 if (p_id == NULL) {
395                         gl_dbgE("Invalid p_id!");
396                         continue;
397                 }
398                 free(p_id);
399                 p_id = NULL;
400         }
401         *sel_id_list = NULL;
402         return 0;
403 }
404
405 static int _gl_db_get_cluster_list(void *data, bool b_update)
406 {
407         GL_CHECK_VAL(data, -1);
408         gl_appdata *ad = (gl_appdata *)data;
409         int length = 0;
410         int local_item_cnt = 0;
411         Eina_List *item_list = NULL;
412         Mcluster *f_data = NULL;
413         gl_cluster *default_cluster = NULL;
414         int err = -1;
415         int edit_album_cnt = 0;
416         minfo_cluster_filter filter;
417         Mcluster *new_mc = NULL;
418         Eina_List *sel_id_list = NULL;
419         bool b_selected = false;
420         char new_mc_id[GL_MTYPE_ITEN_ID_LEN_MAX] = { 0, };
421         char sel_id[GL_MTYPE_ITEN_ID_LEN_MAX] = { 0, };
422
423         if (b_update) {
424                 gl_dbg("Update mode.");
425                 gl_cluster *album_item = ad->albuminfo.selected_album;
426                 if (album_item && album_item->cluster &&
427                     album_item->cluster->uuid) {
428                         g_strlcpy(sel_id, album_item->cluster->uuid,
429                                   GL_MTYPE_ITEN_ID_LEN_MAX);
430                         gl_dbg("Save selected album ID: %s.", sel_id);
431                 }
432                 ad->albuminfo.selected_album = NULL;
433                 /* Get selected cluster IDs list */
434                 _gl_db_get_selected_cluster_id_list(ad, &sel_id_list);
435                 /* Clear cluster list */
436                 _gl_db_clear_cluster_list(ad, false);
437         }
438
439         memset(&filter,0x00,sizeof(minfo_cluster_filter));
440         //ad->new_album_name is the cluster name of newly created album
441         //in moving medias to new album case.
442         if (strlen(ad->albuminfo.new_album_name))
443         {
444                 memset(ad->albuminfo.new_album_name, 0x00, GL_ALBUM_NAME_LEN_MAX);
445                 //get Mcluster from DB via folder full path(URL).
446                 err = minfo_get_cluster(ad->maininfo.db_handle,
447                                         ad->albuminfo.dest_folder, NULL, &new_mc);
448                 if (err < 0)
449                 {
450                         gl_dbgE("minfo_get_cluster fail: %d", err);
451                 }
452                 else if (new_mc->count == 0)
453                 {
454                         //media records of this cluster havn't been inserted to DB.
455                         //save the cluster ID.
456                         //update cluster item count while refresh albums view in _gl_albums_get_label().
457                         gl_dbg("Get newly created Mcluster, url: %s.", ad->albuminfo.dest_folder);
458                         g_strlcpy(new_mc_id, new_mc->uuid,
459                                   GL_MTYPE_ITEN_ID_LEN_MAX);
460                         minfo_destroy_mtype_item(new_mc);
461                 }
462         }
463
464         //get real albums
465         filter.cluster_type = MINFO_CLUSTER_TYPE_ALL;
466         filter.sort_type = MINFO_CLUSTER_SORT_BY_NAME_ASC;
467         filter.start_pos = GL_GET_ALL_RECORDS;
468         filter.end_pos = GL_GET_ALL_RECORDS;
469
470         err = minfo_get_cluster_list(ad->maininfo.db_handle, filter,
471                                         _gl_db_cluster_elist_ite_fn, &item_list);
472         if (err == MB_SVC_ERROR_DB_NO_RECORD)
473         {
474                 gl_dbg("No record!");
475                 ad->albuminfo.cluster_list->clist = NULL;
476                 if (item_list)
477                         _gl_db_clear_mtype_items_list(&item_list);
478                 /* Continue to add AllShare album */
479         }
480         else if (err < 0)
481         {
482                 gl_dbg("Failed to get cluster list!");
483                 if (item_list)
484                         _gl_db_clear_mtype_items_list(&item_list);
485                 /* Continue to add AllShare album */
486         }
487
488         gl_cluster *gcluster = NULL;
489         EINA_LIST_FREE(item_list, f_data) {
490                 if (f_data == NULL || f_data->uuid == NULL) {
491                         gl_dbgE("Invalid Mcluster!");
492                         continue;
493                 }
494                 gl_dbg("folder id: %s.", f_data->uuid);
495
496                 /**
497                 * There are Phone and other filters in libmedia-info,
498                 * but they are seperated, if we want to get  phone
499                 * only we can use is MINFO_CLUSTER_TYPE_ALL,
500                 * and add condition checking to skip MMC albums.
501                 *
502                 * To skip MMC albums if MMC already unmounted,
503                 * in case of delay updating in DB.
504                 */
505                 if ((ad->maininfo.mmc_state == GL_MMC_STATE_REMOVED_MOVING ||
506                      ad->maininfo.mmc_state == GL_MMC_STATE_REMOVED) &&
507                     f_data->type == MINFO_MMC) {
508                         gl_dbgW("MMC was unmounted, skip MMC album!");
509                         minfo_destroy_mtype_item(f_data);
510                         continue;
511                 }
512
513                 if (f_data->count == 0) {
514                         /* append the newly created cluster to list */
515                         if (!g_strcmp0(f_data->uuid, new_mc_id)) {
516                                 gl_dbg("empty local album, but it's newly created...");
517                         } else {
518                                 gl_dbg("empty local album, skipping it...");
519                                 minfo_destroy_mtype_item(f_data);
520                                 continue;
521                         }
522                 }
523                 local_item_cnt += f_data->count;
524
525                 gcluster = NULL;
526                 gcluster = gl_db_new_cluster();
527                 if (gcluster == NULL) {
528                         gl_dbgE("gl_db_new_cluster failed!");
529                         minfo_destroy_mtype_item(f_data);
530                         continue;
531                 }
532
533                 gcluster->ad = ad;
534                 gcluster->cluster = f_data;
535                 length += f_data->count;
536
537                 if (gl_db_is_default_album(ad, f_data))
538                 {
539                         /**
540                         * Default album: Camera Shot
541                         * Now Camera Shot is located in Phone.
542                         * If user can determine the location of default album,
543                         * here we should get the path and check it's in Phone or MMC.
544                         */
545                         default_cluster = gcluster;
546                         ad->albuminfo.cluster_list->clist = eina_list_prepend(ad->albuminfo.cluster_list->clist,
547                                                                                                         gcluster);
548                 }
549                 else
550                 {
551                         ad->albuminfo.cluster_list->clist = eina_list_append(ad->albuminfo.cluster_list->clist,
552                                                                                                         gcluster);
553                 }
554                 /* Default album 'Camera shots' showed in edit view */
555                 edit_album_cnt++;
556
557                 if (sel_id_list) {
558                         b_selected = _gl_db_check_selected_id(&sel_id_list,
559                                                               f_data->uuid);
560                         if (b_selected) {
561                                 b_selected = false;
562                                 /* Set checkbox state */
563                                 gcluster->checked = true;
564                                 /* Append gcluster to selected list */
565                                 gl_db_albums_selected_list_append(ad, gcluster);
566                         }
567                 }
568                 if (strlen(sel_id) > 0 && !g_strcmp0(sel_id, f_data->uuid)) {
569                         gl_dbgW("Found selected_album.");
570                         ad->albuminfo.selected_album = gcluster;
571                 }
572         }
573
574         /* Clear list of selected ID */
575         if (sel_id_list)
576                 __gl_db_free_selected_id_list(&sel_id_list);
577
578         ad->albuminfo.cluster_list->edit_cnt = edit_album_cnt;
579         /**
580         * add "all" album, only inclduing local albums temporarily,
581         */
582         if (local_item_cnt) {
583                 /* Create "All albums" album if any local file exists */
584                 gcluster = _gl_db_new_cluster_all(ad, local_item_cnt);
585                 if (gcluster == NULL) {
586                         gl_dbgE("_gl_db_new_cluster_all failed!");
587                         _gl_db_clear_cluster_list(ad, false);
588                         return -1;
589                 }
590
591                 if (default_cluster)
592                         ad->albuminfo.cluster_list->clist = eina_list_append_relative(ad->albuminfo.cluster_list->clist,
593                                                                                                         gcluster, default_cluster);
594                 else
595                         ad->albuminfo.cluster_list->clist = eina_list_prepend(ad->albuminfo.cluster_list->clist,
596                                                                                                         gcluster);
597
598                 default_cluster = gcluster;
599         }
600
601         gl_dbg("Cluster Done.");
602         return length;
603 }
604
605 /*
606 *  get a new item from media service by item id
607 */
608 Mitem *gl_db_new_mitem(void *data, const char *item_id)
609 {
610         GL_CHECK_NULL(data);
611         Mitem *mitem = NULL;
612         gl_appdata *ad = (gl_appdata *)data;
613         /*new API, to use media id to get item.  */
614         minfo_get_item_by_id(ad->maininfo.db_handle, item_id, &mitem);
615
616         return mitem;
617 }
618
619 gl_item *
620 gl_db_new_item_mitem(Mitem * mitem)
621 {
622         gl_item *gitem = _gl_db_new_item();
623         GL_CHECK_NULL(gitem);
624         gitem->item = mitem;
625
626         return gitem;
627 }
628
629 /*
630 *   get a new cluster from media service by cluster id
631 */
632 Mcluster *gl_db_new_mcluster(void *data, const char *cluster_id)
633 {
634         gl_dbg("cluster_id=%s", cluster_id);
635         GL_CHECK_NULL(data);
636         gl_appdata *ad = (gl_appdata *)data;
637         Mcluster *mcluster = NULL;
638         int ret = -1;
639         ret = minfo_get_cluster(ad->maininfo.db_handle, NULL, cluster_id, &mcluster);
640         if (ret != 0)
641         {
642                 gl_dbgE("minfo_get_cluster failed (ret=%d)", ret);
643                 if (mcluster)
644                 {
645                         minfo_destroy_mtype_item(mcluster);
646                 }
647
648                 return NULL;
649         }
650
651         return mcluster;
652 }
653
654 gl_cluster *
655 gl_db_new_cluster(void)
656 {
657         gl_cluster *gcluster = (gl_cluster *) malloc(sizeof(gl_cluster));
658         GL_CHECK_NULL(gcluster);
659         memset(gcluster, 0x00, sizeof(gl_cluster));
660         gcluster->cluster = NULL;
661         gcluster->index = 0;
662         gcluster->item = NULL;
663         gcluster->checked = false;
664         gcluster->ad = NULL;
665         gcluster->_reserved = NULL;
666
667         return gcluster;
668 }
669
670 int
671 gl_db_clear_item_list(void *data)
672 {
673         GL_CHECK_VAL(data, GL_DB_FAIL);
674         _gl_db_clear_item_list(data);
675
676         return GL_DB_SUCCESS;
677 }
678
679 int
680 gl_db_free_cluster(gl_cluster * gcluster)
681 {
682         GL_CHECK_VAL(gcluster, GL_DB_FAIL);
683
684         if (gcluster->cluster && gcluster->cluster->uuid &&
685             !g_strcmp0(gcluster->cluster->uuid, GL_ALBUM_ALL_ID))
686         {
687                 _gl_db_free_cluster_all(gcluster);
688         }
689         else
690         {
691                 _gl_db_free_cluster(gcluster);
692         }
693
694         return GL_DB_SUCCESS;
695 }
696
697 bool
698 gl_db_get_cluster_list(void *data)
699 {
700         GL_CHECK_FALSE(data);
701         gl_appdata *ad = (gl_appdata *)data;
702         int n_entire_items = 0;
703
704         _gl_db_clear_cluster_list(ad, true);
705
706         ad->albuminfo.cluster_list = _gl_db_new_cluster_list();
707         GL_CHECK_FALSE(ad->albuminfo.cluster_list);
708         n_entire_items = _gl_db_get_cluster_list(ad, false);
709         if (n_entire_items <= 0)        //if error code is returned, negative value is possible
710         {
711                 return false;
712         }
713         gl_dbg("cluster-length:%d", n_entire_items);
714
715         return true;
716 }
717
718 int gl_db_update_cluster_list(void *data)
719 {
720         GL_CHECK_VAL(data, -1);
721         gl_appdata *ad = (gl_appdata *)data;
722         int len = 0;
723
724         len = _gl_db_get_cluster_list(ad, true);
725         gl_dbg("Cluster list length: %d.", len);
726         if (len <= 0)
727                 return GL_DB_FAIL;
728
729         return GL_DB_SUCCESS;
730 }
731
732 int
733 gl_db_cluster_list_remove(void *data, gl_cluster * item)
734 {
735         GL_CHECK_VAL(item, GL_DB_FAIL);
736         GL_CHECK_VAL(item->cluster, GL_DB_FAIL);
737         GL_CHECK_VAL(item->cluster->uuid, GL_DB_FAIL);
738         GL_CHECK_VAL(data, GL_DB_FAIL);
739         gl_appdata *ad = (gl_appdata *)data;
740         gl_cluster *current = NULL;
741         Eina_List *l = NULL;
742
743         GL_CHECK_VAL(ad->albuminfo.cluster_list, GL_DB_FAIL);
744         GL_CHECK_VAL(ad->albuminfo.cluster_list->clist, GL_DB_FAIL);
745         Eina_List *cluster_list = ad->albuminfo.cluster_list->clist;
746         EINA_LIST_FOREACH(cluster_list, l, current)
747         {
748                 if (current == NULL || current->cluster == NULL ||
749                     current->cluster->uuid == NULL) {
750                         gl_dbgE("Invalid album item!");
751                         continue;
752                 }
753
754                 if (!g_strcmp0(current->cluster->uuid, item->cluster->uuid))
755                 {
756                         ad->albuminfo.cluster_list->clist = eina_list_remove(ad->albuminfo.cluster_list->clist,
757                                                                                                         current);
758                         gl_db_free_cluster(current);
759                         break;
760                 }
761                 current = NULL;
762         }
763
764         return GL_DB_SUCCESS;
765 }
766
767 int gl_db_get_cluster_by_id(void *data, const char *cluster_id, gl_cluster **cluster, int *pos)
768 {
769         GL_CHECK_VAL(data, -1);
770         GL_CHECK_VAL(pos, -1);
771         GL_CHECK_VAL(cluster, -1);
772         GL_CHECK_VAL(cluster_id, -1);
773         gl_appdata *ad = (gl_appdata *)data;
774         int i = 0;
775         gl_cluster *current = NULL;
776
777         *cluster = NULL;
778         *pos = 0;
779
780         GL_CHECK_VAL(ad->albuminfo.cluster_list, -1);
781         int length = eina_list_count(ad->albuminfo.cluster_list->clist);
782         gl_dbg("album length: %d, current album id: %s", length, cluster_id);
783
784         for (i = 0; i < length; i++) {
785                 current = eina_list_nth(ad->albuminfo.cluster_list->clist, i);
786                 if (current && current->cluster && current->cluster->uuid) {
787                         gl_dbg("cluster : %s", current->cluster->display_name);
788                 } else {
789                         gl_dbg("cluster is NULL");
790                         break;
791                 }
792
793                 if (!g_strcmp0(current->cluster->uuid, cluster_id)) {
794                         *pos = i;
795                         *cluster = current;
796                         gl_dbg("Find album: %s", current->cluster->display_name);
797                         return 0;
798                 }
799         }
800         return 0;
801 }
802
803 //add a new cluster whose url is 'cluster_url'.
804 int
805 gl_db_add_cluster(void *data, char *cluster_url)
806 {
807         GL_CHECK_VAL(cluster_url, GL_DB_FAIL);
808         GL_CHECK_VAL(data, GL_DB_FAIL);
809         gl_appdata *ad = (gl_appdata *)data;
810         int ret = -1;
811
812         char cluster_id[GL_MTYPE_ITEN_ID_LEN_MAX] = { 0, };
813         ret = minfo_add_cluster(ad->maininfo.db_handle, cluster_url, cluster_id,
814                                 GL_MTYPE_ITEN_ID_LEN_MAX);
815         if (ret < 0)
816         {
817                 gl_dbgE("minfo_add_cluster failed, ret: %d", ret);
818         }
819         return GL_DB_SUCCESS;
820 }
821
822 /* Get new record from DB to check mitem exists or was already removed */
823 bool gl_db_exists_item(void *data, const char *id)
824 {
825         GL_CHECK_NULL(data);
826         GL_CHECK_FALSE(id);
827         gl_appdata *ad = (gl_appdata *)data;
828         Mitem *new_item = gl_db_new_mitem(ad, id);
829         if (new_item == NULL) {
830                 gl_dbgW("Mitem doesn't exist!");
831                 return false;
832         } else {
833                 minfo_destroy_mtype_item(new_item);
834                 new_item = NULL;
835                 return true;
836         }
837 }
838
839 /**
840 * Get medias count of album.
841 */
842 int gl_db_get_item_cnt(void *data, const char *cluster_id, int *item_cnt)
843 {
844         GL_CHECK_VAL(item_cnt, GL_DB_FAIL);
845         GL_CHECK_VAL(cluster_id, GL_DB_FAIL);
846         GL_CHECK_VAL(data, GL_DB_FAIL);
847         gl_appdata *ad = (gl_appdata *)data;
848         int err = -1;
849         gl_dbg("cluster_id: %s.", cluster_id);
850
851         if (g_strcmp0(cluster_id, GL_ALBUM_ALL_ID)) {
852                 /* It's normal album */
853                 minfo_item_filter filter;
854                 memset(&filter, 0x00, sizeof(minfo_item_filter));
855                 filter.file_type = MINFO_ITEM_IMAGE | MINFO_ITEM_VIDEO;
856                 filter.sort_type = MINFO_MEDIA_SORT_BY_DATE_DESC;
857                 filter.start_pos = GL_GET_ALL_RECORDS;
858                 filter.end_pos = GL_GET_ALL_RECORDS;
859                 filter.with_meta = false;
860
861                 err = minfo_get_item_cnt(ad->maininfo.db_handle, cluster_id,
862                                                 filter, item_cnt);
863         } else {
864                 /* All albums */
865                 gl_dbg("All albums media count.");
866                 gl_dbg("All albums media count.");
867                 err = minfo_get_all_item_count(ad->maininfo.db_handle,
868                                                    MINFO_CLUSTER_TYPE_LOCAL_ALL,
869                                                    MINFO_ITEM_ALL,
870                                                    MINFO_MEDIA_FAV_ALL, item_cnt);
871         }
872
873         if (err < 0) {
874                 gl_dbg("Failed to get item count[err: %d]!", err);
875                 return GL_DB_FAIL;
876         }
877
878         gl_dbg("Item count: %d.", *item_cnt);
879         return GL_DB_SUCCESS;
880 }
881
882 int gl_db_update_item_cnt(gl_cluster * album)
883 {
884         GL_CHECK_VAL(album, GL_DB_FAIL);
885         GL_CHECK_VAL(album->cluster, GL_DB_FAIL);
886         int item_count = 0;
887         int err = GL_DB_FAIL;
888         GL_CHECK_VAL(album->cluster->uuid, GL_DB_FAIL);
889         err = gl_db_get_item_cnt(album->ad, album->cluster->uuid, &item_count);
890         if (err != GL_DB_SUCCESS) {
891                 gl_dbg("gl_db_get_item_cnt failed!");
892                 album->cluster->count = 0;
893                 return GL_DB_FAIL;
894         }
895
896         gl_dbg("Media count: old=%d, new=%d", album->cluster->count,
897                item_count);
898         album->cluster->count = item_count;
899
900         return GL_DB_SUCCESS;
901 }
902
903 int
904 gl_db_get_item_list(void *data,
905                 gl_cluster * album,
906                 int start_pos,
907                 int end_pos)
908 {
909         GL_CHECK_VAL(data, -1);
910         gl_appdata *ad = (gl_appdata *)data;
911         Eina_List *itemlist = NULL;
912         minfo_item_filter filter;
913         int err = -1;
914         minfo_file_type file_type;
915
916         file_type = MINFO_ITEM_IMAGE | MINFO_ITEM_VIDEO; /* default */
917         /* get file-type from bundle when launched by appsvc */
918         if (ad->albuminfo.aul_launch_type == GL_AUL_T_VIEW_ALBUM) {
919                 if (ad->albuminfo.aul_file_type == GL_AUL_FILE_T_IMAGE) {
920                         file_type = MINFO_ITEM_IMAGE;
921                 } else if (ad->albuminfo.aul_file_type == GL_AUL_FILE_T_VIDEO) {
922                         file_type = MINFO_ITEM_VIDEO;
923                 }
924         }
925
926         memset(&filter,0x00,sizeof(minfo_item_filter));
927         GL_CHECK_VAL(album, GL_DB_FAIL);
928         GL_CHECK_VAL(album->cluster, GL_DB_FAIL);
929         gl_dbg("db_get_item_list--folder category; start_pos[%d], end_pos[%d]\n",
930                 start_pos, end_pos);
931
932         GL_CHECK_VAL(album->cluster->uuid, GL_DB_FAIL);
933         /* Real album */
934         if (g_strcmp0(album->cluster->uuid, GL_ALBUM_ALL_ID))
935         {
936                 filter.file_type = file_type;
937                 filter.sort_type = MINFO_MEDIA_SORT_BY_DATE_DESC;
938                 filter.start_pos = start_pos;
939                 filter.end_pos = end_pos;
940                 filter.with_meta = true;
941
942                 ad->uginfo.sort_type = filter.sort_type;
943
944                 if (start_pos == (GL_FIRST_VIEW_END_POS + 1) &&
945                         end_pos == GL_GET_UNTIL_LAST_RECORD)
946                 {
947                         /* Keep medias_elist and medias_cnt unchanged */
948                         gl_dbg("Gridview append idler; Keep medias_elist unchanged.");
949                 }
950                 else
951                 {
952                         /*Clear item list before new one got */
953                         _gl_db_clear_item_list(ad);
954                 }
955
956                 err = minfo_get_item_list(ad->maininfo.db_handle,
957                                                 album->cluster->uuid, filter,
958                                                 _gl_db_elist_ite_fn, &itemlist);
959         }
960         else            //add "All" album
961         {
962                 gl_dbg("db_get_item_list--all media\n");
963                 filter.file_type = file_type;
964                 filter.sort_type = MINFO_MEDIA_SORT_BY_DATE_DESC;
965                 filter.start_pos = start_pos;
966                 filter.end_pos = end_pos;
967                 filter.with_meta = true;
968
969                 ad->uginfo.sort_type = filter.sort_type;
970
971                 if (start_pos == (GL_FIRST_VIEW_END_POS + 1) &&
972                         end_pos == GL_GET_UNTIL_LAST_RECORD)
973                 {
974                         /* Keep medias_elist and medias_cnt unchanged */
975                         gl_dbg("Gridview append idler; Keep medias_elist unchanged.");
976                 }
977                 else
978                 {
979                         /* Clear item list before new one got */
980                         _gl_db_clear_item_list(ad);
981                 }
982
983                 err = minfo_get_all_item_list(ad->maininfo.db_handle,
984                                                   MINFO_CLUSTER_TYPE_LOCAL_ALL, filter,
985                                               _gl_db_elist_ite_fn,
986                                               &itemlist);
987         }
988
989         gl_dbg("Error code: %d", err);
990         if ((err == 0) && (itemlist != NULL))
991         {
992                 Mitem *item = NULL;
993                 gl_item *gitem = NULL;
994                 EINA_LIST_FREE(itemlist, item)
995                 {
996                         if (item == NULL || item->uuid == NULL) {
997                                 gl_dbgE("Invalid item!");
998                                 continue;
999                         }
1000
1001                         gitem = _gl_db_new_item();
1002                         if (gitem == NULL) {
1003                                 gl_dbgE("_gl_db_new_item failed!");
1004                                 minfo_destroy_mtype_item(gitem);
1005                                 continue;
1006                         }
1007
1008                         gitem->ad = ad;
1009                         gitem->item = item;
1010                         ad->maininfo.medias_elist = eina_list_append(ad->maininfo.medias_elist, gitem);
1011
1012                         item = NULL;
1013                         gitem = NULL;
1014                 }
1015
1016                 ad->maininfo.medias_cnt = eina_list_count(ad->maininfo.medias_elist);
1017                 gl_dbg("medias_elist=%p", ad->maininfo.medias_elist);
1018         }
1019         else
1020         {
1021                 ad->maininfo.medias_cnt = 0;
1022                 if (start_pos == (GL_FIRST_VIEW_END_POS + 1) &&
1023                         end_pos == GL_GET_UNTIL_LAST_RECORD)
1024                 {
1025                         /* Keep medias_elist and medias_cnt unchanged */
1026                         ad->maininfo.medias_cnt = eina_list_count(ad->maininfo.medias_elist);
1027                         gl_dbg("Gridview append idler; medias_elist=%p",
1028                                ad->maininfo.medias_elist);
1029                 }
1030                 else
1031                 {
1032                         ad->maininfo.medias_elist = NULL;
1033                 }
1034
1035                 if (itemlist)
1036                         _gl_db_clear_mtype_items_list(&itemlist);
1037         }
1038
1039         gl_dbg("DB all count : %d", ad->maininfo.medias_cnt);
1040         return err;
1041 }
1042
1043 int gl_db_update_item_list(void *data)
1044 {
1045         GL_CHECK_VAL(data, -1);
1046         gl_appdata *ad = (gl_appdata *)data;
1047         Eina_List *itemlist = NULL;
1048         minfo_item_filter filter;
1049         int err = -1;
1050         int view_mode = gl_get_view_mode(ad);
1051         Eina_List *sel_id_list = NULL;
1052         gl_item *gitem = NULL;
1053
1054         memset(&filter, 0x00, sizeof(minfo_item_filter));
1055
1056         if (view_mode == GL_VIEW_THUMBS_EDIT ||
1057             view_mode == GL_VIEW_VIDEOLIST_EDIT) {
1058                 gl_dbg("Edit view.");
1059                 /* Get ID list of selected items */
1060                 _gl_db_get_selected_item_id_list(ad, &sel_id_list);
1061         }
1062
1063         gl_cluster *cur_album = ad->albuminfo.current_album;
1064         GL_CHECK_VAL(cur_album, -1);
1065         GL_CHECK_VAL(cur_album->cluster, -1);
1066         GL_CHECK_VAL(cur_album->cluster->uuid, -1);
1067
1068         filter.file_type = MINFO_ITEM_IMAGE | MINFO_ITEM_VIDEO;
1069         filter.sort_type = MINFO_MEDIA_SORT_BY_DATE_DESC;
1070         filter.start_pos = GL_GET_ALL_RECORDS;
1071         filter.end_pos = GL_GET_ALL_RECORDS;
1072         filter.with_meta = true;
1073
1074         ad->uginfo.sort_type = filter.sort_type;
1075         /* Clear item list before new one got */
1076         _gl_db_clear_item_list(ad);
1077
1078         if (!g_strcmp0(cur_album->cluster->uuid, GL_ALBUM_ALL_ID)) {
1079                 gl_dbg("All albums medias");
1080                 int cluster_t = MINFO_CLUSTER_TYPE_LOCAL_ALL;
1081                 err = minfo_get_all_item_list(ad->maininfo.db_handle,
1082                                                         cluster_t, filter,
1083                                                         _gl_db_elist_ite_fn,
1084                                                         &itemlist);
1085         } else {
1086                 gl_dbg("Normal album medias");
1087                 err = minfo_get_item_list(ad->maininfo.db_handle,
1088                                                 cur_album->cluster->uuid,
1089                                                 filter, _gl_db_elist_ite_fn,
1090                                                 &itemlist);
1091         }
1092
1093         gl_dbg("Error code: %d", err);
1094         if ((err != 0) || (itemlist == NULL)) {
1095                 gl_dbgE("(err != 0) || (itemlist == NULL)");
1096                 ad->maininfo.medias_cnt = 0;
1097                 ad->maininfo.medias_elist = NULL;
1098                 /* Clear list of selected ID */
1099                 if (sel_id_list) {
1100                         eina_list_free(sel_id_list);
1101                         sel_id_list = NULL;
1102                 }
1103
1104                 if (itemlist)
1105                         _gl_db_clear_mtype_items_list(&itemlist);
1106
1107                 return err;
1108         }
1109
1110         bool b_selected = false;
1111         Mitem *item = NULL;
1112         Eina_List *medias_elist = NULL;
1113         EINA_LIST_FREE(itemlist, item) {
1114                 if (item == NULL || item->uuid == NULL) {
1115                         gl_dbgE("Invalid item!");
1116                         continue;
1117                 }
1118                 gitem = _gl_db_new_item();
1119                 if (gitem == NULL) {
1120                         gl_dbgE("_gl_db_new_item failed!");
1121                         minfo_destroy_mtype_item(gitem);
1122                         continue;
1123                 }
1124                 gitem->ad = ad;
1125                 gitem->item = item;
1126                 /* Append item to medias_elist */
1127                 medias_elist = eina_list_append(ad->maininfo.medias_elist,
1128                                                 gitem);
1129                 ad->maininfo.medias_elist = medias_elist;
1130
1131                 if (sel_id_list) {
1132                         b_selected = _gl_db_check_selected_id(&sel_id_list,
1133                                                               item->uuid);
1134                         if (b_selected) {
1135                                 b_selected = false;
1136                                 /* Set checkbox state */
1137                                 gitem->checked = true;
1138                                 /* Append gitem to selected list */
1139                                 gl_db_selected_list_append(ad, gitem);
1140                         }
1141                 }
1142         }
1143
1144         /* Clear list of selected ID */
1145         if (sel_id_list)
1146                 __gl_db_free_selected_id_list(&sel_id_list);
1147
1148         ad->maininfo.medias_cnt = eina_list_count(ad->maininfo.medias_elist);
1149         gl_dbg("All medias count:%d.", ad->maininfo.medias_cnt);
1150         return err;
1151 }
1152
1153 int
1154 gl_db_get_first_several_items(gl_cluster * album,
1155         gl_item * items[], int *item_count,
1156         minfo_media_sort_type sort_type)
1157 {
1158         GL_CHECK_VAL(items, GL_DB_FAIL);
1159         GL_CHECK_VAL(item_count, GL_DB_FAIL);
1160         GL_CHECK_VAL(album, GL_DB_FAIL);
1161         GL_CHECK_VAL(album->cluster, GL_DB_FAIL);
1162         GL_CHECK_VAL(album->cluster->uuid, GL_DB_FAIL);
1163         GL_CHECK_VAL(album->ad, GL_DB_FAIL);
1164         gl_appdata *ad = (gl_appdata *)album->ad;
1165         minfo_item_filter filter;
1166         Eina_List *item_list = NULL;
1167         int result_cnt = 0;
1168         Mitem *item = NULL;
1169         gl_item *gitem = NULL;
1170         int err = -1;
1171
1172         if (*item_count <= 0)
1173         {
1174                 return 0;
1175         }
1176         memset(&filter,0x00,sizeof(minfo_item_filter));
1177         if (g_strcmp0(album->cluster->uuid, GL_ALBUM_ALL_ID) )  //real album
1178         {
1179                 filter.file_type = MINFO_ITEM_IMAGE | MINFO_ITEM_VIDEO;
1180                 filter.sort_type = sort_type;
1181                 filter.start_pos = GL_FIRST_VIEW_START_POS;
1182                 filter.end_pos = (*item_count == 1 ? 1 : (*item_count - 1));
1183                 filter.with_meta = false;
1184
1185                 err = minfo_get_item_list(ad->maininfo.db_handle,
1186                                                 album->cluster->uuid, filter,
1187                                                 _gl_db_elist_ite_fn, &item_list);
1188                 if (err != 0 || item_list == NULL) {
1189                         gl_dbgE("minfo_get_item_list failed : err=%d", err);
1190                         *item_count = 0;
1191                         if (item_list)
1192                                 _gl_db_clear_mtype_items_list(&item_list);
1193                         return GL_DB_FAIL;
1194                 }
1195
1196                 EINA_LIST_FREE(item_list, item) {
1197                         if (item == NULL) {
1198                                 gl_dbgE("Invalid Mitem!");
1199                                 continue;
1200                         }
1201                         result_cnt++;
1202                         if(result_cnt <= *item_count) {
1203                                 gitem = NULL;
1204                                 gitem = _gl_db_new_item();
1205                                 if (gitem == NULL) {
1206                                         gl_dbgE("_gl_db_new_item failed!");
1207                                         minfo_destroy_mtype_item(gitem);
1208                                         result_cnt--;
1209                                         continue;
1210                                 }
1211                                 gitem->item = item;
1212                                 gitem->ad = ad;
1213                                 items[result_cnt-1] = gitem;
1214                         } else {
1215                                 minfo_destroy_mtype_item(item);
1216                         }
1217                         item = NULL;
1218                 }
1219
1220                 if(*item_count > result_cnt)
1221                         *item_count = result_cnt;
1222         }
1223         else                    //add "All" album
1224         {
1225                 gl_dbg("db_get_item_list--all media\n");
1226                 filter.file_type = MINFO_ITEM_IMAGE | MINFO_ITEM_VIDEO;
1227                 filter.sort_type = sort_type;
1228
1229                 filter.start_pos = GL_FIRST_VIEW_START_POS;
1230                 filter.end_pos = (*item_count == 1 ? 1 : (*item_count - 1));
1231                 filter.with_meta = false;
1232
1233                 //use new api to get all local files, mmc status checking would be done in new apis
1234                 err = minfo_get_all_item_list(ad->maininfo.db_handle,
1235                                                         MINFO_CLUSTER_TYPE_LOCAL_ALL,
1236                                                         filter, _gl_db_elist_ite_fn,
1237                                                         &item_list);
1238                 if (err != 0 || item_list == NULL) {
1239                         gl_dbgE("minfo_get_item_list fails : err=%d", err);
1240                         *item_count = 0;
1241                         if (item_list)
1242                                 _gl_db_clear_mtype_items_list(&item_list);
1243
1244                         return GL_DB_FAIL;
1245                 }
1246
1247                 EINA_LIST_FREE(item_list, item) {
1248                         if (item == NULL) {
1249                                 gl_dbgE("Invalid Mitem!");
1250                                 continue;
1251                         }
1252                         result_cnt++;
1253                         if(result_cnt <= *item_count) {
1254                                 gitem = NULL;
1255                                 gitem = _gl_db_new_item();
1256                                 if (gitem == NULL) {
1257                                         gl_dbgE("_gl_db_new_item failed!");
1258                                         minfo_destroy_mtype_item(gitem);
1259                                         result_cnt--;
1260                                         continue;
1261                                 }
1262                                 gitem->item = item;
1263                                 gitem->ad = ad;
1264                                 items[result_cnt-1] = gitem;
1265                         } else {
1266                                 minfo_destroy_mtype_item(item);
1267                         }
1268                         item = NULL;
1269                 }
1270
1271                 if(*item_count > result_cnt)
1272                         *item_count = result_cnt;
1273         }
1274
1275         if (*item_count)
1276         {
1277                 gl_dbg("first %d items for this album(%s)",
1278                         *item_count, album->cluster->display_name);
1279         }
1280
1281         return GL_DB_SUCCESS;
1282 }
1283
1284 bool
1285 gl_db_is_item_cnt_zero(void *data, minfo_file_type type)
1286 {
1287         GL_CHECK_VAL(data, GL_DB_FAIL);
1288         gl_appdata *ad = (gl_appdata *)data;
1289         int i = 0;
1290         gl_item *gitem = NULL;
1291
1292         /* Get all medias count of current album */
1293         int all_cnt = ad->maininfo.medias_cnt;
1294         for (i = 1; i <= all_cnt; i++)
1295         {
1296                 gl_db_get_item_by_index(ad, i, false, &gitem);
1297                 if (gitem && gitem->item)
1298                 {
1299                         if (gitem->item->type == type)
1300                         {
1301                                 return false;
1302                         }
1303                 }
1304         }
1305
1306         gl_dbg(" item_cnt = 0 ");
1307         return true;
1308 }
1309
1310 int
1311 gl_db_destroy_item(gl_item * gitem)
1312 {
1313         GL_CHECK_VAL(gitem, GL_DB_FAIL);
1314         GL_CHECK_VAL(gitem->item, GL_DB_FAIL);
1315         _gl_db_destroy_item(gitem);
1316         return GL_DB_SUCCESS;
1317 }
1318
1319 /**
1320 * select_mode: true, get item from selected_media_elist; false, get item from media_elist.
1321 */
1322 int
1323 gl_db_get_item_by_index(void *data, int idx, bool select_mode, gl_item ** gitem)
1324 {
1325         GL_CHECK_VAL(data, GL_DB_FAIL);
1326         gl_appdata *ad = (gl_appdata *)data;
1327
1328         if (!select_mode) {
1329                 if (idx > ad->maininfo.medias_cnt) {
1330                         gl_dbg("db_get_item_by_index(%d) is failed, ad->maininfo.medias_cnt=%d\n",
1331                                 idx, ad->maininfo.medias_cnt);
1332                         *gitem = NULL;
1333                         return GL_DB_FAIL;
1334                 }
1335
1336                 *gitem = eina_list_nth(ad->maininfo.medias_elist, idx - 1);
1337         } else {
1338                 Eina_List *sel_list = ad->selectedinfo.medias_elist;
1339                 *gitem = (gl_item *) eina_list_nth(sel_list, --idx);
1340         }
1341         return GL_DB_SUCCESS;
1342 }
1343
1344 int
1345 gl_db_item_list_remove(void *data, gl_item * gitem)
1346 {
1347         GL_CHECK_VAL(gitem, GL_DB_FAIL);
1348         GL_CHECK_VAL(gitem->item, GL_DB_FAIL);
1349         GL_CHECK_VAL(gitem->item->uuid, GL_DB_FAIL);
1350         GL_CHECK_VAL(data, GL_DB_FAIL);
1351         gl_appdata *ad = (gl_appdata *)data;
1352         gl_item *current = NULL;
1353         Eina_List *l = NULL;
1354
1355         Eina_List *media_elist = ad->maininfo.medias_elist;
1356         EINA_LIST_FOREACH(media_elist, l, current)
1357         {
1358                 if (current == NULL || current->item == NULL ||
1359                     current->item->uuid == NULL) {
1360                         gl_dbgE("Invalid gitem!");
1361                         continue;
1362                 }
1363
1364                 if (!g_strcmp0(current->item->uuid, gitem->item->uuid))
1365                 {
1366                         ad->maininfo.medias_elist = eina_list_remove(ad->maininfo.medias_elist, current);
1367
1368                         ad->maininfo.medias_cnt--;
1369                         gl_db_destroy_item(current);
1370                         break;
1371                 }
1372                 current = NULL;
1373         }
1374
1375         return 0;
1376 }
1377
1378 /* Remove file from DB and file system */
1379 int gl_db_remove_item(gl_item * gitem)
1380 {
1381         GL_CHECK_VAL(gitem, GL_DB_FAIL);
1382         GL_CHECK_VAL(gitem->item, GL_DB_FAIL);
1383         GL_CHECK_VAL(gitem->item->uuid, GL_DB_FAIL);
1384         GL_CHECK_VAL(gitem->ad, GL_DB_FAIL);
1385         gl_appdata *ad = (gl_appdata *)gitem->ad;
1386         int ret = -1;
1387
1388         if (!gitem->item->file_url) {
1389                 gl_dbgW("Invalid file_url!");
1390                 ret = minfo_delete_media_id(ad->maininfo.db_handle, gitem->item->uuid);
1391                 if (ret != 0) {
1392                         gl_dbgE("minfo_delete_media_id failed[%d]!", ret);
1393                         return GL_DB_FAIL;
1394                 } else {
1395                         return GL_DB_SUCCESS;
1396                 }
1397         }
1398         gl_dbg("Remove file: %s.", gitem->item->file_url);
1399         /* Delete record from DB then delete media from file system */
1400         ret = minfo_delete_media(ad->maininfo.db_handle, gitem->item->file_url);
1401         if (ret != 0) {
1402                 gl_dbgE("minfo_delete_media failed[%d]!", ret);
1403                 return GL_DB_FAIL;
1404         }
1405
1406         if (!ecore_file_unlink(gitem->item->file_url)) {
1407                 gl_dbgE("ecore_file_unlink failed!");
1408                 return GL_DB_FAIL;
1409         }
1410         return GL_DB_SUCCESS;
1411 }
1412
1413 /* Append gl_item to medias_elist */
1414 int
1415 gl_db_append_item(void *data, gl_item * gitem)
1416 {
1417         GL_CHECK_VAL(gitem, GL_DB_FAIL);
1418         GL_CHECK_VAL(gitem->item, GL_DB_FAIL);
1419         GL_CHECK_VAL(data, GL_DB_FAIL);
1420         gl_appdata *ad = (gl_appdata *)data;
1421
1422         gitem->ad = ad;
1423         ad->maininfo.medias_elist = eina_list_append(ad->maininfo.medias_elist, gitem);
1424         ad->maininfo.medias_cnt++;
1425
1426         return 0;
1427 }
1428
1429 gl_item *
1430 gl_db_selected_list_get_nth(void *data, int idx)
1431 {
1432         GL_CHECK_NULL(data);
1433         gl_appdata *ad = (gl_appdata *)data;
1434
1435         return eina_list_nth(ad->selectedinfo.medias_elist, idx);
1436 }
1437
1438 int
1439 gl_db_selected_list_append(void *data, gl_item * gitem)
1440 {
1441         GL_CHECK_VAL(gitem, GL_DB_FAIL);
1442         GL_CHECK_VAL(gitem->item, GL_DB_FAIL);
1443         GL_CHECK_VAL(data, GL_DB_FAIL);
1444         gl_appdata *ad = (gl_appdata *)data;
1445
1446         /* Update selected images count */
1447         if (gitem->item->type == MINFO_ITEM_IMAGE)
1448                 ad->selectedinfo.images_cnt++;
1449
1450         Eina_List *sel_list = ad->selectedinfo.medias_elist;
1451         sel_list = eina_list_append(sel_list, gitem);
1452         ad->selectedinfo.medias_elist = sel_list;
1453         return GL_DB_SUCCESS;
1454 }
1455
1456 int
1457 gl_db_selected_list_remove(void *data, gl_item * gitem)
1458 {
1459         GL_CHECK_VAL(gitem, GL_DB_FAIL);
1460         GL_CHECK_VAL(gitem->item, GL_DB_FAIL);
1461         GL_CHECK_VAL(gitem->item->uuid, GL_DB_FAIL);
1462         GL_CHECK_VAL(data, GL_DB_FAIL);
1463         gl_appdata *ad = (gl_appdata *)data;
1464         gl_item *current = NULL;
1465         Eina_List *l = NULL;
1466
1467         Eina_List *sel_list = ad->selectedinfo.medias_elist;
1468         EINA_LIST_FOREACH(sel_list, l, current) {
1469                 if (current == NULL || current->item == NULL ||
1470                     current->item->uuid == NULL) {
1471                         gl_dbgE("Invalid gitem!");
1472                         continue;
1473                 }
1474                 if (!g_strcmp0(current->item->uuid, gitem->item->uuid)) {
1475                         /* Update selected images count */
1476                         if (current->item->type == MINFO_ITEM_IMAGE &&
1477                             ad->selectedinfo.images_cnt > 0)
1478                                 ad->selectedinfo.images_cnt--;
1479
1480                         sel_list = eina_list_remove(sel_list, current);
1481                         ad->selectedinfo.medias_elist = sel_list;
1482                         break;
1483                 }
1484                 current = NULL;
1485         }
1486         return GL_DB_SUCCESS;
1487 }
1488
1489 int
1490 gl_db_selected_list_finalize(void *data)
1491 {
1492         GL_CHECK_VAL(data, GL_DB_FAIL);
1493         gl_appdata *ad = (gl_appdata *)data;
1494         gl_item *gitem = NULL;
1495
1496         Eina_List *sel_list = ad->selectedinfo.medias_elist;
1497         EINA_LIST_FREE(sel_list, gitem) {
1498                 if (gitem)
1499                         gitem->checked = false;
1500         }
1501
1502         ad->selectedinfo.medias_elist = NULL;
1503         ad->selectedinfo.images_cnt = 0;
1504         return GL_DB_SUCCESS;
1505 }
1506
1507 int
1508 gl_db_selected_list_count(void *data)
1509 {
1510         GL_CHECK_VAL(data, GL_DB_FAIL);
1511         gl_appdata *ad = (gl_appdata *)data;
1512
1513         return eina_list_count(ad->selectedinfo.medias_elist);
1514 }
1515
1516 /*
1517 *   get full path of cluster
1518 */
1519 int gl_db_get_folder_fullpath(void *data, const char *cluster_id, char *path)
1520 {
1521         GL_CHECK_VAL(path, GL_DB_FAIL);
1522         GL_CHECK_VAL(cluster_id, GL_DB_FAIL);
1523         GL_CHECK_VAL(data, GL_DB_FAIL);
1524         gl_appdata *ad = (gl_appdata *)data;
1525         /*For safety, add one more parameter as a size of the output array */
1526         return minfo_get_cluster_fullpath_by_id(ad->maininfo.db_handle,
1527                                                 cluster_id, path, GL_DIR_PATH_LEN_MAX);
1528 }
1529
1530 /*
1531 *   Check it's default album[Camera shot] or not
1532 */
1533 bool
1534 gl_db_is_default_album(void *data, Mcluster* mcluster)
1535 {
1536         GL_CHECK_FALSE(mcluster);
1537         GL_CHECK_FALSE(mcluster->display_name);
1538         GL_CHECK_FALSE(mcluster->uuid);
1539
1540         /* Name is 'Camera shot and' folder locates in Phone */
1541         if (!strcmp(mcluster->display_name, GL_ALBUM_DEFAULT_NAME) &&
1542                 mcluster->type == MINFO_PHONE)
1543         {
1544                 char dir_path[GL_DIR_PATH_LEN_MAX] = { 0, };
1545                 char parent_path[GL_DIR_PATH_LEN_MAX] = { 0, };
1546
1547                 int ret = gl_db_get_folder_fullpath(data, mcluster->uuid, dir_path);
1548                 if(ret != 0)
1549                 {
1550                         gl_dbgE("gl_db_get_folder_fullpath failed[%d]!", ret);
1551                         return false;
1552                 }
1553                 gl_dbg("Full path: %s", dir_path);
1554
1555                 _gl_db_get_file_dir_names(dir_path, NULL, NULL, parent_path);
1556                 gl_dbg("Parent path: %s.", parent_path);
1557
1558                 /* And parent folder is Phone root path, it's default folder */
1559                 return (strcmp(parent_path, GL_ROOT_PATH_PHONE) == 0);
1560         }
1561
1562         return false;
1563 }
1564
1565 bool gl_db_is_root_path(void *data, const char *cluster_id, const char *path)
1566 {
1567         int res = 0;
1568         char dir_path[GL_DIR_PATH_LEN_MAX] = { 0, };
1569
1570         if (path)
1571         {
1572                 g_strlcpy(dir_path, path, GL_DIR_PATH_LEN_MAX);
1573         }
1574         else
1575         {
1576                 if (cluster_id == NULL || strlen(cluster_id) <= 0) {
1577                         gl_dbgE("Invalid cluster_id!");
1578                         return false;
1579                 }
1580                 res = gl_db_get_folder_fullpath(data, cluster_id, dir_path);
1581                 if (res < 0)
1582                 {
1583                         gl_dbg("get folder fullpath failed(%d), return!", res);
1584                         return false;
1585                 }
1586         }
1587
1588         if (!g_strcmp0(GL_ROOT_PATH_PHONE, dir_path) ||
1589             !g_strcmp0(GL_ROOT_PATH_MMC, dir_path)) {
1590                 gl_dbg("Root path: %s.", dir_path);
1591                 return true;
1592         }
1593
1594         return false;
1595 }
1596
1597 int
1598 gl_db_get_albums_selected_cnt(void *data)
1599 {
1600         GL_CHECK_VAL(data, GL_DB_FAIL);
1601         gl_appdata *ad = (gl_appdata *)data;
1602
1603         return eina_list_count(ad->albuminfo.selected_albums_elist);
1604 }
1605
1606 int
1607 gl_db_albums_selected_list_append(void *data, gl_cluster * item)
1608 {
1609         GL_CHECK_VAL(item, GL_DB_FAIL);
1610         GL_CHECK_VAL(item->cluster, GL_DB_FAIL);
1611         GL_CHECK_VAL(data, GL_DB_FAIL);
1612         gl_appdata *ad = (gl_appdata *)data;
1613         ad->albuminfo.selected_albums_elist = eina_list_append(ad->albuminfo.selected_albums_elist, item);
1614
1615         return GL_DB_SUCCESS;
1616 }
1617
1618 int
1619 gl_db_albums_selected_list_remove(void *data, gl_cluster * item)
1620 {
1621         GL_CHECK_VAL(item, GL_DB_FAIL);
1622         GL_CHECK_VAL(item->cluster, GL_DB_FAIL);
1623         GL_CHECK_VAL(item->cluster->uuid, GL_DB_FAIL);
1624         GL_CHECK_VAL(data, GL_DB_FAIL);
1625         gl_appdata *ad = (gl_appdata *)data;
1626         gl_cluster *current = NULL;
1627         Eina_List *l = NULL;
1628
1629         Eina_List *sel_list = ad->albuminfo.selected_albums_elist;
1630         EINA_LIST_FOREACH(sel_list, l, current)
1631         {
1632                 if (current == NULL || current->cluster == NULL ||
1633                     current->cluster->uuid == NULL) {
1634                         gl_dbgE("Invalid gcluster!");
1635                         continue;
1636                 }
1637
1638                 if (!g_strcmp0(current->cluster->uuid, item->cluster->uuid))
1639                 {
1640                         ad->albuminfo.selected_albums_elist = eina_list_remove(ad->albuminfo.selected_albums_elist, current);
1641                         break;
1642                 }
1643                 current = NULL;
1644         }
1645
1646         return GL_DB_SUCCESS;
1647 }
1648
1649 int
1650 gl_db_finalize_albums_selected_list(void *data)
1651 {
1652         GL_CHECK_VAL(data, GL_DB_FAIL);
1653         gl_appdata *ad = (gl_appdata *)data;
1654         gl_cluster *item = NULL;
1655
1656         Eina_List *sel_list = ad->albuminfo.selected_albums_elist;
1657         EINA_LIST_FREE(sel_list, item)
1658         {
1659                 if (item)
1660                         item->checked = false;
1661         }
1662
1663         ad->albuminfo.selected_albums_elist = NULL;
1664         return GL_DB_SUCCESS;
1665 }
1666
1667 bool
1668 gl_db_is_albums_selected_list_empty(void *data)
1669 {
1670         GL_CHECK_VAL(data, GL_DB_FAIL);
1671         gl_appdata *ad = (gl_appdata *)data;
1672         gl_cluster *current = NULL;
1673         Eina_List *l = NULL;
1674
1675         Eina_List *sel_list = ad->albuminfo.selected_albums_elist;
1676         EINA_LIST_FOREACH(sel_list, l, current)
1677         {
1678                 if (current == NULL || current->cluster == NULL)
1679                 {
1680                         continue;
1681                 }
1682                 else
1683                 {
1684                         if (current->cluster->count)
1685                         {
1686                                 return false;
1687                         }
1688                 }
1689         }
1690
1691         return true;
1692 }
1693
1694 int
1695 gl_db_init(void *data)
1696 {
1697         GL_CHECK_VAL(data, GL_DB_FAIL);
1698         gl_appdata *ad = (gl_appdata *)data;
1699         MediaSvcHandle *_db_handle = NULL;
1700
1701         int err = media_svc_connect(&_db_handle);
1702         if (err < 0) {
1703                 gl_dbgE("Connect to DB failed!");
1704                 return GL_DB_FAIL;
1705         }
1706
1707         ad->maininfo.db_handle = _db_handle;
1708         return GL_DB_SUCCESS;
1709 }
1710
1711 int
1712 gl_db_finalize(void *data)
1713 {
1714         GL_CHECK_VAL(data, GL_DB_FAIL);
1715         gl_appdata *ad = (gl_appdata *)data;
1716
1717         _gl_db_clear_cluster_list(ad, true);
1718         _gl_db_clear_item_list(ad);
1719
1720         int err = media_svc_disconnect(ad->maininfo.db_handle);
1721         if (err < 0) {
1722                 gl_dbgE("Disconnect with DB failed!");
1723                 return GL_DB_FAIL;
1724         }
1725
1726         return GL_DB_SUCCESS;
1727 }