#!/bin/sh
if [ $# -ne 1 ] ; then
  echo "Usage: `basename $0` <parameter file>
Partial CHARMM output is expected on STDIN; parameters are written to STDOUT.
Only supports missing BOND, ANGLE and DIHEDRAL parameters."
  exit 1
 fi
awk -v par=$1 '/^ <CODES>: No /{
    if ($3=="torsion") tnp=4
     else if ($3=="angle") tnp=3
       else if ($3=="bond") tnp=2
	 else next;
    for(i=1;i<=npa;i++) if(tnp==typ[i]) if(mexact(i,tnp,7)) next;
    typ[++npa]=tnp;j=7;for(i=1;i<=tnp;i++) at[npa,i]=$(++j);
    p="";for(i=1;i<npa;i++) if(tnp!=2 && tnp==typ[i]) if(mapprox(i,tnp,7)) {
          p=app[i];break};
    if (!p) {p=++ngrp;lead[i]=""};
    app[npa]=p;nap[p]++}
  END{print "Exact matches:";
    bond=1;while (getline < par) {if ($0~"^IMP[RH]") break;
      fa="";fp="";for(i=1;i<=npa;i++){t=typ[i];
        if ($t~"^[\-0-9]" || $(t+1)!~"^[\-0-9]") continue;
        api=app[i];npi=nap[api];if(!fa) if(mexact(i,t,0)) {
	  if (!(i in exa)) {exa[i]="";nap[api]=--npi};
	  print $0;fa=1};
	if (bond || !(i in lead) || !npi || fp) continue;
        if (mapprox(i,t,0)) {prox[api,++npr[api]]=$0;fp=1};
	if (fa && fp) break };
      if ($0~"^ANGL") bond="" };
    printf("\nApproximate matches:\n");
    for(i=1;i<=ngrp;i++) if(nap[i]) {z=npr[i];
        for(j=1;j<=z;j++) print prox[i,j]} }
  function mexact(par,type,off) {
    f=1;j=off;for(k=1;k<=type;k++) if($(++j)!=at[par,k]){f="";break};
    if(!f) {f=1;j=off;for(k=type;k>=1;k--) if($(++j)!=at[par,k]){f="";break} };
    return f}
  function mapprox(par,type,off) {
    tw=off+2;two=at[par,2];if (type==3) {if ($tw==two) return 1}
     else {th=off+3;thr=at[par,3];
      if (($tw==two && $th==thr)||($tw==thr && $th==two)) return 1} }'
