More generic use of event.
[familia.git] / src / storage / storage.c
1 #include <stdio.h>
2 #include <stdlib.h>
3
4 #include "storage.h"
5
6 #include "../debug.h"
7
8 struct familia_storage * _familia_storage_current;
9
10 extern void _familia_storage_positions_init();
11 extern void _familia_storage_positions_free();
12
13 struct familia_storage * familia_storage_get_current()
14 {
15         return _familia_storage_current;
16 }
17
18 void familia_storage_set_current(struct familia_storage * storage)
19 {
20         _familia_storage_current = storage;
21 }
22
23 struct familia_storage * familia_storage_new()
24 {
25         struct familia_storage * storage = NULL;
26         storage = malloc(sizeof(struct familia_storage));
27
28         if (!storage) {
29                 debug("["__FILE__ "] There was a problem with allocating memory for storage.\n");
30                 return NULL;
31         }
32
33         storage->individuals = NULL;
34         storage->individuals_no = 0;
35         storage->families = NULL;
36         storage->families_no = 0;
37
38 /*      _familia_storage_positions_init();*/
39
40         return storage;
41 }
42
43 void familia_storage_free(struct familia_storage * storage)
44 {
45         unsigned int i = 0;
46
47         if (storage->individuals_no) {
48                 for (i = 0; i < storage->individuals_no; i++) {
49                         familia_individual_free(storage->individuals[i]);
50                         storage->individuals[i] = NULL;
51                 }
52                 free(storage->individuals);
53                 storage->individuals = NULL;
54                 storage->individuals_no = 0;
55         }
56
57         if (storage->families_no) {
58                 for (i = 0; i < storage->families_no; i++) {
59                         familia_family_free(storage->families[i]);
60                         storage->families[i] = NULL;
61                 }
62                 free(storage->families);
63                 storage->families = NULL;
64                 storage->families_no = 0;
65         }
66
67 /*      _familia_storage_positions_free();*/
68 }
69
70 void familia_storage_add_individual(struct familia_storage * storage, struct familia_individual * individual)
71 {
72         struct familia_individual ** tmp = NULL;
73         int size = (storage->individuals_no + 1);
74
75         if (individual) {
76                 tmp = realloc(storage->individuals, size * sizeof(struct familia_individual *));
77                 
78                 if (tmp) {
79                         individual->id = storage->individuals_no;
80                         storage->individuals = tmp;
81                         storage->individuals[storage->individuals_no] = individual;
82                         storage->individuals_no++;
83                 }
84                 else {
85                         debug("["__FILE__ "] There were problems with allocating memory for individual.\n");
86                 }
87         }
88 }
89
90 struct familia_individual * familia_storage_get_individual_by_id(struct familia_storage * storage, unsigned int id)
91 {
92         if (storage->individuals_no < id) {
93                 debug("["__FILE__ "Trying to get not existing individual!\n");
94                 return NULL;
95         }
96         return storage->individuals[id];
97 }
98
99 void familia_storage_remove_individual_by_id(struct familia_storage * storage, unsigned int id)
100 {
101         unsigned int i = 0;
102         int found = 0;
103         struct familia_individual ** tmp = NULL;
104         
105         if (storage->individuals_no < id) {
106                 debug("["__FILE__ "] Trying to remove not existing individual!\n");
107                 return;
108         }
109
110         for (i = 0; i < storage->individuals_no; i++) {
111                 if (storage->individuals[i]->id == id) {
112                         found = 1;
113                         familia_individual_free(storage->individuals[i]);
114                         storage->individuals[i] = NULL;
115                 }
116
117                 /*
118                  * If family has been found, reorder rest of files to avoid
119                  * NULL pointers inside array.
120                  */
121                 if (found && (i < storage->individuals_no - 1)) {
122                         storage->individuals[i] = storage->individuals[i + 1];
123                 }
124         }
125         
126         if (found) {
127                 tmp = realloc(storage->individuals,
128                         (storage->families_no) * sizeof(struct familia_family *));
129
130                 if (tmp) {
131                         storage->individuals = tmp;
132                 }
133                 storage->individuals_no--;
134         }
135 }
136
137 void familia_storage_add_family(struct familia_storage * storage, struct familia_family * family)
138 {
139         struct familia_family ** tmp = NULL;
140         int size = (storage->families_no + 1);
141
142         if (family) {
143                 tmp = realloc(storage->families, size * sizeof(struct familia_family *));
144                 
145                 if (tmp) {
146                         family->id = storage->families_no;
147                         storage->families = tmp;
148                         storage->families[storage->families_no] = family;
149                         storage->families_no++;
150                 }
151                 else {
152                         debug("["__FILE__ "] There were problems with allocating memory for family.\n");
153                 }
154         }
155 }
156
157 struct familia_family * familia_storage_get_family_by_id(struct familia_storage * storage, unsigned int id)
158 {
159         if (storage->families_no < id) {
160                 debug("["__FILE__ "Trying to get not existing family!\n");
161                 return NULL;
162         }
163         return storage->families[id];
164 }
165
166 void familia_storage_remove_family_by_id(struct familia_storage * storage, unsigned int id)
167 {
168         unsigned int i = 0;
169         int found = 0;
170         struct familia_family ** tmp = NULL;
171         
172         if (storage->families_no < id) {
173                 debug("["__FILE__ "] Trying to remove not existing family!\n");
174                 return;
175         }
176
177         for (i = 0; i < storage->families_no; i++) {
178                 if (storage->families[i]->id == id) {
179                         found = 1;
180                         familia_family_free(storage->families[i]);
181                         storage->families[i] = NULL;
182                 }
183
184                 /*
185                  * If family has been found, reorder rest of files to avoid
186                  * NULL pointers inside array.
187                  */
188                 if (found && (i < storage->families_no - 1)) {
189                         storage->families[i] = storage->families[i + 1];
190                 }
191         }
192         
193         if (found) {
194                 tmp = realloc(storage->families,
195                         (storage->families_no) * sizeof(struct familia_family *));
196
197                 if (tmp) {
198                         storage->families = tmp;
199                 }
200                 storage->families_no--;
201         }
202 }
203
204 void familia_storage_dump_all()
205 {
206         unsigned int i;
207         struct familia_storage * storage = NULL;
208         struct familia_family * family = NULL;
209         struct familia_individual * individual = NULL;
210         struct familia_individual * i1 = NULL;
211         struct familia_individual * i2 = NULL;
212         
213         storage = familia_storage_get_current();
214         
215         for (i = 0; i < storage->individuals_no; i++) {
216                 struct familia_family * f = NULL;
217
218                 individual = storage->individuals[i];
219
220                 printf("Individual (%d)\n", individual->id);
221                 printf("\t First name: %s\n", individual->first_name);
222                 printf("\t Last name: %s\n", individual->last_name);
223
224                 if (individual->families_no > 0) {
225                         unsigned int j;
226
227                         printf("\t Families:\n");
228                         for (j = 0; j < individual->families_no; j++) {
229                                 f = individual->families[j];
230                                 i1 = familia_family_get_parent(f, Individual1);
231                                 i2 = familia_family_get_parent(f, Individual2);
232                                 
233                                 printf("\t > %s&%s\n",
234                                         i1 ? familia_individual_get_first_name(i1) : "NULL",
235                                         i2 ? familia_individual_get_first_name(i2) : "NULL");
236                         }
237                 }
238
239                 printf("\t Parents:\n");
240                 f = NULL;
241                 f = familia_individual_get_parents(individual);
242
243                 if (f) {
244                         i1 = familia_family_get_parent(f, Individual1);
245                         i2 = familia_family_get_parent(f, Individual2);
246                 
247                         printf("\t > %s&%s\n",
248                                 i1 ? familia_individual_get_first_name(i1) : "NULL",
249                                 i2 ? familia_individual_get_first_name(i2) : "NULL");
250                 }
251                 else {
252                         printf("\t (none)\n");
253                 }
254         }
255
256
257         for (i = 0; i < storage->families_no; i++) {
258                 unsigned int j;
259
260                 family = storage->families[i];
261
262                 printf("Family (%d)\n", family->id);
263                 i1 = familia_family_get_parent(family, Individual1);
264                 printf("\t First parent: %s\n", i1 ? familia_individual_get_first_name(i1) : "NULL");
265
266                 i2 = familia_family_get_parent(family, Individual2);
267                 printf("\t Second parent: %s\n", i2 ? familia_individual_get_first_name(i2) : "NULL");
268
269                 printf("\t Children:\n");
270                 if (family->children_no > 0) {
271                         for (j = 0; j < family->children_no; j++) {
272                                 i1 = family->children[j];
273                                 printf("\t > %s\n", i1 ? familia_individual_get_first_name(i1) : "NULL");
274                         }
275                 }
276         }
277 }