/*==================================================================
  ==================================================================
  ==	XMusic -- An Interactive Interface to Csound		  ==
  ==       Copyright (C) 1988 by George D. Drapeau                ==
  ==                  All Rights Reserved                         ==
  ==================================================================
  ==================================================================
*/
/* $Log:	writeorch.c,v $
 * Revision 1.4  89/08/06  18:16:54  drapeau
 * Cleaned up the code for the first X11 release.
 *  */

#include <X11/X.h>
#include <X11/Xlib.h>
#include <X11/Xutil.h>
#include <stdio.h>
#include <string.h>
#include "defs.h"
#include "externs.h"

WriteInstrument(tool)
     Tool	*tool;
{
  char	RateToChar();
  
  if (tool->input1)						    /* Does this tool have an input1? */
    WriteInstrument(tool->input1);				    /* Yes, write that tool's Csound code first */
  if (tool->input2)						    /* Does this tool have an input2? */
    WriteInstrument(tool->input2);				    /* Yes, write that tool's Csound code second */
  if (tool->input3)						    /* Does this tool have an input3? */
    WriteInstrument(tool->input3);				    /* Yes, write that tool's Csound code third */
  if (tool->input4)						    /* Does this tool have an input4? */
    WriteInstrument(tool->input4);				    /* Yes, write that tool's Csound code fourth */
  if (tool->input5)						    /* Does this tool have an input5? */
    WriteInstrument(tool->input5);				    /* Yes, write that tool's Csound code fifth */
  if (tool->input6)						    /* Does this tool have an input6? */
    WriteInstrument(tool->input6);				    /* Yes, write that tool's Csound code sixth */
  if (tool->input7)						    /* Does this tool have an input7? */
    WriteInstrument(tool->input7);				    /* Yes, write that tool's Csound code seventh */
  if (tool->input8)						    /* Does this tool have an input8? */
    WriteInstrument(tool->input8);				    /* Yes, write that tool's Csound code eighth */

  if (tool->type != ParamTool)
    {
      fprintf(orchFile,"\n");					    /* Start a new line for this entry in the Csound file */
      fprintf(orchFile,"%c%s\t", RateToChar(tool->rate),	    /* Write the name of this tool to the Csound file */
	      tool->name);
      if ((tool->type == EQTool) ||				    /* EQTools and SumTools look like...  */
	  (tool->type == SumTool))				    /* "aeqtool3 = <expression>", so... */
	fprintf(orchFile,"= ");					    /* ...put an equals sign between tool name and fct. */
      if (tool->type != SumTool)				    /* SumTools are infix operators, so don't write fName yet */
	fprintf(orchFile,"%s\t\t",tool->fName);			    /* If appropriate, write the corresponding Csound fct. */
    }
  if (tool->input1)						    /* Does this tool have a first input? */
    {								    /* Yes, determine which name to use for the input name */
      if ((tool->input1->type == EQTool) ||			    /* Use the equation or parameter name */
	  (tool->input1->type == ParamTool))
	fprintf(orchFile,"%s",tool->input1->fName);
      else							    /* Use the name of the tool */
	fprintf(orchFile,"%c%s",RateToChar(tool->input1->rate),
		tool->input1->name);
    }
  else
    if (tool->arg1)						    /* Should the default value be used for 1st param? */
      fprintf(orchFile,"%s",tool->arg1);			    /* Yes, write the argument's value to the Csound file */
  if (tool->input2)						    /* Is there a second input for this tool? */
    {
      if (tool->type == SumTool)				    /* Are we writing arguments for a SumTool? (ie, +,-,*,/) */
	fprintf(orchFile," %s ",tool->fName);			    /* Yes, write the operator (+,-,*,/) */
      else							    /* No, so write a "," to separate arguments */
	fprintf(orchFile,", ");
      if ((tool->input2->type == EQTool) ||			    /* Use the equation or parameter name */
	  (tool->input2->type == ParamTool))
	fprintf(orchFile,"%s",tool->input2->fName);
      else							    /* Use the name of the tool */
	fprintf(orchFile,"%c%s",RateToChar(tool->input2->rate),
		tool->input2->name);
    }
  else
    if (tool->arg2)						    /* Should the default value be used for 2nd param? */
      fprintf(orchFile,", %s",tool->arg2);			    /* Yes, write the argument's value to the Csound file */
  if (tool->input3)						    /* Is there another input for this tool? */
    {
      if (tool->type == SumTool)				    /* Are we writing arguments for a SumTool? (ie, +,-,*,/) */
	fprintf(orchFile," %s ",tool->fName);			    /* Yes, write the operator (+,-,*,/) */
      else							    /* No, so write a "," to separate arguments */
	fprintf(orchFile,", ");
      if ((tool->input3->type == EQTool) ||			    /* Use the equation or parameter name */
	  (tool->input3->type == ParamTool))
	fprintf(orchFile,"%s",tool->input3->fName);
      else							    /* Use the name of the tool */
	fprintf(orchFile,"%c%s",RateToChar(tool->input3->rate),
		tool->input3->name);
    }
  else
    if (tool->arg3)						    /* Should the default value be used for this param? */
      fprintf(orchFile,", %s",tool->arg3);			    /* Yes, write the argument's value to the Csound file */
  if (tool->input4)						    /* Is there another input for this tool? */
    {
      if (tool->type == SumTool)				    /* Are we writing arguments for a SumTool? (ie, +,-,*,/) */
	fprintf(orchFile," %s ",tool->fName);			    /* Yes, write the operator (+,-,*,/) */
      else							    /* No, so write a "," to separate arguments */
	fprintf(orchFile,", ");
      if ((tool->input4->type == EQTool) ||			    /* Use the equation or parameter name */
	  (tool->input4->type == ParamTool))
	fprintf(orchFile,"%s",tool->input4->fName);
      else							    /* Use the name of the tool */
	fprintf(orchFile,"%c%s",RateToChar(tool->input4->rate),
		tool->input4->name);
    }
  else
    if (tool->arg4)						    /* Should the default value be used for this param? */
      fprintf(orchFile,", %s",tool->arg4);			    /* Yes, write the argument's value to the Csound file */
  if (tool->input5)						    /* Is there another input for this tool? */
    {
      if (tool->type == SumTool)				    /* Are we writing arguments for a SumTool? (ie, +,-,*,/) */
	fprintf(orchFile," %s ",tool->fName);			    /* Yes, write the operator (+,-,*,/) */
      else							    /* No, so write a "," to separate arguments */
	fprintf(orchFile,", ");
      if ((tool->input5->type == EQTool) ||			    /* Use the equation or parameter name */
	  (tool->input5->type == ParamTool))
	fprintf(orchFile,"%s",tool->input5->fName);
      else							    /* Use the name of the tool */
	fprintf(orchFile,"%c%s",RateToChar(tool->input5->rate),
		tool->input5->name);
    }
  else
    if (tool->arg5)						    /* Should the default value be used for this param? */
      fprintf(orchFile,", %s",tool->arg5);			    /* Yes, write the argument's value to the Csound file */
  if (tool->input6)						    /* Is there another input for this tool? */
    {
      if (tool->type == SumTool)				    /* Are we writing arguments for a SumTool? (ie, +,-,*,/) */
	fprintf(orchFile," %s ",tool->fName);			    /* Yes, write the operator (+,-,*,/) */
      else							    /* No, so write a "," to separate arguments */
	fprintf(orchFile,", ");
      if ((tool->input6->type == EQTool) ||			    /* Use the equation or parameter name */
	  (tool->input6->type == ParamTool))
	fprintf(orchFile,"%s",tool->input6->fName);
      else							    /* Use the name of the tool */
	fprintf(orchFile,"%c%s",RateToChar(tool->input6->rate),
		tool->input6->name);
    }
  else
    if (tool->arg6)						    /* Should the default value be used for this param? */
      fprintf(orchFile,", %s",tool->arg6);			    /* Yes, write the argument's value to the Csound file */
  if (tool->input7)						    /* Is there another input for this tool? */
    {
      if (tool->type == SumTool)				    /* Are we writing arguments for a SumTool? (ie, +,-,*,/) */
	fprintf(orchFile," %s ",tool->fName);			    /* Yes, write the operator (+,-,*,/) */
      else							    /* No, so write a "," to separate arguments */
	fprintf(orchFile,", ");
      if ((tool->input7->type == EQTool) ||			    /* Use the equation or parameter name */
	  (tool->input7->type == ParamTool))
	fprintf(orchFile,"%s",tool->input7->fName);
      else							    /* Use the name of the tool */
	fprintf(orchFile,"%c%s",RateToChar(tool->input7->rate),
		tool->input7->name);
    }
  else
    if (tool->arg7)						    /* Should the default value be used for this param? */
      fprintf(orchFile,", %s",tool->arg7);			    /* Yes, write the argument's value to the Csound file */
  if (tool->input8)						    /* Is there another input for this tool? */
    {
      if (tool->type == SumTool)				    /* Are we writing arguments for a SumTool? (ie, +,-,*,/) */
	fprintf(orchFile," %s ",tool->fName);			    /* Yes, write the operator (+,-,*,/) */
      else							    /* No, so write a "," to separate arguments */
	fprintf(orchFile,", ");
      if ((tool->input8->type == EQTool) ||			    /* Use the equation or parameter name */
	  (tool->input8->type == ParamTool))
	fprintf(orchFile,"%s",tool->input8->fName);
      else							    /* Use the name of the tool */
	fprintf(orchFile,"%c%s",RateToChar(tool->input8->rate),
		tool->input8->name);
    }
  else
    if (tool->arg8)						    /* Should the default value be used for this param? */
      fprintf(orchFile,", %s",tool->arg8);			    /* Yes, write the argument's value to the Csound file */
  tool->visited = TRUE;						    /* Mark this node as visited */
}								    /* end function WriteInstrument */



void WriteOrchFile()
{
  Tool	*tool;
  int	instrNum = 1;

  if ((orchFile = fopen(orchFileName,"w")) == NULL)
    {
      printf("Can't create a Csound file for writing.\n");
      exit(1);
    }
  printf("Writing the diagram to a Csound file called %s.\n",orchFileName);
  fprintf(orchFile,";;;Csound file %s, Written by XMusic.\n",orchFileName); /* Write Csound header information */
  fprintf(orchFile,"\t\tsr = 20000\n\t\tkr = 500\n");
  fprintf(orchFile,"\t\tksmps = 40\n\t\tnchnls = 1\n\n");
  for (tool = toolList; tool; tool = tool->next)		    /* Mark all nodes in the diagram as not yet visited */
    tool->visited = FALSE;
  while(1)
    {
      for (tool = toolList;					    /* Find the first tool in the list that has not... */
	   (tool != NULL) && (tool->visited == TRUE);		    /* ...yet been visited */
	   tool = tool->next)
	;
      if (tool == NULL)						    /* If there are no more tools to examine, exit... */
	break;							    /* ...the outer while loop. */
      fprintf(orchFile,"\t\tinstr\t%d",instrNum++);		    /* Write a new name for this instrument */
      for ( ; tool->output; tool = tool->output)		    /* Find the end of this chain of tools, in other words... */
	;							    /* ...the final output of one instrument */
      WriteInstrument(tool);					    /* Write all the tools comprising this instrument */
      fprintf(orchFile,"\nout\t\t%c%s\n",RateToChar(tool->rate),
	      tool->name);
      fprintf(orchFile,"\t\tendin\n\n");
    }								    /* end while loop */
  fclose(orchFile);						    /* Close the orchestra file */
  printf("Done writing the Csound file.\n");
}								    /* end function WriteOrchFile */

