1 // ----------------------------------------------------------------------------
2 // Copyright (C) 2014
3 //              David Freese, W1HKJ
4 //
5 // This file is part of flmsg
6 //
7 // flrig is free software; you can redistribute it and/or modify
8 // it under the terms of the GNU General Public License as published by
9 // the Free Software Foundation; either version 3 of the License, or
10 // (at your option) any later version.
11 //
12 // flrig is distributed in the hope that it will be useful,
13 // but WITHOUT ANY WARRANTY; without even the implied warranty of
14 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15 // GNU General Public License for more details.
16 //
17 // You should have received a copy of the GNU General Public License
18 // along with this program.  If not, see <http://www.gnu.org/licenses/>.
19 // ----------------------------------------------------------------------------
20 
21 #include <stdlib.h>
22 #include <iostream>
23 #include <fstream>
24 #include <cstring>
25 #include <ctime>
26 #include <sys/types.h>
27 #include <sys/stat.h>
28 #include <stdio.h>
29 #include <errno.h>
30 
31 #include <FL/Fl.H>
32 #include <FL/Enumerations.H>
33 #include <FL/Fl_Window.H>
34 #include <FL/Fl_Button.H>
35 #include <FL/Fl_Group.H>
36 #include <FL/Fl_Sys_Menu_Bar.H>
37 #include <FL/x.H>
38 #include <FL/Fl_Help_Dialog.H>
39 #include <FL/Fl_Menu_Item.H>
40 #include <FL/Fl_File_Icon.H>
41 
42 #include "config.h"
43 #include "flmsg_config.h"
44 
45 #include "flmsg.h"
46 #include "templates.h"
47 #include "debug.h"
48 #include "util.h"
49 #include "gettext.h"
50 #include "flmsg_dialog.h"
51 #include "flinput2.h"
52 #include "date.h"
53 #include "calendar.h"
54 #include "icons.h"
55 #include "fileselect.h"
56 #include "wrap.h"
57 #include "status.h"
58 #include "parse_xml.h"
59 
60 #ifdef WIN32
61 #  include "flmsgrc.h"
62 #  include "compat.h"
63 #  define dirent fl_dirent_no_thanks
64 #endif
65 
66 #include <FL/filename.H>
67 #include "dirent-check.h"
68 
69 #include <FL/x.H>
70 #include <FL/Fl_Pixmap.H>
71 #include <FL/Fl_Image.H>
72 
73 using namespace std;
74 
75 // ---------------------------------------------------------------------
76 // hics 214 field variables and template variables
77 // ---------------------------------------------------------------------
78 
79 string hics214_tag_incident			= ":1:";
80 string hics214_tag_date				= ":2:";
81 string hics214_tag_time				= ":2a:";
82 string hics214_tag_op_period		= ":3:";
83 string hics214_tag_sec_brch			= ":4:";
84 string hics214_tag_position			= ":5:";
85 string hics214_tag_activity_time	= ":T[n]:"; // 30
86 string hics214_tag_activity_event	= ":E[n]:";
87 string hics214_tag_prepared_by		= ":7:";
88 string hics214_tag_facility			= ":8:"; // new field
89 
90 string hics214_incident;
91 string hics214_date;
92 string hics214_time;
93 string hics214_op_period;
94 string hics214_sec_brch;
95 string hics214_position;
96 string hics214_activity_time[30];
97 string hics214_activity_event[30];
98 string hics214_prepared_by;
99 string hics214_facility;
100 
101 // =====================================================================
102 
103 string hics214_buff;
104 string hics214_def_filename = "";
105 string hics214_base_filename = "";
106 string hics214_template_name = "";
107 bool hics214_using_template = false;
108 
hics214_cb_set_date()109 void hics214_cb_set_date()
110 {
111 	hics214_txt_date->value(szDate(progStatus.dtformat));
112 }
113 
hics214_cb_set_time()114 void hics214_cb_set_time()
115 {
116 	hics214_txt_time->value(szTime(progStatus.UTC));
117 }
118 
hics214_clear_fields()119 void hics214_clear_fields()
120 {
121 	hics214_incident.clear();
122 	hics214_date.clear();
123 	hics214_time.clear();
124 	hics214_op_period.clear();
125 	hics214_sec_brch.clear();
126 	hics214_position.clear();
127 	hics214_prepared_by.clear();
128 	hics214_facility.clear();
129 
130 	for (int i = 0; i < 30; i++) {
131 		hics214_activity_time[i].clear();
132 		hics214_activity_event[i].clear();
133 	}
134 }
135 
check_hics214fields()136 bool check_hics214fields()
137 {
138 	if (hics214_incident != hics214_txt_incident->value())
139 		return true;
140 	if (hics214_date != hics214_txt_date->value())
141 		return true;
142 	if (hics214_time != hics214_txt_time->value())
143 		return true;
144 	if (hics214_op_period != hics214_txt_op_period->value())
145 		return true;
146 	if (hics214_sec_brch != hics214_txt_sec_brch->value())
147 		return true;
148 	if (hics214_position != hics214_txt_position->value())
149 		return true;
150 	if (hics214_prepared_by != hics214_txt_prepared_by->value())
151 		return true;
152 	if (hics214_facility != hics214_txt_facility->value())
153 		return true;
154 
155 	for (int i = 0; i < 30; i++) {
156 		if (hics214_activity_time[i] != hics214_txt_activity_time[i]->value())
157 			return true;
158 		if (hics214_activity_event[i] != hics214_txt_activity_event[i]->value())
159 			return true;
160 	}
161 	return false;
162 }
163 
hics214_update_fields()164 void hics214_update_fields()
165 {
166 	hics214_incident = hics214_txt_incident->value();
167 	hics214_date = hics214_txt_date->value();
168 	hics214_time = hics214_txt_time->value();
169 	hics214_op_period = hics214_txt_op_period->value();
170 	hics214_sec_brch = hics214_txt_sec_brch->value();
171 	hics214_position = hics214_txt_position->value();
172 	hics214_prepared_by = hics214_txt_prepared_by->value();
173 	hics214_facility = hics214_txt_facility->value();
174 
175 	for (int i = 0; i < 30; i++) {
176 		hics214_activity_time[i] = hics214_txt_activity_time[i]->value();
177 		hics214_activity_event[i] = hics214_txt_activity_event[i]->value();
178 	}
179 }
180 
hics214_update_form()181 void hics214_update_form()
182 {
183 	hics214_txt_incident->value(hics214_incident.c_str());
184 	hics214_txt_date->value(hics214_date.c_str());
185 	hics214_txt_time->value(hics214_time.c_str());
186 	hics214_txt_op_period->value(hics214_op_period.c_str());
187 	hics214_txt_sec_brch->value(hics214_sec_brch.c_str());
188 	hics214_txt_position->value(hics214_position.c_str());
189 	hics214_txt_prepared_by->value(hics214_prepared_by.c_str());
190 	hics214_txt_facility->value(hics214_facility.c_str());
191 
192 	for (int i = 0; i < 30; i++) {
193 		hics214_txt_activity_time[i]->value(hics214_activity_time[i].c_str());
194 		hics214_txt_activity_event[i]->value(hics214_activity_event[i].c_str());
195 	}
196 }
197 
hics214_clear_form()198 void hics214_clear_form()
199 {
200 	hics214_clear_fields();
201 	hics214_update_form();
202 }
203 
hics_nn(string & subst,int n)204 static string &hics_nn(string & subst, int n)
205 {
206 	static string garbage = "#$^*!";
207 	static string hics;
208 	hics.clear();
209 	hics = subst;
210 	size_t pos = hics.find("[");
211 	if (pos == string::npos) return garbage;
212 	pos++;
213 	hics[pos] = '0' + (n/10 % 10);
214 	hics[pos+1] = '0' + n % 10;
215 	hics[pos+2] = ']';
216 	hics += ':';
217 	return hics;
218 }
219 
hics214_make_buff(bool compress=false)220 void hics214_make_buff(bool compress = false)
221 {
222 	string mbuff;
223 	mbuff.clear();
224 	mbuff.append( lineout( hics214_tag_incident, hics214_incident ) );
225 	mbuff.append( lineout( hics214_tag_date, hics214_date ) );
226 	mbuff.append( lineout( hics214_tag_time, hics214_time ) );
227 	mbuff.append( lineout( hics214_tag_op_period, hics214_op_period ) );
228 	mbuff.append( lineout( hics214_tag_sec_brch, hics214_sec_brch) );
229 	mbuff.append( lineout( hics214_tag_position, hics214_position) );
230 	mbuff.append( lineout( hics214_tag_prepared_by, hics214_prepared_by ) );
231 	mbuff.append( lineout( hics214_tag_facility, hics214_facility ) );
232 
233 	for (int i = 0; i < 30; i++) {
234 		mbuff.append( lineout( hics_nn( hics214_tag_activity_time, i ), hics214_activity_time[i] ) );
235 		mbuff.append( lineout( hics_nn( hics214_tag_activity_event, i ), hics214_activity_event[i] ) );
236 	}
237 	if (compress) compress_maybe(mbuff);
238 	hics214_buff.append(mbuff);
239 }
240 
hics214_read_buffer(string data)241 void hics214_read_buffer(string data)
242 {
243 	hics214_clear_fields();
244 	read_header(data);
245 
246 	hics214_incident = findstr(data, hics214_tag_incident);
247 	hics214_date = findstr(data, hics214_tag_date);
248 	hics214_time = findstr(data, hics214_tag_time);
249 	hics214_op_period = findstr(data, hics214_tag_op_period);
250 	hics214_sec_brch = findstr(data, hics214_tag_sec_brch);
251 	hics214_position = findstr(data, hics214_tag_position);
252 	hics214_prepared_by = findstr(data, hics214_tag_prepared_by);
253 	hics214_facility = findstr(data, hics214_tag_facility);
254 
255 	for (int i = 0; i < 30; i++) {
256 		hics214_activity_time[i]    = findstr(data, hics_nn( hics214_tag_activity_time, i ) );
257 		hics214_activity_event[i]   = findstr(data, hics_nn( hics214_tag_activity_event, i ) );
258 	}
259 
260 	hics214_update_form();
261 }
262 
hics214_cb_new()263 void hics214_cb_new()
264 {
265 	if (check_hics214fields()) {
266 		if (fl_choice2("Form modified, save?", "No", "Yes", NULL) == 1) {
267 			update_header(CHANGED);
268 			hics214_cb_save();
269 		}
270 	}
271 	hics214_clear_form();
272 	clear_header();
273 	hics214_def_filename = ICS_msg_dir;
274 	hics214_def_filename.append("new").append(HF214_EXT);
275 	show_filename(hics214_def_filename);
276 	hics214_using_template = false;
277 }
278 
hics214_cb_import()279 void hics214_cb_import()
280 {
281 	fl_alert2("Not implemented");
282 }
283 
hics214_cb_export()284 void hics214_cb_export()
285 {
286 	fl_alert2("Not implemented");
287 }
288 
hics214_cb_wrap_import(string wrapfilename,string inpbuffer)289 void hics214_cb_wrap_import(string wrapfilename, string inpbuffer)
290 {
291 	hics214_clear_form();
292 	hics214_read_buffer(inpbuffer);
293 	hics214_def_filename = ICS_msg_dir;
294 	hics214_def_filename.append(wrapfilename);
295 	show_filename(hics214_def_filename);
296 	hics214_using_template = false;
297 }
298 
eval_hics214_fsize()299 int eval_hics214_fsize()
300 {
301 	Ccrc16 chksum;
302 	evalstr.assign("[WRAP:beg][WRAP:lf][WRAP:fn ");
303 	evalstr.append(hics214_base_filename).append("]");
304 	hics214_update_fields();
305 	update_header(FROM);
306 	evalstr.append(header("<hics214>"));
307 	hics214_buff.clear();
308 	hics214_make_buff(true);
309 	if (hics214_buff.empty()) return 0;
310 	compress_maybe( hics214_buff );
311 	evalstr.append( hics214_buff );
312 	evalstr.append("[WRAP:chksum ").append(chksum.scrc16(evalstr)).append("][WRAP:end]");
313 	return evalstr.length();
314 }
315 
hics214_cb_wrap_export()316 void hics214_cb_wrap_export()
317 {
318 	if (check_hics214fields()) {
319 		if (fl_choice2("Form modified, save?", "No", "Yes", NULL) == 0)
320 			return;
321 		update_header(CHANGED);
322 	}
323 	hics214_update_fields();
324 
325 	if (hics214_base_filename == string("new").append(HF214_EXT) ||\
326 		hics214_base_filename == string("default").append(HF214_EXT) )
327 		hics214_cb_save_as();
328 
329 	string wrapfilename = WRAP_send_dir;
330 	wrapfilename.append(hics214_base_filename);
331 	wrapfilename.append(".wrap");
332 	const char *p = FSEL::saveas(
333 			"Save as wrap file",
334 			"Wrap file\t*.{wrap,WRAP}",
335 			wrapfilename.c_str());
336 	if (p) {
337 		string pext = fl_filename_ext(p);
338 		wrapfilename = p;
339 		update_header(FROM);
340 		hics214_buff.assign(header("<hics214>"));
341 		hics214_make_buff(true);
342 		export_wrapfile(hics214_base_filename, wrapfilename, hics214_buff, pext != ".wrap");
343 
344 		hics214_buff.assign(header("<hics214>"));
345 		hics214_make_buff(false);
346 		hics214_write(hics214_def_filename);
347 	}
348 }
349 
hics214_cb_wrap_autosend()350 void hics214_cb_wrap_autosend()
351 {
352 	if (check_hics214fields()) {
353 		if (fl_choice2("Form modified, save?", "No", "Yes", NULL) == 0)
354 			return;
355 		update_header(CHANGED);
356 	}
357 	hics214_update_fields();
358 
359 	if (hics214_base_filename == string("new").append(HF214_EXT) ||
360 		hics214_base_filename == string("default").append(HF214_EXT) )
361 		hics214_cb_save_as();
362 
363 	update_header(FROM);
364 	hics214_buff.assign(header("<hics214>"));
365 	hics214_make_buff(true);
366 	xfr_via_socket(hics214_base_filename,hics214_buff);
367 
368 	hics214_buff.assign(header("<hics214>"));
369 	hics214_make_buff(false);
370 	hics214_write(hics214_def_filename);
371 }
372 
hics214_cb_load_template()373 void hics214_cb_load_template()
374 {
375 	string hics214_def_filename = hics214_template_name;
376 	const char *p = FSEL::select(
377 			"Open template file",
378 			string("Template file\t*").append(HT214_EXT).c_str(),
379 			hics214_def_filename.c_str());
380 	if (p) {
381 		hics214_clear_form();
382 		read_data_file(p);
383 		hics214_template_name = p;
384 		show_filename(hics214_template_name);
385 		hics214_using_template = true;
386 	}
387 }
388 
hics214_cb_save_template()389 void hics214_cb_save_template()
390 {
391 	if (!hics214_using_template) {
392 		hics214_cb_save_as_template();
393 		return;
394 	}
395 	string hics214_def_filename = hics214_template_name;
396 	const char *p = FSEL::saveas(
397 			"Save template file",
398 			string("Template file\t*").append(HT214_EXT).c_str(),
399 			hics214_def_filename.c_str());
400 	if (p) {
401 		update_header(CHANGED);
402 		hics214_update_fields();
403 		hics214_buff.assign(header("<hics214>"));
404 		hics214_make_buff();
405 		hics214_write(p);
406 	}
407 }
408 
hics214_cb_save_as_template()409 void hics214_cb_save_as_template()
410 {
411 	string hics214_def_filename = hics214_template_name;
412 	const char *p = FSEL::saveas(
413 			"Save as template file",
414 			string("Template file\t*").append(HT214_EXT).c_str(),
415 			hics214_def_filename.c_str());
416 	if (p) {
417 		const char *pext = fl_filename_ext(p);
418 		hics214_template_name = p;
419 		if (strlen(pext) == 0) hics214_template_name.append(HT214_EXT);
420 		remove_spaces_from_filename(hics214_template_name);
421 		clear_header();
422 		update_header(CHANGED);
423 		hics214_update_fields();
424 		hics214_buff.assign(header("<hics214>"));
425 		hics214_make_buff();
426 		hics214_write(hics214_template_name);
427 		show_filename(hics214_template_name);
428 		hics214_using_template = true;
429 	}
430 }
431 
hics214_cb_open()432 void hics214_cb_open()
433 {
434 	const char *p = FSEL::select(
435 			_("Open data file"),
436 			string("HICS-214\t*").append(HF214_EXT).c_str(),
437 			hics214_def_filename.c_str());
438 	if (!p) return;
439 	if (strlen(p) == 0) return;
440 	hics214_clear_form();
441 	read_data_file(p);
442 	hics214_using_template = false;
443 	hics214_def_filename = p;
444 	show_filename(hics214_def_filename);
445 }
446 
hics214_write(string s)447 void hics214_write(string s)
448 {
449 	FILE *file214 = fopen(s.c_str(), "w");
450 	if (!file214) return;
451 
452 	fwrite(hics214_buff.c_str(), hics214_buff.length(), 1, file214);
453 	fclose(file214);
454 }
455 
hics214_cb_save_as()456 bool hics214_cb_save_as()
457 {
458 	const char *p;
459 	string newfilename;
460 
461 	string name = named_file();
462 	if (!name.empty()) {
463 		name.append(HF214_EXT);
464 		newfilename = ICS_msg_dir;
465 		newfilename.append(name);
466 	} else
467 		newfilename = hics214_def_filename;
468 
469 	p = FSEL::saveas(
470 			_("Save data file"),
471 			string("HICS-214\t*").append(HF214_EXT).c_str(),
472 			newfilename.c_str());
473 	if (!p) return false;
474 	if (strlen(p) == 0) return false;
475 
476 	if (progStatus.sernbr_fname) update_sernbr();
477 
478 	const char *pext = fl_filename_ext(p);
479 	hics214_def_filename = p;
480 	if (strlen(pext) == 0) hics214_def_filename.append(HF214_EXT);
481 
482 	remove_spaces_from_filename(hics214_def_filename);
483 	hics214_update_fields();
484 	update_header(NEW);
485 	hics214_buff.assign(header("<hics214>"));
486 	hics214_make_buff();
487 	hics214_write(hics214_def_filename);
488 
489 	hics214_using_template = false;
490 	show_filename(hics214_def_filename);
491 
492 	return true;
493 }
494 
hics214_cb_save()495 void hics214_cb_save()
496 {
497 	if (hics214_base_filename == string("new").append(HF214_EXT) ||
498 		hics214_base_filename == string("default").append(HF214_EXT) ||
499 		hics214_using_template == true) {
500 		hics214_cb_save_as();
501 		return;
502 	}
503 	if (check_hics214fields()) update_header(CHANGED);
504 	hics214_buff.assign(header("<hics214>"));
505 	hics214_update_fields();
506 	hics214_make_buff();
507 	hics214_write(hics214_def_filename);
508 	hics214_using_template = false;
509 }
510 
hics214_cb_html()511 void hics214_cb_html()
512 {
513 	string fname_name = fl_filename_name(hics214_def_filename.c_str());
514 	size_t p = fname_name.rfind('.');
515 	if (p != string::npos) fname_name.erase(p);
516 
517 	string hics214_fname = ICS_dir;
518 	hics214_fname.append(fname_name);
519 	hics214_fname.append(".html");
520 
521 	string html_text = "";
522 
523 	hics214_update_fields();
524 	string form214 = hics214_html_template;
525 
526 	replacestr(form214, TITLE, fname_name);
527 	replacestr(form214, hics214_tag_incident, hics214_incident );
528 	replacestr(form214, hics214_tag_date, hics214_date );
529 	replacestr(form214, hics214_tag_time, hics214_time );
530 	replacestr(form214, hics214_tag_op_period, hics214_op_period );
531 	replacestr(form214, hics214_tag_sec_brch, hics214_sec_brch );
532 	replacestr(form214, hics214_tag_position, hics214_position );
533 	replacestr(form214, hics214_tag_prepared_by, hics214_prepared_by );
534 	replacestr(form214, hics214_tag_facility, hics214_facility );
535 
536 	for (int i = 0; i < 30; i++) {
537 		replacestr(form214, hics_nn( hics214_tag_activity_time, i ), hics214_activity_time[i] );
538 		replacestr(form214, hics_nn( hics214_tag_activity_event, i ), hics214_activity_event[i] );
539 	}
540 
541 	FILE *file214 = fopen(hics214_fname.c_str(), "w");
542 	fprintf(file214,"%s", form214.c_str());
543 	fclose(file214);
544 
545 	open_url(hics214_fname.c_str());
546 }
547 
hics214_cb_textout()548 void hics214_cb_textout()
549 {
550 	string hics214_fname = ICS_dir;
551 	hics214_fname.append("hics214.txt");
552 
553 	hics214_update_fields();
554 	string form214 = hics214_text_template;
555 
556 	replacestr(form214, hics214_tag_incident, hics214_incident );
557 	replacestr(form214, hics214_tag_date, hics214_date );
558 	replacestr(form214, hics214_tag_time, hics214_time );
559 	replacestr(form214, hics214_tag_op_period, hics214_op_period );
560 	replacestr(form214, hics214_tag_sec_brch, hics214_sec_brch );
561 	replacestr(form214, hics214_tag_position, hics214_position );
562 	replacestr(form214, hics214_tag_prepared_by, hics214_prepared_by );
563 	replacestr(form214, hics214_tag_facility, hics214_facility );
564 
565 	for (int i = 0; i < 30; i++) {
566 		replacestr(form214, hics_nn( hics214_tag_activity_time, i ), hics214_activity_time[i] );
567 		replacestr(form214, hics_nn( hics214_tag_activity_event, i ), hics214_activity_event[i] );
568 	}
569 
570 	FILE *file214 = fopen(hics214_fname.c_str(), "w");
571 	fprintf(file214,"%s", form214.c_str());
572 	fclose(file214);
573 
574 	open_url(hics214_fname.c_str());
575 }
576