Added parents to the individual structure and children to family structure.
[familia.git] / src / storage / individual.c
1 #include <stdlib.h>
2 #include <string.h>
3
4 #include "individual.h"
5
6 #include "../debug.h"
7
8 struct familia_individual * familia_individual_new()
9 {
10         struct familia_individual * individual = NULL;
11         individual = malloc(sizeof(struct familia_individual));
12
13         if (!individual) {
14                 debug("["__FILE__ "] There was a problem with allocating memory for individual.\n");
15                 return NULL;
16         }
17
18         individual->id = 0;
19         individual->first_name = NULL;
20         individual->last_name = NULL;
21         individual->families = NULL;
22         individual->families_no = 0;
23
24         return individual;
25 }
26
27 void familia_individual_free(struct familia_individual * individual)
28 {
29         unsigned int i = 0;
30
31         if (individual->first_name) {
32                 free(individual->first_name);
33                 individual->first_name = NULL;
34         }
35
36         if (individual->last_name) {
37                 free(individual->last_name);
38                 individual->last_name = NULL;
39         }
40
41         if (individual->families) {
42                 /* Remove all family links. */
43                 for (i = 0; i < individual->families_no; i++) {
44                         individual->families[i] = NULL;
45                 }
46                 free(individual->families);
47                 individual->families = NULL;
48                 individual->families_no = 0;
49         }
50
51         free(individual);
52 }
53
54 void familia_individual_set_first_name(struct familia_individual * individual, char * first_name)
55 {
56         /* Remove old data if it exists */
57         if (individual->first_name) {
58                 free(individual->first_name);
59         }
60
61         individual->first_name = malloc(strlen(first_name) + 1);
62
63         /*
64          * Malloc could return null on allocation failure.
65          * Check if memory is allocated correctly and copy string.
66          */
67         if (individual->first_name) {
68                 strcpy(individual->first_name, first_name);
69         }
70         else {
71                 debug("There were problems with allocating memory for individual first name.\n");
72         }
73 }
74
75 char * familia_individual_get_first_name(struct familia_individual * individual)
76 {
77         return individual->first_name;
78 }
79
80 void familia_individual_set_last_name(struct familia_individual * individual, char * last_name)
81 {
82         /* Remove old data if it exists */
83         if (individual->last_name) {
84                 free(individual->last_name);
85         }
86         
87         if (last_name == NULL) {
88                 debug ("IS NULL");
89         }
90
91         individual->last_name = malloc(strlen(last_name) + 1);
92
93         /*
94          * Malloc returns NULL on allocation failure.
95          * Check if memory is allocated correctly and copy string.
96          */
97         if (individual->last_name) {
98                 strncpy(individual->last_name, last_name, strlen(last_name));
99         }
100         else {
101                 debug("There were problems with allocating memory for individual last name.\n");
102         }
103 }
104
105 char * familia_individual_get_last_name(struct familia_individual * individual)
106 {
107         return individual->last_name;
108 }
109
110 void familia_individual_add_family(struct familia_individual * individual, struct familia_family * family)
111 {
112         struct familia_family ** tmp = NULL;
113         int size = (individual->families_no + 1);
114
115         tmp = realloc(individual->families, size * sizeof(struct familia_family *));
116
117         if (tmp) {
118                 individual->families = tmp;
119                 individual->families[individual->families_no] = family;
120                 individual->families_no++;
121         }
122         else {
123                 debug("There were problems with allocating memory for family.\n");
124         }
125
126 }
127
128 struct familia_family * familia_individual_get_family_by_id(struct familia_individual * individual, unsigned int id)
129 {
130         if (individual->families_no < id) {
131                 debug("Trying to get not existing family!\n");
132                 return NULL;
133         }
134         return individual->families[id];
135 }
136
137 void familia_individual_remove_family_by_id(struct familia_individual * individual, unsigned int id)
138 {
139         unsigned int i = 0;
140         int found = 0;
141         struct familia_family ** tmp = NULL;
142         
143         if (individual->families_no < id) {
144                 debug("Trying to remove not existing family!\n");
145                 return;
146         }
147
148         for (i = 0; i < individual->families_no; i++) {
149                 if (individual->families[i]->id == id) {
150                         found = 1;
151                         individual->families[i] = NULL;
152                 }
153
154                 /*
155                  * If family has been found, reorder rest of files to avoid
156                  * NULL pointers inside array.
157                  */
158                 if (found && (i < individual->families_no - 1)) {
159                         individual->families[i] = individual->families[i + 1];
160                 }
161         }
162         
163         if (found) {
164                 tmp = realloc(individual->families,
165                         (individual->families_no) * sizeof(struct familia_family *));
166
167                 if (tmp) {
168                         individual->families = tmp;
169                 }
170                 individual->families_no--;
171         }
172 }
173
174 void familia_individual_set_parents(struct familia_individual * individual, struct familia_family * family)
175 {
176         individual->parents = family;
177 }
178
179 struct familia_family * familia_individual_get_parents(struct familia_individual * individual)
180 {
181         return individual->parents;
182 }
183
184 void familia_individual_remove_parents(struct familia_individual * individual)
185 {
186         individual->parents = NULL;
187 }