Moved update_date and update_time to change_date.c
[gedcom-parse.git] / gom / change_date.c
1 /* Change date sub-structure in the gedcom object model.
2    Copyright (C) 2002 The Genes Development Team
3    This file is part of the Gedcom parser library.
4    Contributed by Peter Verthez <Peter.Verthez@advalvas.be>, 2002.
5
6    The Gedcom parser library is free software; you can redistribute it
7    and/or modify it under the terms of the GNU Lesser General Public
8    License as published by the Free Software Foundation; either
9    version 2.1 of the License, or (at your option) any later version.
10
11    The Gedcom parser library is distributed in the hope that it will be
12    useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
13    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14    Lesser General Public License for more details.
15
16    You should have received a copy of the GNU Lesser General Public
17    License along with the Gedcom parser library; if not, write to the
18    Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
19    02111-1307 USA.  */
20
21 /* $Id$ */
22 /* $Name$ */
23
24 #include <stdlib.h>
25 #include <string.h>
26 #include <time.h>
27 #include "change_date.h"
28 #include "family.h"
29 #include "individual.h"
30 #include "note_sub.h"
31 #include "multimedia.h"
32 #include "note.h"
33 #include "repository.h"
34 #include "source.h"
35 #include "submitter.h"
36 #include "user_rec.h"
37 #include "gom_internal.h"
38 #include "gom.h"
39 #include "gedcom.h"
40
41 Gedcom_ctxt sub_chan_start(_ELT_PARAMS_)
42 {
43   Gom_ctxt ctxt = (Gom_ctxt)parent;
44   Gom_ctxt result = NULL;
45
46   if (! ctxt)
47     NO_CONTEXT;
48   else {
49     struct change_date *chan
50       = (struct change_date *)malloc(sizeof(struct change_date));
51     if (! chan)
52       MEMORY_ERROR;
53     else {
54       memset (chan, 0, sizeof(struct change_date));
55       
56       switch (ctxt->ctxt_type) {
57         case REC_FAM:
58           ADDFUNC2_NOLIST(family,change_date)(ctxt, chan); break;
59         case REC_INDI:
60           ADDFUNC2_NOLIST(individual,change_date)(ctxt, chan); break;
61         case REC_OBJE:
62           ADDFUNC2_NOLIST(multimedia,change_date)(ctxt, chan); break;
63         case REC_NOTE:
64           ADDFUNC2_NOLIST(note,change_date)(ctxt, chan); break;
65         case REC_REPO:
66           ADDFUNC2_NOLIST(repository,change_date)(ctxt, chan); break;
67         case REC_SOUR:
68           ADDFUNC2_NOLIST(source,change_date)(ctxt, chan); break;
69         case REC_SUBM:
70           ADDFUNC2_NOLIST(submitter,change_date)(ctxt, chan); break;
71         default:
72           UNEXPECTED_CONTEXT(ctxt->ctxt_type);
73       }
74       result = MAKE_GOM_CTXT(elt, change_date, chan);
75     }
76   }
77   
78   return (Gedcom_ctxt)result;
79 }
80
81 DEFINE_DATE_CB(change_date, sub_chan_date_start, date)
82 DEFINE_STRING_CB(change_date, sub_chan_time_start, time)
83
84 DEFINE_ADDFUNC2(change_date, note_sub, note)
85 DEFINE_ADDFUNC2(change_date, user_data, extra)
86
87 void change_date_subscribe()
88 {
89   gedcom_subscribe_to_element(ELT_SUB_CHAN, sub_chan_start, def_elt_end);
90   gedcom_subscribe_to_element(ELT_SUB_CHAN_DATE, sub_chan_date_start,
91                               def_elt_end);
92   gedcom_subscribe_to_element(ELT_SUB_CHAN_TIME, sub_chan_time_start,
93                               def_elt_end);
94 }
95
96 void CLEANFUNC(change_date)(struct change_date *chan)
97 {
98   if (chan) {
99     SAFE_FREE(chan->date);
100     SAFE_FREE(chan->time);
101     DESTROY_CHAIN_ELTS(note_sub, chan->note);
102     DESTROY_CHAIN_ELTS(user_data, chan->extra);
103   }
104   SAFE_FREE(chan);
105 }
106
107 struct change_date* gom_add_change_date(struct change_date** chan)
108 {
109   struct change_date *obj = NULL;
110   if (chan && ! *chan) {
111     obj = (struct change_date*) malloc(sizeof(struct change_date));
112     if (! obj)
113       MEMORY_ERROR;
114     else {
115       memset(obj, 0, sizeof(struct change_date));
116       *chan = obj;
117     }
118   }
119   return obj;
120 }
121
122 int gom_delete_change_date(struct change_date** chan)
123 {
124   int result = 1;
125   if (chan && *chan) {
126     CLEANFUNC(change_date)(*chan);
127     free(*chan);
128     *chan = NULL;
129     result = 0;
130   }
131   return result;
132 }
133
134 int update_date(struct date_value** dv, struct tm* tm_ptr)
135 {
136   int result;
137   struct date_value* dval = gedcom_new_date_value(NULL);
138   dval->type        = DV_NO_MODIFIER;
139   dval->date1.cal   = CAL_GREGORIAN;
140   dval->date1.day   = tm_ptr->tm_mday;
141   dval->date1.month = tm_ptr->tm_mon + 1;
142   dval->date1.year  = tm_ptr->tm_year + 1900;
143   result = gedcom_normalize_date(DI_FROM_NUMBERS, dval);
144
145   if (result == 0) {
146     if (*dv) free(*dv);
147     *dv = dval;
148   }
149   return result;
150 }
151
152 int update_time(char** tv, struct tm* tm_ptr)
153 {
154   char tval[16];
155   sprintf(tval, "%02d:%02d:%02d",
156           tm_ptr->tm_hour, tm_ptr->tm_min, tm_ptr->tm_sec);
157
158   if (gom_set_string(tv, tval))
159     return 0;
160   else
161     return 1;
162 }
163
164 int gom_update_timestamp(struct change_date** chan, time_t t)
165 {
166   int result = 1;
167   if (chan) {
168     if (! *chan) gom_add_change_date(chan);
169     if (*chan) {
170       struct tm *tm_ptr = localtime(&t);
171       result = 0;
172       result |= update_date(&((*chan)->date), tm_ptr);
173       result |= update_time(&((*chan)->time), tm_ptr);
174     }
175   }
176   return result;
177 }
178
179 int write_change_date(Gedcom_write_hndl hndl, int parent,
180                       struct change_date *chan)
181 {
182   int result = 0;
183
184   if (!chan) return 1;
185
186   result |= gedcom_write_element_str(hndl, ELT_SUB_CHAN, 0, parent, NULL);
187   if (chan->date)
188     result |= gedcom_write_element_date(hndl, ELT_SUB_CHAN_DATE, 0,
189                                         ELT_SUB_CHAN, chan->date);
190   if (chan->time)
191     result |= gedcom_write_element_str(hndl, ELT_SUB_CHAN_TIME, 0,
192                                        ELT_SUB_CHAN_DATE, chan->time);
193   if (chan->note)
194     result |= write_note_subs(hndl, ELT_SUB_CHAN, chan->note);
195   if (chan->extra)
196     result |= write_user_data(hndl, chan->extra);
197   
198   return result;
199 }