#!/usr/bin/perl -CIOEio

#
# Automatic dependency maintainer for Tsukurimashou
# Copyright (C) 2011  Matthew Skala
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, version 3.
#
# As a special exception, if you create a document which uses this font, and
# embed this font or unaltered portions of this font into the document, this
# font does not by itself cause the resulting document to be covered by the
# GNU General Public License. This exception does not however invalidate any
# other reasons why the document might be covered by the GNU General Public
# License. If you modify this font, you may extend this exception to your
# version of the font, but you are not obligated to do so. If you do not
# wish to do so, delete this exception statement from your version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program.  If not, see <http://www.gnu.org/licenses/>.
#
# Matthew Skala
# http://ansuz.sooke.bc.ca/
# mskala@ansuz.sooke.bc.ca
#

$#ARGV>=0 || die "Need a directory to scan";

$dir=shift;

$/=undef;

while (<$dir/*.mp>) {
  next if m!/tsuku-!;
  next if m!intro\.!;
  m!/([^/]+)\.mp$!;
  $file=$1;
  open(MPFILE,$_);
  $content=<MPFILE>;
  close(MPFILE);
  while ($content=~/^(var)?def\s+([a-z0-9_.]+)\s*(\(|=)(.*?)enddef;/msg) {
    $macro=$2;
    $defn{$macro}=$4;
    if (($infile{$macro} ne '') && ($infile{$macro} ne $file)) {
      $multiple_file{$macro}=1;
    }
    $infile{$macro}=$file;
  }
}

foreach $macroa (keys %infile) {
  next if $multiple_file{$macroa};
  foreach $macrob (keys %infile) {
    next if $multiple_file{$macrob};
    $macroc=$macrob;
    $macroc=~s/\./\\./g;
    if ($defn{$macroa}=~/\b$macroc\b/) {
      $macrodep{$macroa}.="$macrob\n";
    }
  }
}

while (@ARGV) {
  $file=shift;
print "Scanning $file...\n";
  open(MPFILE,$file);
  $content=<MPFILE>;
  close(MPFILE);
  if ($content=~/^(.*)\n% AUTODEPS\n((input (.*?)\.mp;\n)*)\n(.*)$/s) {
    $filestart=$1;
    $olddeps=$2;
    $fileend=$5;
    
    %seen=();
    @queue=();
    foreach $macro (keys %infile) {
      next if $multiple_file{$macro};
      next if $seen{$macro};
      $macroc=$macro;
      $macroc=~s/\./\\./g;
      next unless $content=~/\b$macroc\b/;
      $seen{$macro}=1;
      push @queue,$macro;
    }
    
    %incfile=();
    while (@queue) {
      $macro=pop @queue;
      $incfile{$infile{$macro}}=1;
      foreach $macrob (split("\n",$macrodep{$macro})) {
        next if $seen{$macrob};
        $seen{$macrob}=1;
        push @queue,$macrob;
      }
    }
    
    $newdeps='';
    foreach $ifile (sort keys %incfile) {
      $newdeps.="input $ifile.mp;\n";
    }
    if ($newdeps ne $olddeps) {
      print "   editing!\n";
      open(MPFILE,">$file");
      print MPFILE "$filestart\n% AUTODEPS\n$newdeps\n$fileend";
      close(MPFILE);
    }
  }
}
