/*  demo program to demonstrate the use of modules threed.c,          */
/*  grafprt.c, grafstr.c, arrays.c.                                   */
/*  mandel.c is an adaptation of a mandelbrot generator published in  */
/*  micro cornucopia, used here to generate a 3-D demo surface.       */
/*  written in Turbo C version 2.0.                                   */

#include <math.h>
#include <stdio.h>
#include <stdlib.h>
#include <conio.h>
#include <process.h>
#include <graphics.h>
#include "grafprt.h"
#include "grafstr.h"
#include "threed.h"
#include "arrays.h"
#include "mandel.h"

#define WAIT getch()

void input_domain(float *xmin,float *xmax,float *ymin,float *ymax);
void input_params(float *horangle,float *elangle,int *maxits);

/*--------------------------------------------------------------------*/

void main(int argc,char *argv[])

{
  float **z;
  float elangle,horangle;
  float xmax,xmin,ymax,ymin,zmax,zmin;
  float xminw,xmaxw,yminw,ymaxw;
  int nx,ny,hmax,maxits,ier=0;
  int box,fillcolor,edgecolor,boxedgecolor;
  void far (*csetfunc)();
  void far (*linefunc)();
  unsigned char ch;
  char strbuf[80];
  int size1,size2,mode,g_driver,g_mode;

  if ((argc != 2) || ((argv[1][0] != 'p') && (argv[1][0] != 'c')))
    {
      printf("syntax: test3d device \n");
      printf("where:  device = p, output is to the printer \n");
      printf("        device = c, output is to the CRT display \n");
      exit(0);
    }
  else
    ch = argv[1][0];

  switch (ch)
    {
      case 'p' : nx = 80;
                 ny = 80;
                 break;
      case 'c' : nx = 20;
                 ny = 20;
                 break;
    }

/* allocate memory for the arrays:                                    */

   z = (float **) alloc_2d_array(nx,ny,sizeof(float *),sizeof(float));
   if (!z)
     {
       printf("surface array memory allocation failure\n");
       exit(1);
     }

   input_domain(&xmin,&xmax,&ymin,&ymax);

   input_params(&horangle,&elangle,&maxits);

   if (ch == 'p')
     {
       printf("enter 0 for landscape mode printout, 1 for portrait mode ");
       scanf("%d",&mode);
     }

   printf("calling mandelbrot generator\n");

   mandel(xmin,xmax,ymin,ymax,maxits,nx,ny,z,&zmin,&zmax);

/* initialize the graphics device:                                    */

   switch (ch)
     {
             case 'p' : if (initgrafprt())
                          printf("getting ready to call surface routine\n");
                        else
                          {
                            printf("printer memory allocation failure");
                            exit(2);
                          }
                        if (mode)
                          {
                            portrait();
                            xminw = 100;
                            xmaxw = 860;
                            yminw = 800;
                            ymaxw = 1500;
                          }
                        else
                          {
                            landscape();
                            xminw = 50;
                            xmaxw = 1100;
                            yminw = 100;
                            ymaxw = 860;
                          }

                        box = 1;
                        fillcolor = 0;
                        edgecolor = 1;
                        boxedgecolor = 1;

                        hmax = 1599;
                        csetfunc = colorset;
                        linefunc = iprtln;
                        break;
             case 'c' : portrait();
                        detectgraph(&g_driver,&g_mode);
                        if (g_driver == CGA) g_mode = CGAC3;
                        initgraph(&g_driver,&g_mode,"c:\\turboc\\bgi");
                        if (g_driver < 0) exit(3);
                        setbkcolor(1);

                        xminw = 0;
                        xmaxw = getmaxx();
                        yminw = 0;
                        ymaxw = getmaxy();

                        box = 1;
                        fillcolor = 0;
                        edgecolor = 3;
                        boxedgecolor = 2;

                        hmax = ymaxw;
                        csetfunc = setcolor;
                        linefunc = line;
                        break;
     }

   ier = surface(xmin,xmax,ymin,ymax,zmin,zmax,xminw,xmaxw,yminw,ymaxw,
                 hmax,z,horangle,elangle,nx,ny,box,fillcolor,edgecolor,
                 boxedgecolor,csetfunc,linefunc);

   if (ier)
     {
       printf("surface plot ier = %d",ier);
       exit(ier);
     }

/* don't forget to free the array memory...                           */

   free_2d_array((void **) z,nx);

   switch (ch)
     {
       case 'p' : frame();
                  if (mode)
                    {
                      xminw = 50;
                      xmaxw = 910;
                      yminw = 200;
                      ymaxw = 600;
                      size1 = 4;
                      size2 = 2;
                    }
                  else
                    {
                      xminw = 1150;
                      xmaxw = 1550;
                      yminw = 700;
                      ymaxw = 900;
                      size1 = 3;
                      size2 = 1;
                    }

                  defreg(0.0,1.0,0.0,1.0,xminw,xmaxw,yminw,ymaxw);
                  framxy();
                  prtstr("Mandelbrot Set",0.5,0.85,0,size1,1);

                  sprintf(strbuf,"xmin = %9.6f",xmin);
                  prtstr(strbuf,0.1,0.65,0,size2,0);

                  sprintf(strbuf,"xmax = %9.6f",xmax);
                  prtstr(strbuf,0.6,0.65,0,size2,0);

                  sprintf(strbuf,"ymin = %9.6f",ymin);
                  prtstr(strbuf,0.1,0.50,0,size2,0);

                  sprintf(strbuf,"ymax = %9.6f",ymax);
                  prtstr(strbuf,0.6,0.50,0,size2,0);

                  sprintf(strbuf,"horizontal angle = %6.2f",horangle);
                  prtstr(strbuf,0.025,0.35,0,size2,0);

                  sprintf(strbuf,"elevation angle = %6.2f",elangle);
                  prtstr(strbuf,0.525,0.35,0,size2,0);

                  sprintf(strbuf,"maximum iterations = %d",maxits);
                  prtstr(strbuf,0.5,0.20,0,size2,1);

                  printf("getting ready to call prntgr\n");
                  prntgr(0);
                  break;
       case 'c' : WAIT;
                  closegraph();
                  break;
     }

}  /* main() */

/*--------------------------------------------------------------------*/

void input_domain(float *xmin,float *xmax,float *ymin,float *ymax)

{
  printf("for the complete set:\n");
  printf("xmin = -2.25, xmax = 0.75, ymin = -1.5, ymax = 1.5\n\n");

  printf("enter xmin ");
  scanf("%f",xmin);
  printf("enter xmax ");
  scanf("%f",xmax);

  printf("enter ymin ");
  scanf("%f",ymin);
  printf("enter ymax ");
  scanf("%f",ymax);

} /* void input_domain() */

/*--------------------------------------------------------------------*/

void input_params(float *horangle,float *elangle,int * maxits)

{
  printf("enter horizontal view angle (0..360) ");
  scanf("%f",horangle);
  printf("enter elevation view angle (-90..90) ");
  scanf("%f",elangle);
  printf("enter maximum interations ");
  scanf("%d",maxits);

} /* void input_params() */

/*--------------------------------------------------------------------*/


