 /*
  * Khoros: $Id: writepoly.c,v 1.2 1992/03/20 23:29:55 dkhoros Exp $
  */

#if !defined(lint) && !defined(SABER)
static char rcsid[] = "Khoros: $Id: writepoly.c,v 1.2 1992/03/20 23:29:55 dkhoros Exp $";
#endif

 /*
  * $Log: writepoly.c,v $
 * Revision 1.2  1992/03/20  23:29:55  dkhoros
 * VirtualPatch5
 *
  */ 


/*
 *----------------------------------------------------------------------
 *
 *            Copyright 1990 University of New Mexico
 *  
 *  Permission to use, copy, modify, distribute, and sell this
 *  software and its documentation for any purpose is hereby
 *  granted without fee, provided that the above copyright
 *  notice appear in all copies and that both that copyright
 *  notice and this permission notice appear in supporting docu-
 *  mentation, and that the name of UNM not be used in advertis-
 *  ing or publicity pertaining to distribution of the software
 *  without specific, written prior permission.  UNM makes no
 *  representations about the suitability of this software for
 *  any purpose.  It is provided "as is" without express or
 *  implied warranty.
 *  
 *  UNM DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
 *  INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FIT-
 *  NESS, IN NO EVENT SHALL UNM BE LIABLE FOR ANY SPECIAL,
 *  INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
 *  RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
 *  ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
 *  ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
 *  OF THIS SOFTWARE.
 *  
 *----------------------------------------------------------------------
 */

#include "unmcopyright.h"	 /* Copyright 1990 by UNM */
#include "xvparser.h"

static int writeterm();
static char *vlookup(); 

/* >>>>>>>>>>>>>>>>>>>>>>>>>>>>> <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
   >>>>                                                       <<<<
   >>>>	    file name: writepoly.c                            <<<<
   >>>>                                                       <<<<
   >>>>   description: contains the routine writepoly()       <<<<
   >>>>                                                       <<<<
   >>>>      routines: writepoly()			      <<<<
   >>>>                                                       <<<<
   >>>> modifications: see below			      <<<<
   >>>>                                                       <<<<
   >>>>          NOTE: this routine is not for public use!    <<<<
   >>>>                                                       <<<<
   >>>>>>>>>>>>>>>>>>>>>>>>>>>>> <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< */

/***********************************************************************
*
*  Routine Name: 
*
*          Date: Thu Aug 30 15:29:04 MDT 1990
*        
*       Purpose: writes a file of polynomials based on a group of
*                arrays that describe the polynomials. 
*
*         Input: char *fname       - name of polynomial file with explicit
*                                    path if necessary.
*
*                int npolys        - number of polynomials.
*
*		 struct poly_struct *poly;
*				   - polynomial information
*
*		 char *comment	   - a comment that can be supplied by the
*				     calling program to be written to the top
*				     of the output file.
*
*    Written By: Jeremy Worley
*
* Modifications: Jeremy Worley 19 Mar 1992 17:17 MST
*                       added support for transport stuff.  specifically,
*                       changed operations that dealt with FILE structures
*                       to corresponding operations that deal with kfile
*                       structures.
*
***********************************************************************/

#include "varargs.h"
#include "vpoly.h"
#include "kfile.h"

int writepoly(fname,poly,npolys,comment)
    char *fname,*comment;
    struct poly_struct *poly;
    int npolys;
{
    char *program = "writepoly()";
    int i,j,k,num,den,start;
    kfile *kfptr;

    if((kfptr=kfopen(fname,"w"))==NULL){
       fprintf(stderr,"%s:  cannot create \"%s\"\n",program,fname);
       return(0);
    }

    kfprintf(kfptr,"/* %s */\n\n",comment);

    for(i= 0 ; i<npolys; i++){
        kfprintf(kfptr,"\n/* polynomial #%d */\n",i+1);
        kfprintf(kfptr,"%s(%s) = ",poly[i].func_name,poly[i].indep_var);
        start = 0;
        if(poly[i].stages>1){
           for(j=0;j<poly[i].stages;j++){
               num = poly[i].nterms[2*j];
               den = poly[i].nterms[2*j+1];
               kfprintf(kfptr,"[(");
               for(k=start;k<start+num;k++){
                      if(k>start)kfprintf(kfptr," + ");
                      (void)writeterm(kfptr,&(poly[i].terms[k]));
               }
               kfprintf(kfptr,")/(");
               for(k=start+num;k<start+num+den;k++){
                      if(k>start+num)kfprintf(kfptr," + ");
                      (void)writeterm(kfptr,&(poly[i].terms[k]));
               }
               kfprintf(kfptr,")]");
               if(j<poly[i].stages-1)kfprintf(kfptr," *\n\t");
               start += num+den;
           }
           kfprintf(kfptr,";\n");
        }else{
           num = poly[i].nterms[0];
           den = poly[i].nterms[1];
           if(den!=0)kfprintf(kfptr,"(");
           for(k=0;k<num;k++){ 
                  if(k>0)kfprintf(kfptr," + ");
                  (void)writeterm(kfptr,&(poly[i].terms[k]));
           }
           if(den!=0){
              kfprintf(kfptr,")/(");
              for(k=num;k<num+den;k++){
                     if(k>num)kfprintf(kfptr," + ");
                     (void)writeterm(kfptr,&(poly[i].terms[k]));
              }
           }
           if(den!=0)kfprintf(kfptr,")");
           kfprintf(kfptr,";\n");
        }
    }

    if(kfclose(kfptr)==EOF){
       fprintf(stderr,"%s:  unable to close file.\n",program);
       return(0);
    }

    return(1);
}

/***********************************************************************
*
*  Routine Name: writeterm()
*
*          Date: Tue Sep 18 14:19:48 MDT 1990
*        
*       Purpose: actually outputs a single algebraic term to the 
*		 file specified.  It handles special cases such as 
*		 unit coefficients, unit exponents, etc.  
*
*         Input:  
*
*        Output: 
*
*    Written By: Jeremy Worley  
*
* Modifications: Mon Nov 26 16:09:17 MST 1990 Jeremy Worley
*			changed arguments to support term structure
*			and function terms.
*
***********************************************************************/

static int writeterm(kfptr,term)
  kfile *kfptr;
  struct term_struct *term;
{
  char *name;

  if(term->type==_STDTERM){
     if((int)(term->expon)==0){
        kfprintf(kfptr,"%g",term->coef);
     }else if((int)(term->expon)==1){
        if(term->coef==1.0){
           kfprintf(kfptr,"%s",term->varname);
        }else{
           if((name = vlookup(term->coef))!=NULL){
              kfprintf(kfptr,"%s*%s",name,term->varname);
           }else{
              kfprintf(kfptr,"%g*%s",term->coef,term->varname);
           }
        }
     }else{
        if(term->coef==1.0){
           kfprintf(kfptr,"%s^%d",term->varname,(int)(term->expon));
        }else{
           if((name = vlookup(term->coef))!=NULL){
              kfprintf(kfptr,"%s*%s^%d",name,term->varname,(int)(term->expon));
           }else{
              kfprintf(kfptr,"%g*%s^%d",term->coef,term->varname,
                   (int)(term->expon));
           }
        }
     }
  }else{
     if((int)(term->coef)==1){
        kfprintf(kfptr,"%s(",term->fname);
     }else{
        if((name = vlookup(term->coef))!=NULL){
           kfprintf(kfptr,"%s*%s",name,term->fname);
        }else{
           kfprintf(kfptr,"%g*%s(",term->coef,term->fname);
        }
     }
    
     if(term->delay==0){
        kfprintf(kfptr,"%s)",term->varname);
     }else if(term->delay<0){
        kfprintf(kfptr,"%s - %d)",term->varname,(0 - term->delay));
     }else{
        kfprintf(kfptr,"%s + %d)",term->varname,term->delay);
     }
  } /* end big else */
  return(1);
}

/***********************************************************************
*
*  Routine Name: vlookup()
*
*          Date: Sun Sep  9 10:00:17 MDT 1990
*        
*       Purpose: compare values against a table of constants, and return
*		 the name of the constant if it is known.  
*
*         Input: value	- numeric value to be checked against table 
*
*        Output: returns NULL if constant not found, name otherwise 
*
*    Written By: Jeremy Worley 
*
* Modifications:
*
* NOTE: This really won't work as is.  What is needed is a tolerance
*       term to allow for floating point roundoff
*
***********************************************************************/

static char *vlookup(value)
    float value;
{
    int i=0;

    while(constants[i].name!=NULL){
       if(constants[i].value==value)return(constants[i].name);
       i++;
    }

    return((char *)NULL);
}

