/*==================================================================
  ==================================================================
  ==	XMusic -- An Interactive Interface to Csound		  ==
  ==       Copyright (C) 1988 by George D. Drapeau                ==
  ==                  All Rights Reserved                         ==
  ==								  ==
  == Permission to use, copy, modify, and distribute this 	  ==
  == software for any purpose is hereby granted, provided that 	  ==
  == the above copyright notice appear in all copies of this	  ==
  == software.  No warranty of any kind, either expressed or	  ==
  == implied, is provided with XMusic;  XMusic is provided	  ==
  == "as is".  No guarantees are made as to the quality or 	  ==
  == usefulness of this software.				  ==
  ==================================================================
  ==================================================================
*/

/* $Log:	xmusic.c,v $
 * Revision 1.4  89/08/06  18:17:26  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 <sys/file.h>
#include "defs.h"
#include "externs.h"


main(argc,argv)
     int	argc;
     char	**argv;
{
  Tool	*GetNewTool();

  Argc = argc;
  Argv = argv;
  toolList = NULL;						    /* Initialize the tool list */
  lastTool = NULL;						    /* Set last tool looked at to no tool at all */
  DoXEventLoop();						    /* Let another function take care of the X routines */
}								    /* end function main */



Tool	*GetNewTool()						    /* Allocate space for a new tool and return pointer to it */
{
  Tool		*toolPtr;
  char		*malloc();
  static int	toolNum = 1;

  toolPtr = (Tool *)malloc(sizeof(Tool));
  toolPtr->type		=	SineTool;
  toolPtr->visited	=	FALSE;
  toolPtr->rate		=	AudioRate;
  toolPtr->toolNum	=	toolNum++;
  toolPtr->map		=	(Pixmap) 0;
  toolPtr->x		=	0;
  toolPtr->y		=	0;
  toolPtr->name		=	NULL;
  toolPtr->fName	=	NULL;
  toolPtr->next		=	toolPtr->input1	= toolPtr->input2
    			=	toolPtr->input3 = toolPtr->input4
			=	toolPtr->input5	= toolPtr->input6
			=	toolPtr->input7	= toolPtr->input8
			=	toolPtr->output = NULL;
  toolPtr->arg1		=	toolPtr->arg2	= toolPtr->arg3 =
    toolPtr->arg4	=	toolPtr->arg5	= toolPtr->arg6 =
      toolPtr->arg7	=	toolPtr->arg8	= NULL;
  return(toolPtr);						    /* Return a pointer to the newly allocated tool */
}								    /* end function GetNewTool */


Tool	*AddToolToList()					    /* Adds a tool to the end of the tool list & returns... */
{								    /* ...a pointer to the new tool */
  Tool	*tPtr,*newPtr;

  changesMade = 1;						    /* Set flag saying that user made changes to the diagram */
  newPtr = GetNewTool();					    /* Allocate storage for a new tool */
  if (toolList==NULL)						    /* Is the tool list empty? */
    {								    /* Yes, do the following: */
      toolList = newPtr;					    /* Make the head of the list point to the new storage */
      return(toolList);						    /* Return head of the list, now containing one element */
    }								    /* end if toolList... */
  for (tPtr = toolList;  tPtr->next;  tPtr = tPtr->next)	    /* Find the end of the tool list */
    ;
  tPtr->next = newPtr;						    /* Add the new storage to end of the tool list */
  return(tPtr->next);						    /* Return pointer to the new tool */
}								    /* end function AddToolToList */



DeleteToolFromList(tool)					    /* Deletes the tool passed as argument from the list... */
     Tool	*tool;						    /* ...of tools used so far. */
{
  Tool	*last, *next, *tPtr;

  changesMade = 1;						    /* Set flag saying that user made changes to the diagram */
  if (tool->input1)						    /* Is input1 of this tool being used? */
    {
      tool->input1->output = NULL;				    /* Yes, find the tool supplying the input and... */
      tool->input1 = NULL;					    /* ...disconnect it at both ends. */
    }
  if (tool->input2)						    /* Is input2 of this tool being used? */
    {
      tool->input2->output = NULL;				    /* Yes, find the tool supplying the input and... */
      tool->input2 = NULL;					    /* ...disconnect it at both ends. */
    }
  if (tool->input3)						    /* Is input3 of this tool being used? */
    {
      tool->input3->output = NULL;				    /* Yes, find the tool supplying the input and... */
      tool->input3 = NULL;					    /* ...disconnect it at both ends. */
    }
  if (tool->input4)						    /* Is input4 of this tool being used? */
    {
      tool->input4->output = NULL;				    /* Yes, find the tool supplying the input and... */
      tool->input4 = NULL;					    /* ...disconnect it at both ends. */
    }
  if (tool->input5)						    /* Is input5 of this tool being used? */
    {
      tool->input5->output = NULL;				    /* Yes, find the tool supplying the input and... */
      tool->input5 = NULL;					    /* ...disconnect it at both ends. */
    }
  if (tool->input6)						    /* Is input6 of this tool being used? */
    {
      tool->input6->output = NULL;				    /* Yes, find the tool supplying the input and... */
      tool->input6 = NULL;					    /* ...disconnect it at both ends. */
    }
  if (tool->input7)						    /* Is input7 of this tool being used? */
    {
      tool->input7->output = NULL;				    /* Yes, find the tool supplying the input and... */
      tool->input7 = NULL;					    /* ...disconnect it at both ends. */
    }
  if (tool->input8)						    /* Is input8 of this tool being used? */
    {
      tool->input8->output = NULL;				    /* Yes, find the tool supplying the input and... */
      tool->input8 = NULL;					    /* ...disconnect it at both ends. */
    }
  if (tool->output)						    /* Is the output of this tool being used? */
    {
      if (tool->output->input1 == tool)				    /* Yes, Is it connected to input1 of the other tool? */
	tool->output->input1 = NULL;				    /* Yes, disconnect input1 from this tool */
      else if (tool->output->input2 == tool)			    /* No, check the rest of the inputs and disconnect... */
	tool->output->input2 = NULL;				    /* ...the appropriate one */
      else if (tool->output->input3 == tool)
	tool->output->input3 = NULL;	    
      else if (tool->output->input4 == tool)
	tool->output->input4 = NULL;	    
      else if (tool->output->input5 == tool)
	tool->output->input5 = NULL;	    
      else if (tool->output->input6 == tool)
	tool->output->input6 = NULL;	    
      else if (tool->output->input7 == tool)
	tool->output->input7 = NULL;	    
      else if (tool->output->input8 == tool)
	tool->output->input8 = NULL;
      tool->output = NULL;
    }

  if (tool == toolList)						    /* Trying to delete the first tool in the list? */
    {
      if (tool->next)						    /* Is this the only tool in the list? */
	toolList = tool->next;					    /* No, make toolList point to new first tool in list */
      else
	toolList = NULL;					    /* Yes, re-initialize toolList */
      free ((char *)tool);					    /* Free memory taken by this tool */
      return;							    /* Exit this function */
    }
  for (tPtr = toolList, last = toolList;  tPtr;
       last = tPtr, tPtr = tPtr->next)
    {
      if (tPtr->next)
	next = tPtr->next;
      else
	next = NULL;
      if (tPtr == tool)
	{
	  last->next = next;
	  tPtr->next = NULL;
	  free((char *)tPtr);
	  return;
	}							    /* end if tPtr... */
    }								    /* end for tPtr... */
}								    /* end function DeleteToolFromList */




PrintToolList()
{
#ifdef DEBUG
  Tool	*tPtr;
  int	i, toolType;
  
  printf("----------------------------------------------------------\n\n");
  printf("List of tools:\n");  
  for (tPtr = toolList, i = 1; tPtr; tPtr = tPtr->next, i++)
    {
      printf("Tool number %d:\n",i);
      printf("x,y, coords: %d,%d\n",tPtr->x,tPtr->y);
      toolType = tPtr->type;
      printf("Tool type: ");
      switch(toolType)
	{
	case SineTool:
	  printf("Sine\n");
	  break;
	case AmpTool:
	  printf("Amp\n");
	  break;
	case EnvTool:
	  printf("Env\n");
	  break;
	case SumTool:
	  printf("Sum\n");
	  break;
	case ParamTool:
	  printf("Param\n");
	  break;
	case NoiseTool:
	  printf("Noise\n");
	  break;
	case EQTool:
	  printf("Equation\n");
	  break;
	}							    /* end switch */
    }								    /* end for */
  printf("End of list.\n");
#endif
}								    /* end function PrintToolList */



Tool	*GetTool(toolNum)
     int	toolNum;
{
  Tool	*tPtr;

  for (tPtr=toolList;  tPtr;  tPtr= tPtr->next)
    {
      if (tPtr->toolNum == toolNum)
	  return(tPtr);
    }
  return(NULL);
}								    /* end function GetTool */



GetToolPixmaps()
{
  Tool	*tPtr;

  for (tPtr=toolList;  tPtr;  tPtr= tPtr->next)
    switch(tPtr->type)
      {
      case SineTool:
	tPtr->map = sineMap;
	break;
      case EnvTool:
	tPtr->map = envMap;
	break;
      case AmpTool:
	tPtr->map = ampMap;
	break;
      case SumTool:
	tPtr->map = sumMap;
	break;
      case NoiseTool:
	tPtr->map = noiseMap;
	break;
      case EQTool:
	tPtr->map = eqMap;
	break;
      }								    /* end switch tPtr->type... */
}								    /* end function GetToolPixmaps */


char	RateToChar(rateType)
     int	rateType;
{
  switch (rateType)
    {
    case AudioRate:
      return('a');
      break;
    case ControlRate:
      return('k');
      break;
    case InitRate:
      return('i');
      break;
    }
}								    /* end function RateChar */

char	*RateToStr(rateType)
     int	rateType;
{
  switch (rateType)
    {
    case AudioRate:
      return("Audio");
      break;
    case ControlRate:
      return("Control");
      break;
    case InitRate:
      return("Init");
      break;
    }
}								    /* end function RateToStr */
