Added box-merge option for pnd_container, and added ability for mmenu to scan both
[pandora-libraries.git] / minimenu / mmcat.c
1
2 #include <string.h>
3 #include <strings.h>
4 #include <stdlib.h>
5
6 #include "pnd_conf.h"
7 #include "pnd_logger.h"
8 #include "pnd_pxml.h"
9 #include "pnd_container.h"
10 #include "pnd_discovery.h"
11
12 #include "mmenu.h"
13 #include "mmcache.h"
14 #include "mmcat.h"
15
16 mm_category_t g_categories [ MAX_CATS ];
17 unsigned char g_categorycount = 0;
18
19 unsigned char category_push ( char *catname, pnd_disco_t *app ) {
20   mm_category_t *c;
21
22   // check category list; if found, append app to the end of it.
23   // if not found, add it to the category list and plop the app in there.
24   // app's are just app-refs, which contain links to the disco-t list -- thus removal is only in one place, and
25   // an app can be in multiple categories if we like..
26   //
27
28   // find or create category
29   //
30
31   if ( ( c = category_query ( catname ) ) ) {
32     // category was found..
33   } else {
34     // category wasn't found..
35     pnd_log ( PND_LOG_DEFAULT, "New category '%s'\n", catname );
36     g_categories [ g_categorycount ].catname = strdup ( catname );
37     g_categories [ g_categorycount ].refs = NULL;
38     c = &(g_categories [ g_categorycount ]);
39     g_categorycount++;
40   }
41
42   // alloc and populate appref
43   //
44   mm_appref_t *ar = malloc ( sizeof(mm_appref_t) );
45   if ( ! ar ) {
46     return ( 0 );
47   }
48
49   bzero ( ar, sizeof(mm_appref_t) );
50
51   ar -> ref = app;
52
53   // plug it into category
54   //   and sort it on insert!
55 #if 0 // no sorting
56   ar -> next = c -> refs;
57   c -> refs = ar;
58 #else // with sorting
59   // if no refs at all, or new guy has no title, just stick it in at head
60   if ( c -> refs && ar -> ref -> title_en ) {
61     mm_appref_t *iter = c -> refs;
62     mm_appref_t *last = NULL;
63
64     while ( iter ) {
65
66       if ( iter -> ref -> title_en ) {
67         if ( strcmp ( ar -> ref -> title_en, iter -> ref -> title_en ) < 0 ) {
68           // new guy is smaller than the current guy!
69           break;
70         }
71       } else {
72         // since new guy must have a name by here, we're bigger than any guy who does not have a name
73         // --> continue
74       }
75
76       last = iter;
77       iter = iter -> next;
78     }
79
80     if ( iter ) {
81       // smaller than the current guy, so stitch in
82       if ( last ) {
83         ar -> next = iter;
84         last -> next = ar;
85       } else {
86         ar -> next = c -> refs;
87         c -> refs = ar;
88       }
89     } else {
90       // we're the biggest, just append to last
91       last -> next = ar;
92     }
93
94   } else {
95     ar -> next = c -> refs;
96     c -> refs = ar;
97   }
98 #endif
99   c -> refcount++;
100
101   return ( 1 );
102 }
103
104 mm_category_t *category_query ( char *catname ) {
105   unsigned char i;
106
107   for ( i = 0; i < g_categorycount; i++ ) {
108
109     if ( strcasecmp ( g_categories [ i ].catname, catname ) == 0 ) {
110       return ( &(g_categories [ i ]) );
111     }
112
113   }
114
115   return ( NULL );
116 }
117
118 void category_dump ( void ) {
119   unsigned int i;
120
121   // WHY AREN'T I SORTING ON INSERT?
122
123   // dump
124   for ( i = 0; i < g_categorycount; i++ ) {
125     pnd_log ( PND_LOG_DEFAULT, "Category %u: '%s' * %u\n", i, g_categories [ i ].catname, g_categories [ i ].refcount );
126     mm_appref_t *ar = g_categories [ i ].refs;
127
128     while ( ar ) {
129       pnd_log ( PND_LOG_DEFAULT, "  Appref %s\n", IFNULL(ar -> ref -> title_en,"No Name") );
130       ar = ar -> next;
131     }
132
133   } // for
134
135   return;
136 }
137
138 void category_freeall ( void ) {
139   unsigned int i;
140   mm_appref_t *iter, *next;
141
142   for ( i = 0; i < g_categorycount; i++ ) {
143
144     iter = g_categories [ i ].refs;
145
146     while ( iter ) {
147       next = iter -> next;
148       free ( iter );
149       iter = next;
150     }
151
152     g_categories [ i ].refs = NULL;
153
154   } // for
155
156   g_categorycount = 0;
157
158   return;
159 }