#! /usr/bin/gawk -f
# Last edited on 2003-09-18 11:17:09 by stolfi

BEGIN \
  { usage = ( ARGV[0] " [-v dir=PATH] -v topName=NAME < INFILE.pov" );
    abort = -1;

    if (dir == "") { dir = "."; }
    if (topName == "") { arg_error("must define \"topName\""); }

    # Output files:
    topf = ( dir "/" topName "-NEW.pov" );      
    viwf = ( dir "/dcc-view-x-NEW.inc" );     
    camf = ( dir "/dcc-camera-NEW.inc" );     
    litf = ( dir "/dcc-lights-x-NEW.inc" );   
    posf = ( dir "/dcc-pose-x-NEW.inc" );     
    basf = ( dir "/dcc-base-x-NEW.inc" );     
    abaf = ( dir "/dcc-abacus-x-NEW.inc" );  
    rinf = ( dir "/dcc-ring-x-NEW.inc" );  
    etcf = ( dir "/etc-NEW.inc" );            

    # printf "topf=%s\n", topf > "/dev/stderr";
    # printf "viwf=%s\n", viwf > "/dev/stderr";
    # printf "camf=%s\n", camf > "/dev/stderr";
    # printf "litf=%s\n", litf > "/dev/stderr";
    # printf "posf=%s\n", posf > "/dev/stderr";
    # printf "basf=%s\n", basf > "/dev/stderr";
    # printf "abaf=%s\n", abaf > "/dev/stderr";
    # printf "rinf=%s\n", rinf > "/dev/stderr";
    # printf "etcf=%s\n", etcf > "/dev/stderr";

    printf "// Last edited on DATE TIME by USER\n\n" >> posf;
    printf "#declare abacus_turn = 000;\n" >> posf;
    printf "#declare abacus_scale = 1.0;\n" >> posf;

    # While these are true, everything goes to the specified file:
    to_basf = 0;
    to_camf = 0;
    to_litf = 0;
    
    # Indicate whether the the ".pof" file already had an "#include":
    had_viw = 0;
    had_lit = 0;
    had_pos = 0;
    had_bas = 0;
    had_aba = 0;
    had_rin = 0;
    had_sky = 0;
    
    # Count lines written to each file:
    abaf_ct = 0;
    rinf_ct = 0;
  }

(abort >= 0) { exit abort; }


# Lines that should be deleted:

/^ *[\/][\/] *[#]include/ { next; }
/^ *[\/][\/] *[#]declare/ { next; }
/^ *[\/][\/] *(object|translate|scale|rotate|texture|pigment|finish|[{}<>])/ { next; }
/^ *$/ { next; }

/^ *[#]declare  *abacus_shift_Y *= *abacus_bottom_Y *[+] *abacus_frame_thickness[\/]2 *;/ \
  { printf "del %s\n", $0 > "/dev/stderr"; next; }


# Lines that should remain in the top-level ".pov" file:

/^[\/][\/] *POV/ \
  { printf "%s\n", $0 >> topf; next; }
  
/^[\/][\/] *Last edited/ \
  { printf "%s\n\n", $0 >> topf; next; }
  
/^[#]include *["]background[.]inc["]/ \
  { printf "%s\n\n", $0 >> topf; next; }
  
/^[ \/]*global/ \
  { printf "%s\n\n", $0 >> topf; next; }
  
/^[#]include *["]dcc-view-[0-9a-z][.]inc["]/ \
  { printf "%s\n", $0 >> topf; had_viw = 1; next; }
  
/^[#]include *["]dcc-lights-[0-9a-z][.]inc["]/ \
  { printf "%s\n", $0 >> topf; had_lit = 1; next; }
  
/^[#]include *["]dcc-sky-[0-9a-z][.]inc["]/ \
  { printf "%s\n", $0 >> topf; had_sky = 1; next; }
  
/^[#]include *["]dcc-pose-[0-9a-z][.]inc["]/ \
  { printf "%s\n", $0 >> topf; had_pos = 1; next; }
  
/^[#]include *["]dcc-base-[0-9a-z][.]inc["]/ \
  { printf "%s\n", $0 >> topf; had_bas = 1; next; }
  
/^[#]include *["]dcc-abacus-[0-9a-z][.]inc["]/ \
  { printf "%s\n", $0 >> topf; had_aba = 1; next; }
  
/^[#]include *["]dcc-ring-[0-9a-z][.]inc["]/ \
  { printf "%s\n", $0 >> topf; had_rin = 1; next; }
  
/^[#]include *["](fgstyle|rgstyle)-[0-9a-z][.]inc["]/ \
  { printf "%s\n", $0 >> topf; next; }
  
/^[#]include ["]dcc-abacus-shape-0[0-9].inc["]/ \
  { n = $2; gsub(/^-0/, "", n); gsub(/[.]inc$/, "", n);
    printf "#include \"dcc-abacus-%d.inc\"\n", n >> topf;
    had_aba = 1;
    next;
  }

/^[#]include ["]dcc-std-abacus.inc["]/ \
  { printf "#include \"dcc-abacus-x.inc\"\n" >> topf;
    had_aba = 1;
    next;
  }

# Lines that describe the light sources:

/^ *light_source/ { to_litf = 1; }
(to_litf > 0) \
  { printf "%s\n", $0 >> litf; 
    if ($0 ~ /^ *[}]/) { to_litf = 0; }
    next;
  }
  

# Lines that define the view:

/^ *[#]declare  *cam(DX|DY|DZ)/ \
  { printf "%s\n", $0 >> viwf; next; }

/^ *[#]declare  *sky(X|Y|Z)/ \
  { printf "%s\n", $0 >> viwf; next; }


# Lines that define the camera:

/^ *camera */ { to_camf = 1; }
(to_camf > 0) \
  { printf "%s\n", $0 >> camf; 
    if ($0 ~ /^ *[}]/) { to_camf = 0; }
    next;
  }


# Lines that define the abacus's pose:

/^ *[#]declare  *abacus_bottom_Y/ \
  { printf "%s\n", $0 >> posf; next; }


# Lines that describe the base:

/^ *[#]declare  *show_/ \
  { printf "%s\n", $0 >> basf; next; }

/^ *[#]declare  *base_top_Y/ \
  { printf "%s\n", $0 >> basf; next; }

/^ *[#]if *[()] *show_/ { to_basf = 1; }
(to_basf > 0) \
  { printf "%s\n", $0 >> basf; 
    if ($0 ~ /^ *[#]end/) { to_basf = 0; }
    next;
  }


# Lines that describe the abacus:

/^ *[#]declare  *abacus_.*[;]/ \
  { printf "%s\n", $0 >> abaf; abaf_ct++; next; }

/^[#]include ["]dcc-abacus(|-special).inc["]/ \
  { printf "%s\n", $0 >> abaf; abaf_ct++; next; }
  
/^ *object *{ *abacus  *translate *< *0[.0]* *, *abacus_shift_Y *, *0[.0]* *> *} *$/ \
  { if (abaf_ct > 0) 
      { printf "%s\n", $0 >> abaf; abaf_ct++; }
    next;
  }

/^ *object *{ *abacus([{} ]|$)/ \
  { printf "%s\n", $0 >> abaf; abaf_ct++; next; }


# Lines that describe the ring:

/^ *[#]declare  *ring_.*[;]/ \
  { printf "%s\n", $0 >> rinf; rinf_ct++; next; }

/^[#]include ["]dcc-ring(|-special).inc["]/ \
  { printf "%s\n", $0 >> rinf; rinf_ct++; next; }
  
/^ *object *{ *ring  *translate *< *0[.0]* *, *ring_shift_Y *, *0[.0]* *> *} *$/ \
  { if (rinf_ct > 0) 
      { printf "%s\n", $0 >> rinf; rinf_ct++; }
    next;
  }

/^ *object *{ *ring([{} ]|$)/ \
  { printf "%s\n", $0 >> rinf; rinf_ct++; next; }

# All else should go to the "etc" file:

/^ *[\/][\/]/ \
  { print >> etcf; next; }


// \
  { print >> etcf; next; }

END \
  { if (abort >= 0) { exit abort; }
    if (! had_viw) { printf "#include \"dcc-view-x.inc\"\n\n" >> topf; }
    if (! had_lit) { printf "#include \"dcc-lights-x.inc\"\n\n" >> topf; }
    if (! had_pos) { printf "#include \"dcc-pose-x.inc\"\n\n" >> topf; }
    if (! had_bas) { printf "#include \"dcc-base-x.inc\"\n" >> topf; }
    if (! had_aba) { printf "#include \"dcc-abacus-x.inc\"\n" >> topf; }
    if (topName == "dcc-logo-ring")
      { if (! had_rin) { printf "#include \"dcc-ring-x.inc\"\n" >> topf; } 
        if (! had_sky) { printf "#include \"dcc-sky-x.inc\"\n" >> topf; } 
      }
    printf "\n#include \"etc.inc\"\n" >> topf;
    close(topf); close(posf); close(basf); 
    close(abaf); close(etcf); close(viwf);
    close(litf); close(camf); close(rinf);
  }

function data_warning(msg)
{
  printf "warning: line %d: %s\n", FNR, msg > "/dev/stderr";
}

function data_error(msg)
{
  printf "line %d: %s\n", FNR, msg > "/dev/stderr";
  abort = 1; exit abort;
}

function arg_error(msg)
{
  printf "%s\n", msg > "/dev/stderr";
  printf "usage: %s\n", usage > "/dev/stderr";
  abort = 1; exit abort;
}
