#include "types.h"
inherit Stdio.File : out;

string globalbase;
object windex;

// Conversion table:
//
// "*"		"\\(**"
// "\\"		"\\e"
// "()"		"(\\|)"
// " - "	" \\- "

void make_page(string base, TAG tag, string ind, string fbase);

void mkdirhier(string what)
{
   string d=".";
   foreach (what/"/",string add)
   {
      d+="/"+add;
      mkdir(d);
   }
}

string make_manpage(string base, SGML data, string ind, string fbase)
{
   string res="";
   int stripws=1;

   if (stringp(data))
   {
      sscanf(data,"%*[ \t\n\r]%s",data);
      res+=data;
   }
   else if(arrayp(data))
      foreach (data, TAG tag)
	 if (objectp(tag))
	 {
	    switch (tag->tag)
	    {
	       case "method":
	       case "function":
	       case "constant":
	       case "class":
	       case "module":
	       case "variable":
		  make_page(base,tag,ind,fbase);
		  continue;

	       case "man_title":
		  res+="\n.SH "+tag->params->title+"\n";
		  stripws=1;
		  break;

	       case "p":
		  res+="\n.PP\n";
		  stripws=1;
		  break;
	       case "br":
		  res+="\n.br\n";
		  stripws=1;
		  break;

	       case "link":
	       case "i": 
	       case "emboss":
		  res+="\\f2"+make_manpage(base,tag->data,ind,fbase)+"\\f1";
		  continue;

	       case "b": 
	       case "strong":
		  res+="\\f3"+make_manpage(base,tag->data,ind,fbase)+"\\f1";
		  continue;

	       case "pre":
		  res+="\n.nf\n"+make_manpage(base,tag->data,ind,fbase)
		     +"\n.fi\n";
		  stripws=0;
		  continue;
	    }
	    res+=make_manpage(base,tag->data,ind,fbase);
	 }
	 else if (stringp(tag))
	 {
	    if (stripws) sscanf(tag,"%*[ \t\n\r]%s",tag);
	    res+=tag;
	    stripws=0;
	 }

   return res;
}

string strip_eightbit(string s)
{
  return(s & String.strmult("\177", sizeof(s)));
}

int pages=0;

void make_page(string base, TAG tag, string ind, string fbase)
{
//   werror(ind+tag->tag+" "+tag->params->name+"\n");
 
   werror("manpage "+(++pages)+"...\r");

   mixed err = catch {

   string *outfiles,*names,*s_outfiles;
   string obase=base;
   string q;

   outfiles=Array.map(names=tag->params->name/",",
			  lambda(string s,string t,string u,string base)
			  {
			     s=replace(s,"->",".");
			     sscanf(s,t+".%s",s);
			     return u+"/"+s+"."+base;
			  },fbase,globalbase+base,base);

   sscanf(outfiles[0],"%*s/man%*s/%s",q);
   if (q) {
     array(string) a = q/".";
     if (sizeof(a) > 1) {
       q = a[..sizeof(a)-2]*".";
     }
   }
   
//   werror("files: "+outfiles*", "+"\n");

   if (tag->params->mansuffix)
   {
      base+=tag->params->mansuffix;
      fbase=(tag->params->name/",")[0];
      mkdirhier(globalbase+base);
   }

   string page=make_manpage(base,tag->data,ind+" ",fbase);

//   werror("creating "+outfiles[0]+"...\n"); 

   object f=Stdio.File(outfiles[0],"wtc");
   string t=ctime(time());
   f->write(strip_eightbit(".\\\" t\n"
			   ".\\\" automatic generated from wmml\n"
			   ".TH "+names*","+" "+obase+" \""+
			   t[8..9]+t[3..7]+t[20..23]+"\" Pike \"Pike Manual\"\n"
			   +page+"\n"));
   f->close();

   foreach (outfiles[1..],string s)
   {
      string name;
      sscanf(outfiles[0],"man/%s",name);
//      werror("creating "+s+" -> "+name+"...\n"); 
      object f=Stdio.File(s ,"wtc");
      f->write(".so "+name+"\n");
      f->close();
   }

   foreach (({q})+names,string s)
      windex->write(sprintf("%-15s %-15s - %s\n",
			    s,q+" ("+obase+")",
			    tag->params->title || (names*", ")));

   };
   if (err)
	 werror("Error while making manpage for "+tag->name+" ("+base+"):\n"
		+master()->describe_backtrace(err));
}

void make_pages(string base, SGML data, string ind, string fbase)
{
   if (arrayp(data))
      foreach (data, TAG tag)
	 if (objectp(tag))
	    if ((<"method","function","class","module">)[tag->tag])
	       make_page(base,tag,ind,fbase);
	    else
	       make_pages(base,tag->data,ind,fbase);
}

void output(string base, WMML data)
{
   globalbase="man/man";
   mkdirhier("man/man3p");
   windex=Stdio.File("man/windex","wtc");
   make_pages("3p",data->data,"","");
}