/* A graph widget by Rob Fletcher
   Computing Service
   University of York
   Heslington 
   YORK

This version runs on an SGI Indigo (on my desk!) fine. 

Other folk may find some coding changes necessary.

Use at your peril.

Please advise of changes and please buzz back any
future generations.

Enjoy!

1. Mouse down on graph allows movement
2. Click on graph gets resize handles - don't like the way SUIT
   does this.
3. Cursors on, then all manner of wonderful things happen.


*/



#include <stdio.h>
#include <string.h>
#include <ctype.h>
#include "suit.h"
#include <math.h>


/* Various Property define */
#define PARAMETER "parameter"
#define CURSOR1_X "cursor 1 x"
#define CURSOR1_Y "cursor 1 y"
#define CURSOR2_X "cursor 2 x"
#define CURSOR2_Y "cursor 2 y"
#define CURSOR_ON "cursors on"
#define AV_ON "AV on"
#define AF_ON "AF on"
#define AH_ON "AH on"
#define GRAPH "current graph"
#define XV "x value label"
#define YV "y value label"



/* Various bits to define the data here which I use later on */

#define NPAR	4
#define MAX_FRAMES 200
#define MAX_VAR_PARS 4
char *VarFrqNames[NPAR] = {"F0","AV","AF","AH"};
double pdata[NPAR][MAX_FRAMES];	/* from synth */
int maxval[NPAR];       /* Maximum values for all parameters */
int minval[NPAR];       /* Minimum values for all parameters */
int defval[NPAR];       /* Default values for all parameters */
int nsamp = 100;
double msecs[MAX_FRAMES];
/*  End of my data stuff */

/* prototype */
void makegraph(int k);


/* Make these globals to use by other widgets */
SUIT_object  Igebb[MAX_VAR_PARS];

int current_parameter;  /* track we are editing - use for data pointer */

GP_point pt1,pt2 ; 




/*=======================================================*/
/* various functions to alter the data                   */


void Ins(SUIT_object me)
{
int i,j,x1, x2,gap;

    if ( SUIT_getBoolean(SUIT_getObject(me,GRAPH),CURSOR_ON) ){
        x1 = (int) SUIT_getDouble(SUIT_getObject(me,GRAPH),CURSOR1_X);
        x2 = (int) SUIT_getDouble(SUIT_getObject(me,GRAPH),CURSOR2_X);
        gap = x2-x1;
        j = SUIT_getInteger(SUIT_getObject(me,GRAPH),PARAMETER);
        for (i=nsamp+gap-1;i>x1;i--) pdata[j][i] = pdata[j][i-gap];
        for (i=x1+1;i<x2;i++) pdata[j][i] = pdata[j][x1];
        SUIT_redisplayRequired(SUIT_getObject(me,GRAPH));
    }
}


void Cut(SUIT_object me)
{
int i,j,x1, x2,gap;

    if ( SUIT_getBoolean(SUIT_getObject(me,GRAPH),CURSOR_ON) ){
        x1 = (int) SUIT_getDouble(SUIT_getObject(me,GRAPH),CURSOR1_X);
        x2 = (int) SUIT_getDouble(SUIT_getObject(me,GRAPH),CURSOR2_X);
        gap = x2-x1;
        j = SUIT_getInteger(SUIT_getObject(me,GRAPH),PARAMETER);
        for (i=x1;i<=x1+nsamp-x2;i++) pdata[j][i] = pdata[j][i+gap];
        for (i=nsamp-gap;i<nsamp;i++) pdata[j][i] = (double)(double)minval[j];
        SUIT_redisplayRequired(SUIT_getObject(me,GRAPH));
    }
}



void Zero(SUIT_object me)
{
int i,j,x1, x2;

    if ( SUIT_getBoolean(SUIT_getObject(me,GRAPH),CURSOR_ON) ){
        x1 = (int) SUIT_getDouble(SUIT_getObject(me,GRAPH),CURSOR1_X);
        x2 = (int) SUIT_getDouble(SUIT_getObject(me,GRAPH),CURSOR2_X);
        j = SUIT_getInteger(SUIT_getObject(me,GRAPH),PARAMETER);
        for (i=x1;i<=x2;i++) pdata[j][i] = (double)minval[j];
        SUIT_redisplayRequired(SUIT_getObject(me,GRAPH));
    }
}


void Tonic(SUIT_object me)
{
int i,j,x1, x2;
double dy;

    if ( SUIT_getBoolean(SUIT_getObject(me,GRAPH),CURSOR_ON) ){
        x1 = (int) SUIT_getDouble(SUIT_getObject(me,GRAPH),CURSOR1_X);
        x2 = (int) SUIT_getDouble(SUIT_getObject(me,GRAPH),CURSOR2_X);
        j = SUIT_getInteger(SUIT_getObject(me,GRAPH),PARAMETER);
        dy = pt2.y - pdata[j][ x1 ];
        for (i=x1;i<=x2;i++) {
            pdata[j][i] += dy;
            if( pdata[j][i] > maxval[j] ) pdata[j][i] = maxval[j];
            if( pdata[j][i] < minval[j] ) pdata[j][i] = minval[j];
        }   
        SUIT_redisplayRequired(SUIT_getObject(me,GRAPH));
    }
}



void Inter(SUIT_object me)
{
int i,j,x1, x2;
float mx,y2;


if ( SUIT_getBoolean(SUIT_getObject(me,GRAPH),CURSOR_ON) ){
    x1 = (int) SUIT_getDouble(SUIT_getObject(me,GRAPH),CURSOR1_X);
    x2 = (int) SUIT_getDouble(SUIT_getObject(me,GRAPH),CURSOR2_X);
    y2 = SUIT_getDouble(SUIT_getObject(me,GRAPH),CURSOR2_Y);
    j = SUIT_getInteger(SUIT_getObject(me,GRAPH),PARAMETER);
    mx = (y2 - pdata[j][x1])/(x2-x1);
    for (i=x1;i<=x2 ;i++) { 
         pdata[j][i] = pdata[j][x1] + mx*(i-x1);
        if( pdata[j][i] > maxval[j] ) pdata[j][i] = maxval[j];
        if( pdata[j][i] < minval[j] ) pdata[j][i] = minval[j];
    }
    SUIT_redisplayRequired(SUIT_getObject(me,GRAPH));
}

}


void SinePlus(SUIT_object me)
{
int i,j,x1, x2;
float mx,y1,y2,dy;


if ( SUIT_getBoolean(SUIT_getObject(me,GRAPH),CURSOR_ON) ){
    x1 = (int) SUIT_getDouble(SUIT_getObject(me,GRAPH),CURSOR1_X);
    x2 = (int) SUIT_getDouble(SUIT_getObject(me,GRAPH),CURSOR2_X);
    y2 = SUIT_getDouble(SUIT_getObject(me,GRAPH),CURSOR2_Y);
    j = SUIT_getInteger(SUIT_getObject(me,GRAPH),PARAMETER);
    mx = (3.14159/2.0)/(x2-x1);
    y1 = pdata[j][x1];
    dy = fabs(y2 - pdata[j][ x1 ]);

    if( y1 != y2 ){
        if( y1 < y2 ) {
            for( i=x1;i<=x2;i++) 
		pdata[j][i] = pdata[j][x1] + sin( mx * (i-x1))*dy;
                if( pdata[j][i] > maxval[j] ) pdata[j][i] = maxval[j];
        }
        else
	{
	    for( i=x1;i<=x2;i++)
		pdata[j][i] = pdata[j][x1] + ( cos( mx * (i-x1)) - 1.0) *dy;
                if( pdata[j][i] < minval[j] ) pdata[j][i] = minval[j];
	}

    SUIT_redisplayRequired(SUIT_getObject(me,GRAPH));
   }
}

}



void SineMinus(SUIT_object me)
{
int i,j,x1, x2;
float mx,y1,y2,dy;


if ( SUIT_getBoolean(SUIT_getObject(me,GRAPH),CURSOR_ON) ){
    x1 = (int) SUIT_getDouble(SUIT_getObject(me,GRAPH),CURSOR1_X);
    x2 = (int) SUIT_getDouble(SUIT_getObject(me,GRAPH),CURSOR2_X);
    y2 = SUIT_getDouble(SUIT_getObject(me,GRAPH),CURSOR2_Y);
    j = SUIT_getInteger(SUIT_getObject(me,GRAPH),PARAMETER);
    mx = (3.14159/2.0)/(x2-x1);
    y1 = pdata[j][x1];
    dy = fabs(y2 - pdata[j][ x1 ]);

    if( y1 != y2 ){
        if( y1 < y2 ) {
            for( i=x1;i<=x2;i++) 
		pdata[j][i] = pdata[j][x1]   + (1.0 -  cos( mx * (i-x1))  )*dy;
                if( pdata[j][i] > maxval[j] ) pdata[j][i] = maxval[j];
        }
        else
	{
	    for( i=x1;i<=x2;i++)
		pdata[j][i] = pdata[j][x1] - sin( mx * (i-x1))*dy;
                if( pdata[j][i] < minval[j] ) pdata[j][i] = minval[j];
	}

    SUIT_redisplayRequired(SUIT_getObject(me,GRAPH));
    }

}

}


/*=======================================================*/
/* show various params on current graph switches */
void Av(SUIT_object me)
{
SUIT_setBoolean( SUIT_getObject(me,GRAPH),AV_ON,
                 !SUIT_getBoolean(SUIT_getObject(me,GRAPH),AV_ON));
}

void Af(SUIT_object me)
{
SUIT_setBoolean( SUIT_getObject(me,GRAPH),AF_ON,
                 !SUIT_getBoolean(SUIT_getObject(me,GRAPH),AF_ON));
}

void Ah(SUIT_object me)
{
SUIT_setBoolean( SUIT_getObject(me,GRAPH),AH_ON,
                 !SUIT_getBoolean(SUIT_getObject(me,GRAPH),AH_ON));
}

void Zoom(SUIT_object me)
{
int k;
    if( SUIT_getBoolean(SUIT_getObject(me,GRAPH),CURSOR_ON) ) {
    k = SUIT_getInteger(SUIT_getObject(me,GRAPH),PARAMETER);
    if( SUIT_getBoolean(me,CURRENT_VALUE) ) {
        SUIT_setWindow(SUIT_getObject(me,GRAPH),WINDOW,
	               SUIT_defWindow(pt1.x-1.0,(double)minval[k],
                                      pt2.x+1.0,maxval[k]) );
     }
     else   {
        SUIT_setWindow(SUIT_getObject(me,GRAPH),WINDOW,
	               SUIT_defWindow(0.0,(double)minval[k],
                                      (double)nsamp-1,maxval[k]) );
     }
     }
     else
         SUIT_setBoolean(me,CURRENT_VALUE,FALSE);
}


void Cursors(SUIT_object me)
{
SUIT_setBoolean( SUIT_getObject(me,GRAPH),CURSOR_ON,
                 !SUIT_getBoolean(SUIT_getObject(me,GRAPH),CURSOR_ON));
SUIT_setDouble(SUIT_getObject(me,GRAPH),CURSOR1_X,pt1.x);
SUIT_setDouble(SUIT_getObject(me,GRAPH),CURSOR2_X,pt2.x);
}


/*=======================================================*/
/* Make the cursors skip an increment                    */

void Skip( SUIT_object me )
{
double tempx;
int j;

    j = SUIT_getInteger(SUIT_getObject(me,GRAPH),PARAMETER);
    tempx = pt2.x + (pt2.x - pt1.x);
    pt1.x = pt2.x;
    pt1.y = pdata[j][ (int) pt1.x ];
    pt2.y = pdata[j][ (int) pt2.x ];
    pt2.x = tempx;
    SUIT_setDouble(SUIT_getObject(me,GRAPH),CURSOR1_X,pt1.x);
    SUIT_setDouble(SUIT_getObject(me,GRAPH),CURSOR1_Y,pt1.y);
    SUIT_setDouble(SUIT_getObject(me,GRAPH),CURSOR2_X,pt2.x);
    SUIT_setDouble(SUIT_getObject(me,GRAPH),CURSOR2_Y,pt2.y);
    SUIT_redisplayRequired(SUIT_getObject(me,GRAPH));
    SUIT_performRedisplay();

}


/*=======================================================*/
/*      Dragging functions                               */

void DragCursorLine_1( point p)
{

pt1 = GP_unMapPoint( p);

if( pt1.x < 0.0 ) pt1.x = 0.0;
if( pt1.x > (double)nsamp) pt1.x = (double) nsamp;
if( pt1.y < minval[current_parameter] ) pt1.y = minval[current_parameter];
if( pt1.y > maxval[current_parameter]) pt1.y = maxval[current_parameter];

if( pt1.x > pt2.x ) pt1.x = pt2.x -1;
GP_lineCoord( pt1.x , maxval[current_parameter], 
              pt1.x,  minval[current_parameter] );
GP_setMarkerStyle( MARKER_CIRCLE);
GP_setMarkerSize(8);
GP_markerCoord(pt1.x,pdata[current_parameter][(int)pt1.x]);
GP_lineCoord(pt1.x,pt2.y,pt2.x,pt2.y);
}

void DragCursorLine_2( point p)
{

pt2 = GP_unMapPoint( p);

if( pt1.x < 0.0 ) pt1.x = 0.0;
if( pt1.x > (double)nsamp) pt1.x = (double) nsamp;
if( pt1.y < minval[current_parameter] ) pt1.y = minval[current_parameter];
if( pt1.y > maxval[current_parameter])  pt1.y = maxval[current_parameter];

if( pt2.x < pt1.x ) pt2.x = pt1.x +1;
if( pt2.y < pdata[current_parameter][ (int)pt2.x] )
   GP_lineCoord( pt2.x ,minval[current_parameter] , pt2.x,
                 pdata[current_parameter][ (int)pt2.x] );
else
   GP_lineCoord( pt2.x ,maxval[current_parameter] , pt2.x,
                 pdata[current_parameter][ (int)pt2.x] );
   GP_lineCoord( 0.0, pt2.y,(double) nsamp, pt2.y);
   GP_lineCoord( pt1.x, pdata[current_parameter][(int)pt1.x], pt2.x, pt2.y);
} 


/*===========================================================*/
/*  Create graph widget */


SUIT_object CreateIgeChip(char *name,
            void (*HitProc)(SUIT_object o,SUIT_event ev),
            void (*PaintProc)(SUIT_object o)) 
{
    SUIT_object obj;
      
    obj = SUIT_createObject(name, "Ige Widget");


    SUIT_addDisplayToObject(obj, "standard", HitProc, PaintProc);
    SUIT_setDouble(obj,CURSOR1_X,0.0);
    SUIT_setDouble(obj,CURSOR1_Y,0.0);
    SUIT_setDouble(obj,CURSOR2_X,0.0);
    SUIT_setDouble(obj,CURSOR2_Y,0.0);
    SUIT_setBoolean(obj,CURSOR_ON,FALSE);
    SUIT_setBoolean(obj,AV_ON,FALSE);
    SUIT_setBoolean(obj,AF_ON,FALSE);
    SUIT_setBoolean(obj,AH_ON,FALSE);
    SUIT_setInteger(obj,PARAMETER,-1);

       SUIT_makePropertyTemporary (obj, PARAMETER, OBJECT);
       SUIT_lockProperty (obj, PARAMETER, OBJECT);

       SUIT_makePropertyTemporary (obj, CURSOR1_X, OBJECT);
       SUIT_lockProperty (obj, CURSOR1_X, OBJECT);
       SUIT_makePropertyTemporary (obj, CURSOR1_Y, OBJECT);
       SUIT_lockProperty (obj, CURSOR1_Y, OBJECT);
 
       SUIT_makePropertyTemporary (obj, CURSOR2_X, OBJECT);
       SUIT_lockProperty (obj, CURSOR2_X, OBJECT);
       SUIT_makePropertyTemporary (obj, CURSOR2_Y, OBJECT);
       SUIT_lockProperty (obj, CURSOR2_Y, OBJECT);

       SUIT_makePropertyTemporary (obj, CURSOR_ON, OBJECT);
       SUIT_lockProperty (obj, CURSOR_ON, OBJECT);

       SUIT_makePropertyTemporary (obj,AV_ON , OBJECT);
       SUIT_lockProperty (obj,AV_ON , OBJECT);
       SUIT_makePropertyTemporary (obj,AF_ON , OBJECT);
       SUIT_lockProperty (obj,AF_ON, OBJECT);
       SUIT_makePropertyTemporary (obj,AH_ON, OBJECT);
       SUIT_lockProperty (obj, AH_ON, OBJECT);


    return obj;
}

/*=======================================================*/
/* Paint proc                                            */

void IgePaint(SUIT_object me)
{
int i;
boolean draw;

    GP_rectangle rect;
    GP_color track_colour, c1_colour,black_lines,AV_lines,AF_lines,AH_lines;

    double x1,x2,x3,x4,y1,y2,y3,y4,tick,tickint;
    SUIT_window wind;
    int pad,x;
    GP_point cursor1,cursor2;

track_colour=GP_defColor( "red",TRUE );
c1_colour=GP_defColor( "green",TRUE );
black_lines = GP_defColor( "black", TRUE );
AV_lines = GP_defColor( "blue", TRUE );
AF_lines = GP_defColor( "magenta", TRUE );
AH_lines = GP_defColor( "cyan", TRUE );

    pad = SUIT_getInteger( me , PARAMETER);
    wind = SUIT_getWindow(me,WINDOW);

/* lets do some ticks */
    y1 = wind.bottom_left.y;
    y2 = wind.bottom_left.y + 
            (wind.top_right.y - wind.bottom_left.y) *.015; 
    y3 = wind.top_right.y;
    y4 = wind.top_right.y - 
            (wind.top_right.y - wind.bottom_left.y) *.015;
    for(tick = wind.bottom_left.x;tick < wind.top_right.x;tick += 4) {
        GP_lineCoord(tick,y1,tick,y2);
        GP_lineCoord(tick,y3,tick,y4);

    }
    x1 = wind.bottom_left.x;
    x2 = wind.bottom_left.x +
             (wind.top_right.x - wind.bottom_left.x) *.015; 
    x3 = wind.top_right.x;
    x4 = wind.top_right.x -
             (wind.top_right.x - wind.bottom_left.x) *.015; 

/* this is a fudge up coz we either have a Hz range (few k) or dB (0-80)
   or % */

    if( (wind.top_right.y - wind.bottom_left.y) < 110 ) 
       tickint = 10;
    else
       tickint = 100; 

    for(tick = wind.bottom_left.y;tick < wind.top_right.y;tick += tickint) {
        GP_lineCoord(x1,tick,x2,tick);
        GP_lineCoord(x3,tick,x4,tick);
    }

    GP_drawRectangle(wind);

/* if cursors are on - only show cursor stuff */
	if( SUIT_getBoolean(me,CURSOR_ON) ) {
           GP_setColor( c1_colour );

	   x = (int) SUIT_getDouble(me,CURSOR1_X);
           cursor1.x = x; ;
           cursor1.y = minval[pad];
           GP_lineCoord(cursor1.x,maxval[pad],cursor1.x,cursor1.y);
	
           GP_setColor( black_lines );
           GP_setMarkerStyle( MARKER_CIRCLE);
           GP_setMarkerSize(6);
	   GP_markerCoord(cursor1.x,pdata[pad][x]);

           GP_setColor( c1_colour );
	   x = (int) SUIT_getDouble(me,CURSOR2_X);
           cursor2.x = x;
           cursor2.y = SUIT_getDouble(me,CURSOR2_Y);
           if( cursor2.y < pdata[pad][x] )
             GP_lineCoord(cursor2.x,minval[pad],cursor2.x,pdata[pad][x]);
            else
             GP_lineCoord(cursor2.x,maxval[pad],cursor2.x,pdata[pad][x]);
             GP_lineCoord(cursor2.x-2.0,cursor2.y,cursor2.x+2.0,cursor2.y);
             GP_setColor( black_lines );
             GP_lineCoord(cursor1.x-1.0,cursor2.y,cursor1.x+1.0,cursor2.y);

        }


/* lets see what we have to show for AV, AF and AH */
    y1 = (double) maxval[pad] - (double)maxval[pad] *0.01 ;
    y2 = (double)minval[pad];


    if( SUIT_getBoolean(me,AV_ON)) {
        GP_setColor( AV_lines );
        i = 0;
        draw = TRUE;

        while( i < nsamp )
        {
        if( draw && pdata[1][i] != 0)
          { x1 = (double)i; 	
            GP_lineCoord(x1,y1,x1,y2);	
            draw = FALSE;
          }
         if( !draw )
              if( pdata[1][i] == 0 ) 
                 {
                   x2 = (double)i;
                   GP_lineCoord(x1,y1,x2,y1);
                   GP_lineCoord(x2,y1,x2,y2);
                   draw = TRUE;
                 }   
          i++;
          }
	}




    if( SUIT_getBoolean(me,AF_ON)) {
        GP_setColor( AF_lines );
        i = 0;
        draw = TRUE;

        while( i < nsamp )
        {
        if( draw && pdata[2][i] != 0)
          { x1 = (double)i; 	
            GP_lineCoord(x1,y1,x1,y2);	
            draw = FALSE;
          }
         if( !draw )
              if( pdata[2][i] == 0 ) 
                 {
                   x2 = (double)i;
                   GP_lineCoord(x1,y1,x2,y1);
                   GP_lineCoord(x2,y1,x2,y2);
                   draw = TRUE;
                 }   
          i++;
          }
	}



    if( SUIT_getBoolean(me,AH_ON)) {
        GP_setColor( AH_lines );
        i = 0;
        draw = TRUE;

        while( i < nsamp )
        {
        if( draw && pdata[3][i] != 0)
          { x1 = (double)i; 	
            GP_lineCoord(x1,y1,x1,y2);	
            draw = FALSE;
          }
         if( !draw )
              if( pdata[3][i] == 0 ) 
                 {
                   x2 = (double)i;
                   GP_lineCoord(x1,y1,x2,y1);
                   GP_lineCoord(x2,y1,x2,y2);
                   draw = TRUE;
                 }   
          i++;
          }
	}



/* paint the data */
    GP_setColor( track_colour );
    GP_polyLineCoord(nsamp,msecs,&pdata[pad][0]);


} 




/* Hit proc */
void IgeHit( SUIT_object me, SUIT_event ev)
{
static    SUIT_viewport oldvp,      
                  newvp;
    int j,x,y;
    int yvalue,pad;
    GP_point pt;
    char xval[5];
    char yval[5];
    double cursor1_x, cursor2_x, currpos;

	if( SUIT_getBoolean(me,CURSOR_ON) ) {
            current_parameter = SUIT_getInteger(me,PARAMETER);
            j = current_parameter;
/* swith cursor style */
	GP_setCursor(PROMPT_CURSOR);

/* are we "near" cursor_1 or cursor_2 */
	    cursor1_x = SUIT_getDouble(me,CURSOR1_X);
	    cursor2_x = SUIT_getDouble(me,CURSOR2_X);
            currpos = ev.worldLocation.x;

            if( currpos < cursor1_x || currpos < cursor1_x+2 ) {
                pt = GP_unMapPoint(SUIT_drag( DragCursorLine_1 ));

                if( pt.x < 0.0 ) pt.x = 0.0;
                if( pt.y < (double)minval[j] ) pt.y = (double)minval[j];
                if( pt.x > (double) nsamp) pt.x = (double) nsamp;
                if( pt.y > (double)maxval[j]) pt.y = (double)maxval[j];

	        SUIT_setDouble(me,CURSOR1_X,pt.x);
	        SUIT_setDouble(me,CURSOR1_Y,pt.y);
                x = (int) pt.x;
                yvalue = pdata[j][x];
	    }
            else {
                pt = GP_unMapPoint(SUIT_drag( DragCursorLine_2 ));
 
                if( pt.x < 0.0 ) pt.x = 0.0;
                if( pt.y < (double)minval[j] ) pt.y = (double)minval[j];
                if( pt.x > (double) nsamp) pt.x = (double) nsamp;
                if( pt.y > (double)maxval[j]) pt.y = (double)maxval[j];

	        SUIT_setDouble(me,CURSOR2_X,pt.x);
	        SUIT_setDouble(me,CURSOR2_Y,pt.y);
                x = (int) pt.x;
                yvalue = (int) pt.y;
	    }
	    GP_setCursor(STANDARD_CURSOR);


/* Sun users may have to fix this bit! */

            sprintf(xval,"%4d ",x*5);
            sprintf(yval,"%4d ",yvalue);

/* !!! */
            SUIT_setText(SUIT_getObject(me,XV),LABEL,xval);
            SUIT_setText(SUIT_getObject(me,YV),LABEL,yval);
            SUIT_redisplayRequired( SUIT_getObject(me,XV) );
            SUIT_redisplayRequired( SUIT_getObject(me,YV) );
            SUIT_performRedisplay();
        }
        else 
        {




/* Handle resize and move */
        if( SUIT_isAnyoneOverMe(SUIT_getParent(me)) )
            SUIT_bringToFront( SUIT_getParent(me) );
        oldvp = SUIT_getViewport (SUIT_getParent(me), VIEWPORT);
        
        if (ev.type == MOUSE_DOWN) {
           newvp = SUIT_moveRectangle (
                       SUIT_mapViewportToScreen(SUIT_getParent(me),oldvp),
                       ev.locator.position, FALSE);
           SUIT_setViewport (SUIT_getParent(me), VIEWPORT, 
                          SUIT_mapScreenToViewport(SUIT_getParent(me),newvp));
           SUIT_redisplayRequired( SUIT_getParent(me));

        }
        else 
            if( ev.type == CLICK ) {
                    if( OBJECT_SELECTED(SUIT_getParent(me)) ) 
                        OBJECT_SELECTED(SUIT_getParent(me)) = FALSE;
		    else {
                         newvp = SUIT_resizeRectangle (
                                 SUIT_mapViewportToScreen(SUIT_getParent(me),
                                 oldvp));
                         OBJECT_SELECTED(SUIT_getParent(me)) = FALSE;
                         SUIT_setViewport (SUIT_getParent(me), VIEWPORT, 
                                           SUIT_mapScreenToViewport(SUIT_getParent(me),newvp));
                         SUIT_redisplayRequired( SUIT_getParent(me));

                     }
            }

        }


}
   



void makegraph(int k)
{
SUIT_viewport parvp,vp;
SUIT_object Igepad, xv,yv,tname,zero,tonic,cursors,inter,plus,minus,cut,
     skip,stacker,av,ah,af,zoom,ins;
GP_font trn10; 
char  objname[10];
double stackerwidth,stackerheight;

        trn10 = GP_defFont("times","normal",10);
        strcpy(objname,VarFrqNames[k]);
        objname[ strlen(VarFrqNames[k]) + 1 ] = 0;

        objname[ strlen(VarFrqNames[k]) ]='b';

	Igebb[k] = SUIT_createBulletinBoard(objname);

        objname[ strlen(VarFrqNames[k]) ]='g';
        Igepad = CreateIgeChip(objname,IgeHit, IgePaint);

	SUIT_addChildToObject(Igebb[k],Igepad);
/* Lets now do the top line bizz */

        objname[ strlen(VarFrqNames[k]) ]='n';
	tname = SUIT_createLabel(objname);
        SUIT_setText(tname,LABEL,VarFrqNames[k]);

        objname[ strlen(VarFrqNames[k]) ]='x';
	xv = SUIT_createLabel(objname);
        SUIT_setText(xv,LABEL,"0000");
	SUIT_setBoolean(xv,HAS_BORDER,TRUE);

        objname[ strlen(VarFrqNames[k]) ]='y';
	yv = SUIT_createLabel(objname);
        SUIT_setText(yv,LABEL,"0000");
	SUIT_setBoolean(yv,HAS_BORDER,TRUE);

/* add objects to Ige */
	SUIT_setObject(Igepad,XV,xv);
	SUIT_setObject(Igepad,YV,yv);

        objname[ strlen(VarFrqNames[k]) ]='z';
	zero = SUIT_createButton(objname,Zero);
	SUIT_setText(zero,LABEL,"Zero");
        SUIT_setObject(zero,GRAPH,Igepad);

        objname[ strlen(VarFrqNames[k]) ]='t';
	tonic = SUIT_createButton(objname,Tonic);
	SUIT_setText(tonic,LABEL,"Tonic");
        SUIT_setObject(tonic,GRAPH,Igepad);

        objname[ strlen(VarFrqNames[k]) ]='i';
	inter = SUIT_createButton(objname,Inter);
	SUIT_setText(inter,LABEL,"Linear");
        SUIT_setObject(inter,GRAPH,Igepad);

        objname[ strlen(VarFrqNames[k]) ]='p';
	plus = SUIT_createButton(objname,SinePlus);
	SUIT_setText(plus,LABEL,"Sine +");
        SUIT_setObject(plus,GRAPH,Igepad);

        objname[ strlen(VarFrqNames[k]) ]='m';
	minus = SUIT_createButton(objname,SineMinus);
	SUIT_setText(minus,LABEL,"Sine -");
        SUIT_setObject(minus,GRAPH,Igepad);

        objname[ strlen(VarFrqNames[k]) ]='s';
	skip = SUIT_createButton(objname,Skip);
	SUIT_setText(skip,LABEL,"Skip");
        SUIT_setObject(skip,GRAPH,Igepad);

        objname[ strlen(VarFrqNames[k]) ]='k';
	cut = SUIT_createButton(objname,Cut);
	SUIT_setText(cut,LABEL,"Cut");
        SUIT_setObject(cut,GRAPH,Igepad);

        objname[ strlen(VarFrqNames[k]) ]='q';
	ins = SUIT_createButton(objname,Ins);
	SUIT_setText(ins,LABEL,"Ins");
        SUIT_setObject(ins,GRAPH,Igepad);

        objname[ strlen(VarFrqNames[k]) ]='c';
	cursors = SUIT_createOnOffSwitch(objname,Cursors);
        SUIT_setObject(cursors,GRAPH,Igepad);
	SUIT_setText(cursors,LABEL,"Cursors");

        objname[ strlen(VarFrqNames[k]) ]='v';
	av = SUIT_createOnOffSwitch(objname,Av);
        SUIT_setObject(av,GRAPH,Igepad);
	SUIT_setText(av,LABEL,"AV");

        objname[ strlen(VarFrqNames[k]) ]='f';
	af = SUIT_createOnOffSwitch(objname,Af);
        SUIT_setObject(af,GRAPH,Igepad);
	SUIT_setText(af,LABEL,"AF");

        objname[ strlen(VarFrqNames[k]) ]='h';
	ah = SUIT_createOnOffSwitch(objname,Ah);
        SUIT_setObject(ah,GRAPH,Igepad);
	SUIT_setText(ah,LABEL,"AH");

        objname[ strlen(VarFrqNames[k]) ]='l';
	zoom = SUIT_createOnOffSwitch(objname,Zoom);
        SUIT_setObject(zoom,GRAPH,Igepad);
	SUIT_setText(zoom,LABEL,"Zoom");



        SUIT_setFont(xv,FONT,trn10);
        SUIT_setFont(yv,FONT,trn10);
        SUIT_setFont(tname,FONT,trn10);
        SUIT_setFont(tonic,FONT,trn10);
        SUIT_setFont(zero,FONT,trn10);
        SUIT_setFont(cursors,FONT,trn10);
        SUIT_setFont(inter,FONT,trn10);
        SUIT_setFont(cut,FONT,trn10);
        SUIT_setFont(ins,FONT,trn10);
        SUIT_setFont(plus,FONT,trn10);
        SUIT_setFont(minus,FONT,trn10);
        SUIT_setFont(skip,FONT,trn10);
        SUIT_setFont(av,FONT,trn10);
        SUIT_setFont(af,FONT,trn10);
        SUIT_setFont(ah,FONT,trn10);
        SUIT_setFont(zoom,FONT,trn10);

        objname[ strlen(VarFrqNames[k]) ]='e';
	stacker = SUIT_createStacker(objname);
        SUIT_setEnumString( stacker , ACTIVE_DISPLAY ,
                        "horizontal stacking");

	SUIT_addChildToObject(stacker,tname);
	SUIT_addChildToObject(stacker,xv);
	SUIT_addChildToObject(stacker,yv);
	SUIT_addChildToObject(stacker,zero);
	SUIT_addChildToObject(stacker,tonic);
	SUIT_addChildToObject(stacker,skip);
	SUIT_addChildToObject(stacker,inter);
	SUIT_addChildToObject(stacker,plus);
	SUIT_addChildToObject(stacker,minus);
	SUIT_addChildToObject(stacker,cut);
	SUIT_addChildToObject(stacker,ins);

	SUIT_addChildToObject(stacker,cursors);
	SUIT_addChildToObject(stacker,av);
	SUIT_addChildToObject(stacker,af);
	SUIT_addChildToObject(stacker,ah);
	SUIT_addChildToObject(stacker,zoom);

        vp = SUIT_getViewport(stacker,VIEWPORT);

/* size of stacker = min width of graph */
	stackerwidth = vp.top_right.x - vp.bottom_left.x;
	stackerheight = vp.top_right.y - vp.bottom_left.y;

        SUIT_setViewport(Igebb[k],VIEWPORT,
		SUIT_defViewport(0,0,(int)(stackerwidth),(int)(8*stackerheight)));

        SUIT_addChildToObject(Igebb[k],stacker);

	parvp = SUIT_getViewport(Igebb[k],VIEWPORT);


	vp.bottom_left.x = parvp.bottom_left.x;
	vp.bottom_left.y = parvp.top_right.y - stackerheight;
	vp.top_right.y = parvp.top_right.y;
	vp.top_right.x = parvp.top_right.x;

	SUIT_setViewport(stacker,VIEWPORT,vp);
        SUIT_setBoolean(xv,SHRINK_TO_FIT,FALSE);
        SUIT_setBoolean(yv,SHRINK_TO_FIT,FALSE);

        vp.top_right.y = vp.bottom_left.y - 
                 (parvp.top_right.x - parvp.bottom_left.x ) *.01;
        vp.bottom_left.x = parvp.bottom_left.x +
                 (parvp.top_right.x - parvp.bottom_left.x ) *.01;
        vp.bottom_left.y = parvp.bottom_left.y +
                 (parvp.top_right.y - parvp.bottom_left.y ) *.01;
        vp.top_right.x = parvp.top_right.x - 
                 (parvp.top_right.x - parvp.bottom_left.x ) *.01; 
        SUIT_setViewport(Igepad,VIEWPORT,vp);
        SUIT_setWindow(Igepad,WINDOW,
	               SUIT_defWindow(0.0,(double)minval[k],
                                      (double)nsamp-1,maxval[k]) );
	SUIT_setInteger(Igepad,PARAMETER,k);
        SUIT_setDouble(Igepad,CURSOR1_X,(double)nsamp/4.0);
        SUIT_setDouble(Igepad,CURSOR1_Y,(double)maxval[k]/2.0);
        SUIT_setDouble(Igepad,CURSOR2_X,(double)nsamp*3.0/4.0);
        SUIT_setDouble(Igepad,CURSOR2_Y,(double)maxval[k]/2.0);
 
}



/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
/*                              M A I N                                */
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */

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

/* all this garbage below simply sets up some data to test the
   various things the widget can do */

/* data! */
    for(i=0;i<nsamp;i++) {
	msecs[i]=i;
	pdata[0][i]=(i*i)/2;
    }

/* AV ! */
    for(i=0;i<nsamp;i++) {
	pdata[1][i]=0;
    }

/* AF */
    for(i=0;i<nsamp;i++) {
	pdata[2][i]=0;
    }
/* AH */
    for(i=0;i<nsamp;i++) {
	pdata[3][i]=0;
    }

/* AV */
    for(i=30;i<60;i++) {
	pdata[1][i]=60;
    }

/* AF */
    for(i=20;i<35;i++) {
	pdata[2][i]=60;
    }
/* AH */
    for(i=20;i<32;i++) {
	pdata[3][i]=60;
    }


/* AV */
    for(i=70;i<80;i++) {
	pdata[1][i]=60;
    }
/* AH */
    for(i=65;i<72;i++) {
	pdata[3][i]=60;
    }


    minval[0] = 0;
    maxval[0] = 5000;
    defval[0] = 1000;

    minval[1] = 0;
    maxval[1] = 80;
    defval[0] = 60;

pt1.x = 10.0;
pt1.y = 50.0;
pt2.x = 15.0;
pt2.y = 50.0;

/* here ends the data setting up thingy bit */

    SUIT_init(argv[0]);

    makegraph(0); /* make graph one */     
    makegraph(1); /* shove another on top */

                  /* my "real" app handles viewports 
                     for placing dynamic graphs */

    SUIT_createDoneButton (NULL);

    SUIT_beginStandardApplication();


}
