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 "combo.h"
53 #include "date.h"
54 #include "calendar.h"
55 #include "icons.h"
56 #include "fileselect.h"
57 #include "wrap.h"
58 #include "status.h"
59 #include "parse_xml.h"
60 
61 #ifdef WIN32
62 #  include "flmsgrc.h"
63 #  include "compat.h"
64 #  define dirent fl_dirent_no_thanks
65 #endif
66 
67 #include <FL/filename.H>
68 #include "dirent-check.h"
69 
70 #include <FL/x.H>
71 #include <FL/Fl_Pixmap.H>
72 #include <FL/Fl_Image.H>
73 
74 string severe_wx_date;
75 string severe_wx_time;
76 string severe_wx_zone;
77 bool  severe_wx_exact;
78 bool  severe_wx_not_exact;
79 
80 string severe_wx_city;
81 string severe_wx_state;
82 string severe_wx_county;
83 
84 bool  severe_wx_tornado;
85 bool  severe_wx_funnel_cloud;
86 bool  severe_wx_wall_cloud;
87 bool  severe_wx_hail;
88 string severe_wx_hail_size;
89 
90 bool  severe_wx_high_wind;
91 string severe_wx_wind_speed;
92 bool  severe_wx_measured;
93 bool  severe_wx_estimated;
94 
95 bool  severe_wx_flood;
96 bool  severe_wx_flash_flood;
97 bool  severe_wx_other;
98 
99 bool  severe_wx_dmg_yes;
100 bool  severe_wx_dmg_no;
101 bool  severe_wx_inj_yes;
102 bool  severe_wx_inj_no;
103 
104 string severe_wx_narrative;
105 
106 // could not use real names ... WIN32 barfs
107 enum SWX_QTYPE { B, D, S, M, T, I, F, C, O, E };
108 // bool, string, multi-line string, text, int, float, character, cOmbo, empty
109 
110 struct SWX_QUAD {
111 	SWX_QTYPE  qtype;  // type of field
112 	string html_fld;
113 	void   *ptr;
114 	Fl_Widget *widget; };
115 
116 SWX_QUAD severe_wx_QUAD[] = {
117 { D,	":date:",			&severe_wx_date,			w_severe_wx_date },			// 0
118 { S,	":time:",			&severe_wx_time,			w_severe_wx_time },			// 1
119 { O,	":zone:",			&severe_wx_zone,			w_severe_wx_zone },			// 2
120 { O,	":state:",			&severe_wx_state,			w_severe_wx_state },		// 3
121 { O,	":county:",			&severe_wx_county,			w_severe_wx_county },		// 4
122 { S,	":city:",			&severe_wx_city,			w_severe_wx_city },			// 5
123 { S,	":speed:",			&severe_wx_wind_speed,		w_severe_wx_wind_speed },	// 6
124 { T,	":narrative:",		&severe_wx_narrative,		w_severe_wx_narrative },	// 7
125 { O,	":hail_size:",		&severe_wx_hail_size,		w_severe_wx_hail_size},		// 8
126 { B,	":exact:",			&severe_wx_exact,			w_severe_wx_exact },		// 9
127 { B,	":not_exact:",		&severe_wx_not_exact,		w_severe_wx_not_exact },	// 10
128 { B,	":tornado:",		&severe_wx_tornado,			w_severe_wx_tornado },		// 11
129 { B,	":funnel_cloud:",	&severe_wx_funnel_cloud,	w_severe_wx_funnel_cloud },	// 12
130 { B,	":wall_cloud:",		&severe_wx_wall_cloud,		w_severe_wx_wall_cloud },	// 13
131 { B,	":hail:",			&severe_wx_hail,			w_severe_wx_hail },			// 14
132 { B,	":high_wind:",		&severe_wx_high_wind,		w_severe_wx_high_wind },	// 15
133 { B,	":measured:",		&severe_wx_measured,		w_severe_wx_measured },		// 16
134 { B,	":estimated:",		&severe_wx_estimated,		w_severe_wx_estimated },	// 17
135 { B,	":flood:",			&severe_wx_flood,			w_severe_wx_flood },		// 18
136 { B,	":flash_flood:",	&severe_wx_flash_flood,		w_severe_wx_flash_flood },	// 19
137 { B,	":other:",			&severe_wx_other,			w_severe_wx_other },		// 20
138 { B,	":dmg_yes:",		&severe_wx_dmg_yes,			w_severe_wx_dmg_yes },		// 21
139 { B,	":dmg_no:",			&severe_wx_dmg_no,			w_severe_wx_dmg_no },		// 22
140 { B,	":inj_yes:",		&severe_wx_inj_yes,			w_severe_wx_inj_yes },		// 23
141 { B,	":inj_no:",			&severe_wx_inj_no,			w_severe_wx_inj_no },		// 24
142 { E,	"",					NULL,						NULL }
143 };
144 
145 string buffsevere_wx;
146 string def_severe_wx_filename = "";
147 string base_severe_wx_filename = "";
148 string def_severe_wx_TemplateName = "";
149 
150 bool using_severe_wx_template = false;
151 static bool fields_initialized = false;
152 
153 // required to initialize the control pointers in the QUAD array
154 
init_widgets()155 static void init_widgets()
156 {
157 	severe_wx_QUAD[0].widget  = w_severe_wx_date;
158 	severe_wx_QUAD[1].widget  = w_severe_wx_time;
159 	severe_wx_QUAD[2].widget  = w_severe_wx_zone;
160 	severe_wx_QUAD[3].widget  = w_severe_wx_state;
161 	severe_wx_QUAD[4].widget  = w_severe_wx_county;
162 	severe_wx_QUAD[5].widget  = w_severe_wx_city;
163 	severe_wx_QUAD[6].widget  = w_severe_wx_wind_speed;
164 	severe_wx_QUAD[7].widget  = w_severe_wx_narrative;
165 	severe_wx_QUAD[8].widget  = w_severe_wx_hail_size;
166 	severe_wx_QUAD[9].widget  = w_severe_wx_exact;
167 	severe_wx_QUAD[10].widget = w_severe_wx_not_exact;
168 	severe_wx_QUAD[11].widget = w_severe_wx_tornado;
169 	severe_wx_QUAD[12].widget = w_severe_wx_funnel_cloud;
170 	severe_wx_QUAD[13].widget = w_severe_wx_wall_cloud;
171 	severe_wx_QUAD[14].widget = w_severe_wx_hail;
172 	severe_wx_QUAD[15].widget = w_severe_wx_high_wind;
173 	severe_wx_QUAD[16].widget = w_severe_wx_measured;
174 	severe_wx_QUAD[17].widget = w_severe_wx_estimated;
175 	severe_wx_QUAD[18].widget = w_severe_wx_flood;
176 	severe_wx_QUAD[19].widget = w_severe_wx_flash_flood;
177 	severe_wx_QUAD[20].widget = w_severe_wx_other;
178 	severe_wx_QUAD[21].widget = w_severe_wx_dmg_yes;
179 	severe_wx_QUAD[22].widget = w_severe_wx_dmg_no;
180 	severe_wx_QUAD[23].widget = w_severe_wx_inj_yes;
181 	severe_wx_QUAD[24].widget = w_severe_wx_inj_no;
182 
183 	fields_initialized = true;
184 }
185 
186 //enum SWX_QTYPE { B, S, T, I, F, C, E };
187 // bool, string, text, int, float, character, empty
188 
clearQUAD(SWX_QUAD * p)189 static void clearQUAD(SWX_QUAD *p)
190 {
191 	SWX_QTYPE qt = E;
192 	while ((qt = p->qtype) != E) {
193 		switch (qt) {
194 			case B : (*(bool *)(p->ptr)) = false; break;
195 			case S :
196 			case D :
197 			case M : ((string *)(p->ptr))->clear(); break;
198 			case T : ((string *)(p->ptr))->clear(); break;
199 			case C : (*(char *)(p->ptr)) = ' '; break;
200 			case I : (*(int *)(p->ptr)) = 0; break;
201 			case F : (*(float *)(p->ptr)) = 0.0; break;
202 			case O : break;
203 			case E : return;
204 		}
205 		p++;
206 	}
207 }
208 
clear_severe_wxfields()209 void clear_severe_wxfields()
210 {
211 	if (!fields_initialized) init_widgets();
212 	clearQUAD(severe_wx_QUAD);
213 }
214 
checkQUAD(SWX_QUAD * p)215 static bool checkQUAD(SWX_QUAD *p)
216 {
217 	int i = 0;
218 	float f = 0;
219 	char c = ' ';
220 	SWX_QTYPE qt = E;
221 	while ((qt = p->qtype) != E) {
222 		if (p->widget == NULL) return false;
223 		switch (qt) {
224 			case B:
225 				if (*((bool *)(p->ptr)) != ((Fl_Check_Button *)p->widget)->value())
226 					return true;
227 				break;
228 			case S:
229 			case M:
230 				if (*((string *)(p->ptr)) != ((Fl_Input2 *)p->widget)->value())
231 					return true;
232 				break;
233 			case D:
234 				if (*((string *)(p->ptr)) != ((Fl_DateInput *)p->widget)->value())
235 					return true;
236 				break;
237 			case T:
238 				if (*((string *)(p->ptr)) != ((FTextEdit *)p->widget)->buffer()->text())
239 					return true;
240 				break;
241 			case C:
242 				c = ' ';
243 				if (((Fl_Input2 *)p->widget)->value()[0])
244 					c = ((Fl_Input2 *)p->widget)->value()[0];
245 				if (*((char *)(p->ptr)) != c)
246 					return true;
247 				break;
248 			case I:
249 				i = 0;
250 				if (((Fl_Input2 *)p->widget)->value()[0])
251 					sscanf( ((Fl_Input2 *)p->widget)->value(), "%d", &i);
252 				if (*((int *)(p->ptr)) != i)
253 					return true;
254 				break;
255 			case F:
256 				f = 0;
257 				if (((Fl_Input2 *)p->widget)->value()[0])
258 					sscanf( ((Fl_Input2 *)p->widget)->value(), "%f", &f);
259 				if (*((float *)(p->ptr)) != f)
260 					return true;
261 				break;
262 			case O:
263 				if (((Fl_ListBox *)p->widget)->index() == 0) break;
264 				if (*((string *)(p->ptr)) != ((Fl_ListBox *)p->widget)->value())
265 					return true;
266 				break;
267 			case E:
268 			default: return false;
269 		}
270 		p++;
271 	}
272 	return false;
273 }
274 
check_severe_wxfields()275 bool check_severe_wxfields()
276 {
277 	return checkQUAD(severe_wx_QUAD);
278 }
279 
updateQUAD(SWX_QUAD * p)280 static void updateQUAD(SWX_QUAD *p)
281 {
282 	int i = 0;
283 	float f = 0;
284 	char c = ' ';
285 	SWX_QTYPE qt = E;
286 	while ((qt = p->qtype) != E) {
287 		switch (qt) {
288 			case B:
289 				*((bool *)(p->ptr)) = ((Fl_Check_Button *)p->widget)->value();
290 				break;
291 			case S:
292 			case M:
293 				*((string *)(p->ptr)) = ((Fl_Input2 *)p->widget)->value();
294 				break;
295 			case D:
296 				*((string *)(p->ptr)) = ((Fl_DateInput *)p->widget)->value();
297 				break;
298 			case O:
299 				{	string s = ((Fl_ListBox *)p->widget)->value();
300 					if (s.find("--") == 0)
301 						((string *)(p->ptr))->clear();
302 					else
303 						*((string *)(p->ptr)) = ((Fl_ListBox *)p->widget)->value();
304 				}
305 				break;
306 			case T:
307 				*((string *)(p->ptr)) = ((FTextEdit *)p->widget)->buffer()->text();
308 				break;
309 			case C:
310 				c = ' ';
311 				if (((Fl_Input2 *)p->widget)->value()[0])
312 					c = ((Fl_Input2 *)p->widget)->value()[0];
313 				*((char *)(p->ptr)) = c;
314 				break;
315 			case I:
316 				i = 0;
317 				if (((Fl_Input2 *)p->widget)->value()[0])
318 					sscanf( ((Fl_Input2 *)p->widget)->value(), "%d", &i);
319 				*((int *)(p->ptr)) = i;
320 				break;
321 			case F:
322 				f = 0;
323 				if (((Fl_Input2 *)p->widget)->value()[0])
324 					sscanf( ((Fl_Input2 *)p->widget)->value(), "%f", &f);
325 				*((float *)(p->ptr)) = f;
326 				break;
327 			case E:
328 			default: return;
329 		}
330 		p++;
331 	}
332 }
333 
update_severe_wxfields()334 void update_severe_wxfields()
335 {
336 	if (!fields_initialized) init_widgets();
337 	updateQUAD(severe_wx_QUAD);
338 	if (w_severe_wx_hail->value())
339 		w_severe_wx_hail_size->activate();
340 	else
341 		w_severe_wx_hail_size->deactivate();
342 }
343 
set_severe_wx_counties(int n)344 void set_severe_wx_counties(int n) {
345 	if (n > (numstates - 1)) return;
346 
347 	string st_letters = states[n].substr(0,3);
348 	size_t p1 = counties.find(st_letters);
349 	size_t p2 = counties.rfind(st_letters);
350 	if (p1 == string::npos || p2 == string::npos) {
351 		printf("not found\n");
352 		return;
353 	}
354 	string state_counties = counties.substr(p1 + 3, p2 - p1 - 3);
355 	size_t p4 = 0, p5 = 0;
356 	w_severe_wx_county->clear();
357 	while ((p5 = state_counties.find(',',p4)) != string::npos) {
358 		w_severe_wx_county->add(state_counties.substr(p4, p5-p4).c_str());
359 		p4 = p5 + 1;
360 	}
361 	w_severe_wx_county->index(0);
362 }
363 
set_severe_wx_combos()364 void set_severe_wx_combos() {
365 	w_severe_wx_state->clear();
366 	for (int n = 0; n < numstates; n++) {
367 		if (n == 0)
368 			w_severe_wx_state->add("State/Province");
369 		else
370 			w_severe_wx_state->add(states[n].c_str());
371 	}
372 	w_severe_wx_state->index(0);
373 	set_severe_wx_counties(0);
374 
375 	w_severe_wx_hail_size->clear();
376 	for (int n = 0; n < num_hail_size; n++ )
377 		w_severe_wx_hail_size->add(hail_size[n].c_str());
378 
379 	w_severe_wx_hail_size->index(0);
380 }
381 
updateFORM(SWX_QUAD * p)382 static void updateFORM(SWX_QUAD *p)
383 {
384 	char val[20];
385 	SWX_QTYPE qt = E;
386 	while ((qt = p->qtype) != E) {
387 		switch (qt) {
388 			case B:
389 				((Fl_Check_Button *)p->widget)->value(*((bool *)(p->ptr)));
390 				break;
391 			case S:
392 			case M:
393 				((Fl_Input2 *)p->widget)->value(((string *)(p->ptr))->c_str());
394 				break;
395 			case D:
396 				((Fl_DateInput *)p->widget)->value(((string *)(p->ptr))->c_str());
397 				break;
398 			case O:
399 				((Fl_ListBox *)p->widget)->put_value(((string *)(p->ptr))->c_str());
400 				break;
401 			case T:
402 				((FTextEdit *)p->widget)->clear();
403 				((FTextEdit *)p->widget)->add(((string *)(p->ptr))->c_str());
404 				break;
405 			case C:
406 				val[0] = *((char *)(p->ptr));
407 				val[1] = 0;
408 				((Fl_Input2 *)p->widget)->value(val);
409 				break;
410 			case I:
411 				if (*((int *)(p->ptr)) == 0)
412 					((Fl_Input2 *)p->widget)->value("");
413 				else {
414 					snprintf(val, sizeof(val), "%d", *((int *)(p->ptr)));
415 					((Fl_Input2 *)p->widget)->value(val);
416 				}
417 				break;
418 			case F:
419 				snprintf(val, sizeof(val), "%f", *((float *)(p->ptr)));
420 				((Fl_Input2 *)p->widget)->value(val);
421 				break;
422 			case E:
423 			default: return;
424 		}
425 		p++;
426 	}
427 }
428 
update_severe_wxform()429 void update_severe_wxform()
430 {
431 	if (!fields_initialized) init_widgets();
432 	updateFORM(severe_wx_QUAD);
433 }
434 
clear_severe_wx_form()435 void clear_severe_wx_form()
436 {
437 	clear_severe_wxfields();
438 	update_severe_wxform();
439 // combo initializers
440 	w_severe_wx_state->index(0);
441 	set_severe_wx_counties(0);
442 	w_severe_wx_county->index(0);
443 	w_severe_wx_city->index(0);
444 	w_severe_wx_zone->index(0);
445 	w_severe_wx_hail_size->index(0);
446 // boolean initializers
447 	w_severe_wx_dmg_no->value(1);
448 	w_severe_wx_inj_no->value(1);
449 	w_severe_wx_estimated->value(1);
450 	w_severe_wx_not_exact->value(1);
451 }
452 
453 static string mbuff;
454 
make_buffQUAD(SWX_QUAD * p)455 static void make_buffQUAD(SWX_QUAD *p)
456 {
457 	string one = "1"; string zero = "0";
458 	string sval = " ";
459 	char szval[20];
460 	SWX_QTYPE qt = E;
461 	while ((qt = p->qtype) != E) {
462 		switch (qt) {
463 			case B:
464 				if (*((bool *)(p->ptr)) == true)
465 					mbuff.append( lineout( p->html_fld, *((bool *)(p->ptr)) ? one : zero));
466 				break;
467 			case O: case S: case D: case M:
468 				if (((string *)(p->ptr))->length())
469 					mbuff.append( lineout( p->html_fld, *((string *)(p->ptr))));
470 				break;
471 			case T:
472 				mbuff.append( lineout( p->html_fld, *((string *)(p->ptr))));
473 				break;
474 			case C:
475 				if ((*(char *)(p->ptr)) != 0 && *((char *)(p->ptr)) != ' ') {
476 					sval = " ";
477 					sval[0] = *((char *)(p->ptr));
478 					mbuff.append( lineout( p->html_fld, sval));
479 				}
480 				break;
481 			case I:
482 				if (*((int*)(p->ptr)) > 0) {
483 					snprintf(szval, sizeof(szval), "%d", *((int *)(p->ptr)) );
484 					sval = szval;
485 					mbuff.append( lineout( p->html_fld, sval) );
486 				}
487 				break;
488 			case F:
489 				if (*((float *)(p->ptr)) > 0) {
490 					snprintf(szval, sizeof(szval), "%f", *((float *)(p->ptr)));
491 					sval = szval;
492 					mbuff.append( lineout( p->html_fld, sval) );
493 				}
494 				break;
495 			case E:
496 			default: return;
497 		}
498 		p++;
499 	}
500 }
501 
make_buff_severe_wx(bool compress=false)502 void make_buff_severe_wx(bool compress = false)
503 {
504 	mbuff.clear();
505 	make_buffQUAD(severe_wx_QUAD);
506 	if (compress) compress_maybe(mbuff);
507 	buffsevere_wx.append(mbuff);
508 }
509 
readQUAD(string data,SWX_QUAD * p)510 static void readQUAD(string data, SWX_QUAD *p)
511 {
512 	int i = 0;
513 	float f;
514 	SWX_QTYPE qt = p->qtype;
515 	while (qt != E) {
516 		switch (qt) {
517 			case B:
518 				*((bool *)(p->ptr)) = (findstr( data, p->html_fld ) == "1");
519 				break;
520 			case D: case O: case S: case M:
521 				*((string *)(p->ptr)) = findstr( data, p->html_fld );
522 				break;
523 			case T:
524 				*((string *)(p->ptr)) = findstr( data, p->html_fld );
525 				break;
526 			case C:
527 				*((char *)(p->ptr)) = findstr( data, p->html_fld )[0];
528 				break;
529 			case I:
530 				i = 0;
531 				sscanf( findstr( data, p->html_fld ).c_str(), "%d", &i);
532 				*((int *)(p->ptr)) = i;
533 				break;
534 			case F:
535 				f = 0;
536 				sscanf( findstr( data, p->html_fld ).c_str(), "%f", &f);
537 				*((float *)(p->ptr)) = f;
538 				break;
539 			case E:
540 			default: return;
541 		}
542 		p++;
543 		qt = p->qtype;
544 	}
545 }
546 
read_severe_wx_buffer(string data)547 void read_severe_wx_buffer(string data)
548 {
549 	clear_severe_wxfields();
550 	read_header(data);
551 
552 	readQUAD (data, severe_wx_QUAD);
553 	update_severe_wxform();
554 	int idx = w_severe_wx_state->index();
555 	set_severe_wx_counties(idx);
556 	w_severe_wx_county->value( ((string *)(severe_wx_QUAD[4].ptr))->c_str() );
557 }
558 
cb_severe_wx_new()559 void cb_severe_wx_new()
560 {
561 	if (check_severe_wxfields()) {
562 		if (fl_choice2("Form modified, save?", "No", "Yes", NULL) == 1) {
563 			update_header(CHANGED);
564 			cb_severe_wx_save();
565 		}
566 	}
567 	clear_severe_wx_form();
568 	clear_header();
569 	def_severe_wx_filename = ICS_msg_dir;
570 	def_severe_wx_filename.append("new").append(FSWX_EXT);
571 	show_filename(def_severe_wx_filename);
572 	using_severe_wx_template = false;
573 }
574 
cb_severe_wx_import()575 void cb_severe_wx_import()
576 {
577 	fl_alert2("Not implemented");
578 }
579 
cb_severe_wx_export()580 void cb_severe_wx_export()
581 {
582 	fl_alert2("Not implemented");
583 }
584 
cb_severe_wx_wrap_import(string wrapfilename,string inpbuffer)585 void cb_severe_wx_wrap_import(string wrapfilename, string inpbuffer)
586 {
587 	clear_severe_wx_form();
588 	read_severe_wx_buffer(inpbuffer);
589 	def_severe_wx_filename = ICS_msg_dir;
590 	def_severe_wx_filename.append(wrapfilename);
591 	show_filename(def_severe_wx_filename);
592 	using_severe_wx_template = false;
593 }
594 
eval_severe_wx_fsize()595 int eval_severe_wx_fsize()
596 {
597 	Ccrc16 chksum;
598 	evalstr.assign("[WRAP:beg][WRAP:lf][WRAP:fn ");
599 	evalstr.append(base_severe_wx_filename).append("]");
600 	update_severe_wxfields();
601 	update_header(FROM);
602 	evalstr.append(header("<severe_wx>"));
603 	buffsevere_wx.clear();
604 	make_buff_severe_wx(true);
605 	if (buffsevere_wx.empty()) return 0;
606 	compress_maybe( buffsevere_wx );
607 	evalstr.append( buffsevere_wx );
608 	evalstr.append("[WRAP:chksum ").append(chksum.scrc16(evalstr)).append("][WRAP:end]");
609 	return evalstr.length();
610 }
611 
cb_severe_wx_wrap_export()612 void cb_severe_wx_wrap_export()
613 {
614 	if (check_severe_wxfields()) {
615 		if (fl_choice2("Form modified, save?", "No", "Yes", NULL) == 0)
616 			return;
617 		update_header(CHANGED);
618 	}
619 	update_severe_wxfields();
620 
621 	if (base_severe_wx_filename == string("new").append(FSWX_EXT) ||
622 		base_severe_wx_filename == string("default").append(FSWX_EXT) )
623 		if (!cb_severe_wx_save_as()) return;
624 
625 	string wrapfilename = WRAP_send_dir;
626 	wrapfilename.append(base_severe_wx_filename);
627 	wrapfilename.append(".wrap");
628 	const char *p = FSEL::saveas(
629 			"Save as wrap file",
630 			"Wrap file\t*.{wrap,WRAP}",
631 			wrapfilename.c_str());
632 	if (p) {
633 		string pext = fl_filename_ext(p);
634 		wrapfilename = p;
635 
636 		update_header(FROM);
637 		buffsevere_wx.assign(header("<severe_wx>"));
638 		make_buff_severe_wx(true);
639 		export_wrapfile(base_severe_wx_filename, wrapfilename, buffsevere_wx, pext != ".wrap");
640 
641 		buffsevere_wx.assign(header("<severe_wx>"));
642 		make_buff_severe_wx(false);
643 		write_severe_wx(def_severe_wx_filename);
644 	}
645 }
646 
cb_severe_wx_wrap_autosend()647 void cb_severe_wx_wrap_autosend()
648 {
649 	if (check_severe_wxfields()) {
650 		if (fl_choice2("Form modified, save?", "No", "Yes", NULL) == 0)
651 			return;
652 		update_header(CHANGED);
653 	}
654 	update_severe_wxfields();
655 
656 	if (base_severe_wx_filename == string("new").append(FSWX_EXT) ||
657 		base_severe_wx_filename == string("default").append(FSWX_EXT) )
658 		if (!cb_severe_wx_save_as()) return;
659 
660 	update_header(FROM);
661 	buffsevere_wx.assign(header("<severe_wx>"));
662 	make_buff_severe_wx(true);
663 	xfr_via_socket(base_severe_wx_filename, buffsevere_wx);
664 
665 	buffsevere_wx.assign(header("<severe_wx>"));
666 	make_buff_severe_wx(false);
667 	write_severe_wx(def_severe_wx_filename);
668 }
669 
cb_severe_wx_load_template()670 void cb_severe_wx_load_template()
671 {
672 	string def_severe_wx_filename = def_severe_wx_TemplateName;
673 	const char *p = FSEL::select(
674 			"Open template file",
675 			string("Template file\t*").append(TSWX_EXT).c_str(),
676 			def_severe_wx_filename.c_str());
677 	if (p) {
678 		clear_severe_wx_form();
679 		read_data_file(p);
680 		def_severe_wx_TemplateName = p;
681 		show_filename(def_severe_wx_TemplateName);
682 		using_severe_wx_template = true;
683 	}
684 }
685 
cb_severe_wx_save_template()686 void cb_severe_wx_save_template()
687 {
688 	if (!using_severe_wx_template) {
689 		cb_severe_wx_save_as_template();
690 		return;
691 	}
692 	string def_severe_wx_filename = def_severe_wx_TemplateName;
693 	const char *p = FSEL::saveas(
694 			"Save template file",
695 			string("Template file\t*").append(TSWX_EXT).c_str(),
696 			def_severe_wx_filename.c_str());
697 	if (p) {
698 		update_header(CHANGED);
699 		update_severe_wxfields();
700 		buffsevere_wx.assign(header("<severe_wx>"));
701 		make_buff_severe_wx();
702 		write_severe_wx(p);
703 	}
704 }
705 
cb_severe_wx_save_as_template()706 void cb_severe_wx_save_as_template()
707 {
708 	string def_severe_wx_filename = def_severe_wx_TemplateName;
709 	const char *p = FSEL::saveas(
710 			"Save as template file",
711 			string("Template file\t*").append(TSWX_EXT).c_str(),
712 			def_severe_wx_filename.c_str());
713 	if (p) {
714 		const char *pext = fl_filename_ext(p);
715 		def_severe_wx_TemplateName = p;
716 		if (strlen(pext) == 0) def_severe_wx_TemplateName.append(TSWX_EXT);
717 		remove_spaces_from_filename(def_severe_wx_TemplateName);
718 
719 		clear_header();
720 		update_header(CHANGED);
721 		update_severe_wxfields();
722 		buffsevere_wx.assign(header("<severe_wx>"));
723 		make_buff_severe_wx();
724 		write_severe_wx(def_severe_wx_TemplateName);
725 
726 		show_filename(def_severe_wx_TemplateName);
727 		using_severe_wx_template = true;
728 	}
729 }
730 
cb_severe_wx_open()731 void cb_severe_wx_open()
732 {
733 	const char *p = FSEL::select(
734 			_("Open data file"),
735 			string("ICS-severe_wx\t*").append(FSWX_EXT).c_str(),
736 			def_severe_wx_filename.c_str());
737 	if (!p) return;
738 	if (strlen(p) == 0) return;
739 	clear_severe_wx_form();
740 	read_data_file(p);
741 	using_severe_wx_template = false;
742 	def_severe_wx_filename = p;
743 	show_filename(def_severe_wx_filename);
744 }
745 
write_severe_wx(string s)746 void write_severe_wx(string s)
747 {
748 	FILE *filesevere_wx = fopen(s.c_str(), "w");
749 	if (!filesevere_wx) return;
750 
751 	fwrite(buffsevere_wx.c_str(), buffsevere_wx.length(), 1, filesevere_wx);
752 	fclose(filesevere_wx);
753 }
754 
755 
cb_severe_wx_save_as()756 bool cb_severe_wx_save_as()
757 {
758 	const char *p;
759 	string newfilename;
760 
761 	string name = named_file();
762 	if (!name.empty()) {
763 		name.append(FSWX_EXT);
764 		newfilename = ICS_msg_dir;
765 		newfilename.append(name);
766 	} else
767 		newfilename = def_severe_wx_filename;
768 
769 	p = FSEL::saveas(
770 			_("Save data file"),
771 			string("ICS-severe_wx\t*").append(FSWX_EXT).c_str(),
772 			newfilename.c_str());
773 
774 	if (!p) return false;
775 	if (strlen(p) == 0) return false;
776 
777 	if (progStatus.sernbr_fname) update_sernbr();
778 
779 	const char *pext = fl_filename_ext(p);
780 	def_severe_wx_filename = p;
781 	if (strlen(pext) == 0) def_severe_wx_filename.append(FSWX_EXT);
782 
783 	remove_spaces_from_filename(def_severe_wx_filename);
784 
785 	update_header(NEW);
786 	update_severe_wxfields();
787 	buffsevere_wx.assign(header("<severe_wx>"));
788 	make_buff_severe_wx();
789 	write_severe_wx(def_severe_wx_filename);
790 
791 	using_severe_wx_template = false;
792 	show_filename(def_severe_wx_filename);
793 	return true;
794 }
795 
cb_severe_wx_save()796 void cb_severe_wx_save()
797 {
798 	if (base_severe_wx_filename == string("new").append(FSWX_EXT) ||
799 		base_severe_wx_filename == string("default").append(FSWX_EXT) ||
800 		using_severe_wx_template == true) {
801 		cb_severe_wx_save_as();
802 		return;
803 	}
804 
805 	if (check_severe_wxfields()) update_header(CHANGED);
806 	update_severe_wxfields();
807 	buffsevere_wx.assign(header("<severe_wx>"));
808 	make_buff_severe_wx();
809 	write_severe_wx(def_severe_wx_filename);
810 
811 	using_severe_wx_template = false;
812 }
813 
quad_to_html(string & target,SWX_QUAD * p)814 static void quad_to_html( string &target, SWX_QUAD *p)
815 {
816 	string X = "x"; string SP = "_";
817 	string sval = " ";
818 	string del = "";
819 	char szval[20];
820 	while (p->qtype != E) {
821 		if (p->qtype == B)
822 			replacestr(target, p->html_fld, *((bool *)(p->ptr)) ? X : SP);
823 		else if (p->qtype == S || p->qtype == O || p->qtype == D) {
824 			string s = *((string *)(p->ptr));
825 			if (p->html_fld == ":state:") {
826 				if (s.length() > 1) s.erase(2);
827 				replacestr(target, p->html_fld, s);
828 			} else if (p->html_fld == ":zone") {
829 				size_t cp = s.find(',');
830 				s.erase(cp);
831 				replacestr(target, p->html_fld, s);
832 			} else if (s.find("--") == 0) {
833 				replacestr(target, p->html_fld, del);
834 			} else {
835 				replacestr(target, p->html_fld, *((string *)(p->ptr)));
836 			}
837 		} else if (p->qtype == M) {
838 			sval = *((string *)(p->ptr));
839 			size_t np = string::npos;
840 			while ( (np = sval.find("\n")) != string::npos)
841 				sval.replace(np, 1, "<br>");
842 			replacestr(target, p->html_fld, sval);
843 		} else if (p->qtype == T)
844 			replacestr(target, p->html_fld, *((string *)(p->ptr)));
845 		else if (p->qtype == C) {
846 			sval = " ";
847 			sval[0] = *((char *)(p->ptr));
848 			replacestr(target, p->html_fld, sval);
849 		}
850 		else if (p->qtype == I) {
851 			if (*((int *)(p->ptr)) > 0) {
852 				snprintf(szval, sizeof(szval), "%d", *((int *)(p->ptr)) );
853 				sval = szval;
854 			} else sval.clear();
855 				replacestr(target, p->html_fld, sval);
856 		}
857 		else if (p->qtype == F) {
858 			if (*((float *)(p->ptr)) != 0) {
859 				snprintf(szval, sizeof(szval), "%f", *((float *)(p->ptr)));
860 				sval = szval;
861 			} else sval.clear();
862 			replacestr(target, p->html_fld, sval);
863 		}
864 		p++;
865 	}
866 }
867 
cb_severe_wx_html()868 void cb_severe_wx_html()
869 {
870 	string name_name = fl_filename_name(def_severe_wx_filename.c_str());
871 	size_t p = name_name.rfind('.');
872 	if (p != string::npos) name_name.erase(p);
873 
874 	string severe_wx_rptsta = ICS_dir;
875 	severe_wx_rptsta.append(name_name);
876 	severe_wx_rptsta.append(".html");
877 
878 	update_severe_wxfields();
879 	string formsevere_wx = severe_wx_html_template;
880 
881 	replacestr(formsevere_wx, TITLE, name_name);
882 
883 	quad_to_html (formsevere_wx, severe_wx_QUAD);
884 
885 	FILE *filesevere_wx = fopen(severe_wx_rptsta.c_str(), "w");
886 	fprintf(filesevere_wx,"%s", formsevere_wx.c_str());
887 	fclose(filesevere_wx);
888 
889 	open_url(severe_wx_rptsta.c_str());
890 }
891 
quad_to_text(string & target,SWX_QUAD * p)892 static void quad_to_text( string &target, SWX_QUAD *p)
893 {
894 	string X = "X"; string SP = " ";
895 	string sval = " ";
896 	string del = "";
897 	char szval[20];
898 	while (p->qtype != E) {
899 		if (p->qtype == B) {
900 			bool b = *((bool *)(p->ptr));
901 			if (b) replacestr(target, p->html_fld, X);
902 			else replacestr(target, p->html_fld, SP);
903 		} else if (p->qtype == S || p->qtype == M ||
904 					p->qtype == O || p->qtype == D) {
905 			string s = *((string *)(p->ptr));
906 			if (p->html_fld == ":state:") {
907 				if (s.length() > 1) s.erase(2);
908 				replacestr(target, p->html_fld, s);
909 			} else if (p->html_fld == ":zone") {
910 				size_t cp = s.find(',');
911 				s.erase(cp);
912 				replacestr(target, p->html_fld, s);
913 			} else if (s.find("--") == 0) {
914 				replacestr(target, p->html_fld, del);
915 			} else {
916 				if (((string *)(p->ptr))->length())
917 					replacestr(target, p->html_fld, *((string *)(p->ptr)));
918 				else replacestr(target, p->html_fld, del);
919 			}
920 		} else if (p->qtype == T) {
921 			if (((string *)(p->ptr))->length())
922 				replacestr(target, p->html_fld, *((string *)(p->ptr)));
923 			else replacestr(target, p->html_fld, del);
924 		} else if (p->qtype == C) {
925 			sval = " ";
926 			sval[0] = *((char *)(p->ptr));
927 			if (sval[0] != 0 && sval[0] != ' ')
928 				replacestr(target, p->html_fld, sval);
929 			else replacestr(target, p->html_fld, del);
930 		}
931 		else if (p->qtype == I) {
932 			if (*((int *)(p->ptr)) > 0) {
933 				snprintf(szval, sizeof(szval), "%d", *((int *)(p->ptr)) );
934 				sval = szval;
935 				replacestr(target, p->html_fld, sval);
936 			} else replacestr(target, p->html_fld, del);
937 		}
938 		else if (p->qtype == F) {
939 			if (*((float *)(p->ptr)) != 0) {
940 				snprintf(szval, sizeof(szval), "%f", *((float *)(p->ptr)));
941 				sval = szval;
942 				replacestr(target, p->html_fld, sval);
943 			} else replacestr(target, p->html_fld, del);
944 		}
945 		p++;
946 	}
947 }
948 
cb_severe_wx_textout()949 void cb_severe_wx_textout()
950 {
951 	string severe_wx_rptsta = ICS_dir;
952 	severe_wx_rptsta.append("severe_wx.txt");
953 
954 	update_severe_wxfields();
955 	string formsevere_wx = severe_wx_text_template;
956 
957 	quad_to_text (formsevere_wx, severe_wx_QUAD);
958 
959 	FILE *filesevere_wx = fopen(severe_wx_rptsta.c_str(), "w");
960 	fprintf(filesevere_wx,"%s", formsevere_wx.c_str());
961 	fclose(filesevere_wx);
962 
963 	open_url(severe_wx_rptsta.c_str());
964 }
965 
966