#!/usr/bin/awk -f

function check_lang(prg, cfmt,x,y,lang,m1,m2) {
	cfmt = CONVFMT
	lang = ENVIRON["LANG"]
	CONVFMT = "%+.3e"
	x = 1.23
	y = "" x
	if("+1.230e+00"!=y) {
		# try to change language to "C" at run time
		ENVIRON["LANG"] = "C"
		x = 1.23
		y = "" x
		if("+1.230e+00"!=y) {
			m1 = ": numeric format of language '"
			m2 = "' not supported"
			print prg m1 lang m2 >> "/dev/stderr"
			m1 = ": set the environment variable LANG to C before running "
			print prg m1 prg >> "/dev/stderr"
			err = 1
			exit 1
		}
	}
	CONVFMT = cfmt
}

function print_usage(msg, m1) {
	if(msg!="") print "bd2dat: " msg >> "/dev/stderr"
	m1 = "[-h|-a] [-bl N] (RUN|PFILE|-) [OFILE1 [OFILE2]] [-SP SPFILE ...]"
	print "usage: bd2dat " m1 >> "/dev/stderr"
	print "SP is one of: LP BP HB PD TR UZ RO EP MX" >> "/dev/stderr"
	err = 1
	exit 1
}

function printb(msg,file) {
	if(append) {
		print msg >> file
	} else {
		if(lines[file]++ == 0) {
			print msg  > file
		} else {
			print msg >> file
		}
	}
}

function printa(msg,file, i) {
	if(msg == "") {
		if(!was_blank[file])
			for(i=0; i<blank_lines; ++i)
				printb(msg,file)
		was_blank[file] = 1
	} else {
		printb(msg,file)
		was_blank[file] = 0
	}
}

function exists(fname, status) {
	status = getline < fname
	close(fname)
	return ( status != -1 )
}

function run_name(run, fname) {
	if(run == "-") return run
	
	fname = "data/p." run
	if(exists(fname)) return fname
	
	fname = run
	if(exists(fname)) return fname
	
	print "bd2dat: run or file '" run "' does not exist" >> "/dev/stderr"
	err = 1
	exit 1
}

BEGIN {
	check_lang("bd2dat")
	
	if(ARGC < 2 || ARGV[1] == "-h") print_usage()

	append      = 0
	blank_lines = 2
	curr_arg    = 1
	
	if(ARGC > curr_arg && ARGV[curr_arg]=="-a") {
		if(ARGC < 3) print_usage("too few arguments")
		append = 1
	}
	curr_arg += append

	if(ARGC > curr_arg && ARGV[curr_arg]=="-bl") {
		if(ARGC < 4+append) print_usage("too few arguments")
		blank_lines = ARGV[curr_arg+1]
		curr_arg += 2
	}

	ARGV[1] = run_name(ARGV[curr_arg++])
	
	sb_out = "/dev/null"
	ub_out = "/dev/null"
	
	if( ARGC>curr_arg && substr(ARGV[curr_arg],1,1)!="-" )
		sb_out = ARGV[curr_arg++]

	ub_out = sb_out
	if( ARGC>curr_arg && substr(ARGV[curr_arg],1,1)!="-" )
		ub_out = ARGV[curr_arg++]
	
	show_stab = (sb_out != ub_out)
	curr_out  = sb_out

	lines[sb_out]     = 0
	lines[ub_out]     = 0
	was_blank[sb_out] = 1
	was_blank[ub_out] = 1
	
	sp_types[1]  = "-BP"
	sp_types[2]  = "-LP"
	sp_types[3]  = "-HB"
	sp_types[4]  = "-RO"
	sp_types[-4] = "-UZ"
	sp_types[5]  = "-LP"
	sp_types[6]  = "-BP"
	sp_types[7]  = "-PD"
	sp_types[8]  = "-TR"
	sp_types[9]  = "-EP"
	sp_types[-9] = "-MX"

	sp_args["-BP"]
	sp_args["-LP"]
	sp_args["-HB"]
	sp_args["-RO"]
	sp_args["-UZ"]
	sp_args["-PD"]
	sp_args["-TR"]
	sp_args["-EP"]
	sp_args["-MX"]

	for(arg=curr_arg; arg<ARGC; arg+=2) {
		if(ARGC>arg+1) {
			if(ARGV[arg] in sp_args) {
				sp_file = ARGV[arg+1]
				for(i in sp_types)
					if(sp_types[i]==ARGV[arg]) {
						sp_out[i]          = sp_file
						lines[sp_file]     = 0
						was_blank[sp_file] = 1
					}
			} else {
				print_usage("special point type " ARGV[arg] " not recognized")
			}
		} else {
			print_usage("syntax error at argument " ARGV[arg])
		}
	}
	
	bp_types[1] = "BP"
	bp_types[2] = "LP"
	bp_types[3] = "HB"
	bp_types[5] = "LP"
	bp_types[6] = "BP"
	bp_types[7] = "PD"
	bp_types[8] = "TR"

	state = 0
	ARGC  = 2
}

# BR  PT  TY  LAB  PAR  L2-NORM  ...
#  1   2   3   4    5      6
              
$0 == "" { printa("",curr_out); state = 0; next }

$1 != 0 {
	if(show_stab) {
		
		# begin stability splitting
		if       (state==0) {
			last_line = substr($0,5)
			curr_out  = ($2<0) ? sb_out : ub_out
			state     = 1
			
		} else if(state==1) {
			stab = ($2<0) ? -1 : 1
			curr_out = (stab==1) ? ub_out : sb_out
			printa(last_line, curr_out)
			printa(substr($0,5), curr_out)
			last_line = substr($0,5)
			state     = 2
			
		} else if(stab*$2 > 0) {
			printa(substr($0,5), curr_out)
			last_line = substr($0,5)
			
		} else {
			pt_type = $3 % 10
			if(pt_type in bp_types) {
				printa(substr($0,5), curr_out)
				last_line = substr($0,5)
				printa("", curr_out)
				stab = ($2<0) ? -1 : 1
				curr_out = (stab==1) ? ub_out : sb_out
				printa(last_line, curr_out)
			} else {
				printa("", curr_out)
				stab = ($2<0) ? -1 : 1
				curr_out = (stab==1) ? ub_out : sb_out
				printa(last_line, curr_out)
				printa(substr($0,5), curr_out)
				last_line = substr($0,5)
 			}
			
		}
		#end stability splitting

	} else {
		printa(substr($0,5), sb_out)
	}
	
	pt_type = $3 % 10
	if( pt_type in sp_out) printa(substr($0,5), sp_out[pt_type])
}

END {
	if(state == 1) printa(last_line, curr_out)
	if(err == "") {
		for(file in lines) printa("",file)
	}
}
