#!/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 "sol2dat: " msg >> "/dev/stderr"
	m1 = "[-h|-a] [-bl N] (RUN|QFILE|-) OFILE LAB ..."
	print "usage: sol2dat " m1 >> "/dev/stderr"
	err = 1
	exit 1
}

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

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

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

BEGIN {
	check_lang("sol2dat")
	
	if(ARGC < 2 || ARGV[1] == "-h") print_usage()
	if(ARGC < 4) print_usage("too few arguments")

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

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

	ARGV[1] = run_name(ARGV[curr_arg++])
	
	soutf         = ARGV[curr_arg++]
	plines[soutf] = 0
	
	for(i=curr_arg; i<ARGC; ++i) labs[ARGV[i]] = 0
	
	state = 0
	skip  = 0
	ARGC  = 2
}

# IBR  MTOT  ITP  LAB  NFPR  ISW  NTPL  NAR  NROWPR  NTST  NCOL  NPARX
#  1     2    3    4     5    6     7    8      9     10    11     12

NF > 0 {
	if(state==0) {        ### initial state
		if($4 in labs) {
			labs[$4]++
			state=1
			M=$7         # NTST*NCOL+1 number of mesh points
			N=$8         # NDIM+1      dimension of the problem
			LPP=int(N/7) #             lines per time point
			if(LPP*7<N) ++LPP
			lines=LPP
			line=""
			skip=$9
		} else {
			state=2
			skip=$9
		}
	} else if(state==1) { ### process solution
		--skip
		line=line $0
		if(--lines==0) {
			printa(line,soutf)
			line=""
			lines=LPP
			if(--M==0) {
				for(i=0; i<blank_lines; ++i) printa(line,soutf)
				state=2
			}
		}
	} else if(state==2) { ### skip solution
		if(--skip==0) state=0
	}
}

END {
	if(err == "") {
		for(lab in labs)
			if(!labs[lab])
				print "sol2dat: warning, label " lab " not found" >> "/dev/stderr"
	}
}

# Algebraic problems: (autlib1.f:2698: SUBROUTINE WRTSP8)
#
# WRITE(8,101)IBR,MTOT,ITP,LAB,NFPR,ISW,NTPL,NAR,NROWPR,0,0,NPARX
# WRITE(8,102)T,(U(I),I=1,NDIM)
# WRITE(8,102)(PAR(I),I=1,NPARX)

# Boundary value problems: (autlib1.f:5588: SUBROUTINE WRTBV8)
#
# Writes plotting and restart data on unit 8, viz.:
# (1) data identifying the corresponding point on unit 7,
# (2) the complete solution,
# (3) the direction of the branch.
#
# Specifically the following is written:
#
#  IBR   : The index of the branch.
#  NTOT  : The index of the point.
#  ITP   : The type of point (see STPLBV above).
#  LAB   : The label of the point.
#  NFPR : The number of free parameters used in the computation.
#  ISW   : The value of ISW used in the computation.
#  NTPL  : The number of points in the time interval [0,1] for which
#          solution values are written.
#  NAR   : The number of values written per point.
#          (NAR=NDIM+1, since T and U(i), i=1,..,NDIM are written).
#  NROWPR: The number of lines printed following the identifying line
#          and before the next data set or the end of the file.
#          (Used for quickly skipping a data set when searching).
#  NTST  : The number of time intervals used in the discretization.
#  NCOL  : The number of collocation points used.
#  NPARX : The dimension of the array PAR.
#
#  Following the above described identifying line there are NTPL lines
# containing :
#     T , U-1(T) , U-2(T) , ... , U-NDIM(T),
# where NDIM is the dimension of the system of differential equations.
#
# Following this is a line containing the indices of the free parameters
#    ICP(I),I=1,NFPR,
#
# followed by a line containing the values
#    RL-dot(i) , i=1,NFPR,
#
# and following this are NTPL lines each containing
#    U-dot-1(T), U-dot-2(T), ... , U-dot-NDIM(T).
#
# Finally the parameter values PAR(i) , i=1,NPARX, are written.
#
#  Above, RL-dot(.) and U-dot(.) specify the direction of the branch.
