 /*
  * Khoros: $Id: axes2.c,v 1.2 1992/03/20 22:45:39 dkhoros Exp $
  */

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

 /*
  * $Log: axes2.c,v $
 * Revision 1.2  1992/03/20  22:45:39  dkhoros
 * VirtualPatch5
 *
  */ 

/*
 *----------------------------------------------------------------------
 *
 * Copyright 1990, University of New Mexico.  All rights reserved.

 * Permission to copy and modify this software and its documen-
 * tation only for internal use in your organization is hereby
 * granted, provided that this notice is retained thereon and
 * on all copies.  UNM makes no representations as too the sui-
 * tability and operability 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 OTHER DAMAGES WHAT-
 * SOEVER 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 PER-
 * FORMANCE OF THIS SOFTWARE.
 * 
 * No other rights, including for example, the right to redis-
 * tribute this software and its documentation or the right to
 * prepare derivative works, are granted unless specifically
 * provided in a separate license agreement.
 *---------------------------------------------------------------------
 */

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


/* >>>>>>>>>>>>>>>>>>>>>>>>>>>>> <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
   >>>>                                                       <<<<
   >>>>	    file name:  axes2.c
   >>>>               
   >>>>   description: This file contains the code for generating
   >>>>			the 2D axes and labels.
   >>>>                
   >>>>      routines: 	
   >>>>			draw_axis_xp2()
   >>>>			draw_axis_2D()
   >>>>			xtics_xp2()
   >>>>			ytics_xp2()
   >>>>              
   >>>> modifications:
   >>>>                                                       <<<<
   >>>>>>>>>>>>>>>>>>>>>>>>>>>>> <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< */


/************************************************************
*
*  MODULE NAME: draw_axis_xp2
*
*      PURPOSE: draws axes on 2D plot; adds tics, numbers, labels
*
*        INPUT: gwin - pointer to the VPGraphicsWindow structure
*
*       OUTPUT: none
*
*    CALLED BY: plot_routine
*
*   WRITTEN BY: Danielle Argiro & Mike Lang
*
*
*************************************************************/

draw_axis_xp2(plot_type, do_obscure)
int plot_type, do_obscure;
{
        char *xaxis_label= NULL, *yaxis_label = NULL;
        char *add_power_axis_label();

        if (gwin_attr->draw_axes)
	   draw_axis_2D();

	xtics_xp2(gwin->plot_type);
	ytics_xp2(gwin->plot_type);

	           /* print out X Axis title */
        if (! gwin_attr->clear_labels)
        {
	   if (gwin_attr->draw_numlabels)
               xaxis_label = add_power_axis_label(gwin_attr->xaxis, 
                                           (int) gwin_attr->power_ten.x);
	   else
	       xaxis_label = VStrcpy(gwin_attr->xaxis);
	   write_label(gwin->plot_type,XAXIS, xaxis_label, 
	             gwin_attr->current_colors[XTITLE_COLOR]);
	   if (xaxis_label != NULL)
		free(xaxis_label);

	          /* print out Y Axis title */
	   if (gwin_attr->draw_numlabels)
               yaxis_label = add_power_axis_label(gwin_attr->yaxis, 
                                           (int) gwin_attr->power_ten.y);
	   else
	       yaxis_label = VStrcpy(gwin_attr->yaxis);
	   write_label(gwin->plot_type,YAXIS, yaxis_label, 
		       gwin_attr->current_colors[YTITLE_COLOR]);
	   if (yaxis_label != NULL)
		free(yaxis_label);

	        /* always print out the plot title */
	   write_label(gwin->plot_type,TITLE, gwin_attr->title, 
		    gwin_attr->current_colors[TITLE_COLOR]);
        }

}



/************************************************************
*
*  MODULE NAME: draw_axis_2D
*
*      PURPOSE: draws axes on 2D plot
*
*        INPUT: gwin - pointer to the VPGraphicsWindow structure
*
*       OUTPUT: none
*
*    CALLED BY: draw_axes
*
*   WRITTEN BY: Danielle Argiro & Mike Lang
*
*
*************************************************************/


draw_axis_2D()
{

	Coord axes[3]; 
	int  colorindex; 

	/* draw X axis */
	axes[0].x = gwin_attr->disp_scale_min.x; 
        axes[0].y = gwin_attr->disp_scale_min.y;
	axes[1].x = gwin_attr->disp_scale_max.x; 
	axes[1].y = gwin_attr->disp_scale_min.y;

	/* set the xaxis color */
	if (xp_device != xpX11)
            X3D_set_line_width(gwin->id, ExtraWide);
	colorindex = gwin_attr->current_colors[XAXIS_COLOR];
	X2D_draw_polyline(gwin->id, axes, 2, &Colors[colorindex]); 

	/* draw Y axis */
	axes[0].y = gwin_attr->disp_scale_min.y; 
        axes[0].x = gwin_attr->disp_scale_min.x;
	axes[1].y = gwin_attr->disp_scale_max.y; 
        axes[1].x = gwin_attr->disp_scale_min.x;

	/* set the yaxis color */
	if (xp_device != xpX11)
            X3D_set_line_width(gwin->id, ExtraWide);
	colorindex = gwin_attr->current_colors[YAXIS_COLOR];
	X2D_draw_polyline(gwin->id, axes, 2, &Colors[colorindex]); 
}



/************************************************************
*
*  MODULE NAME: xtics_xp2
*
*      PURPOSE: draws tics, numbers on plots;
*
*        INPUT: gwin - pointer to the VPGraphicsWindow structure
*
*       OUTPUT: none
*
*    CALLED BY: draw_axis_2D draw_axes_3D
*
*   WRITTEN BY: Danielle Argiro & Mike Lang
*
*
*************************************************************/

xtics_xp2(plot_type)
int plot_type;
{
	Vector direction;
	Coord  *tic_lines, *text_coords;
	char tmp_str[100],scale[10];
	caddr_t *axes;
	float width, height, depth = 0, bot_point;
	double x, minor_x;
	float tic_size, half_tic, minor_half_tic, half_tic2;
	char *get_axis_scale();
	double multiplier, last_tic_label, new_minor_tic_intv = 0.0;
	int  num_tics, j=0, i=0, num_minor_tics=0, colorindex;
	int  characters_displayed,decimal_places,power_ten;
        int need_end = 0, num_new_minor_tics = 0, index;
        int last_major_tic, last_characters_displayed, new_index;
	int xpercision_err = False;

	direction.x = 1.0;
	direction.y = 0.0;
	direction.z = 0.0;

        if (gwin_attr->rescale_relabel == RELABEL)
            X2D_set_wc_min_max (gwin->id, gwin_attr->disp_label_min, 
                                          gwin_attr->disp_label_max);

	num_tics = (int)(gwin_attr->disp_label_num_tics.x);
	tic_size = 30.0;
	
	half_tic = (gwin_attr->disp_label_max.y - gwin_attr->disp_label_min.y)
                   / tic_size;
	minor_half_tic = 0.5 * half_tic;

	/* set the width and height of characters */
	width = (gwin_attr->disp_label_max.x - gwin_attr->disp_label_min.x)
                / (1.5 * tic_size);
	height = (gwin_attr->disp_label_max.y - gwin_attr->disp_label_min.y)
                / (1.5 * tic_size);  
	
	characters_displayed = (int)
	((((gwin_attr->disp_label_max.x - gwin_attr->disp_label_min.x)/width)
            / gwin_attr->disp_label_num_tics.x) - 3);

	if(characters_displayed > 6) characters_displayed = 6;

	find_scale_factor(characters_displayed,
                          (double)gwin_attr->disp_label_max.x,
			  (double)gwin_attr->disp_label_min.x,
                          (double)gwin_attr->disp_label_major_intv.x,
			  &decimal_places,&multiplier,&power_ten);
            
        gwin_attr->power_ten.x = (float) power_ten;

	if((characters_displayed >= 3) || 
			(characters_displayed >= 2 && decimal_places == 0))
	{
	   sprintf(scale,"%%.%df",decimal_places);
	}
	else /* too many tics so we only draw first and last label */
   	{
            /* compute a new interval since we only want to
             * label the first and laast points,
             * so, we say we have an 2 tics
             */

/* on the next line I changed height to width 
            characters_displayed = (int)
            ((((gwin_attr->disp_label_max.x - gwin_attr->disp_label_min.x)
                 / height) / 2.0) -1.0);
*/

            characters_displayed = (int)
            ((((gwin_attr->disp_label_max.x - gwin_attr->disp_label_min.x)
                 / width) / 2.0) -1.0);
            if(characters_displayed > 6) characters_displayed = 6;

                /* find a new scale factor based on an interval
                 * of two
                 */
            find_scale_factor(characters_displayed,
                        (double)gwin_attr->disp_label_max.x,
                        (double)gwin_attr->disp_label_min.x,
                        (double)gwin_attr->disp_label_major_intv.x,
                        &decimal_places,&multiplier,&power_ten);

            gwin_attr->power_ten.x = (float) power_ten;

	    sprintf(scale,"%%.%df",decimal_places);
       	    xpercision_err = TRUE;
   	}


         /* set up for the last tic mark, we want to label the end point
          * on the axis. so must figure out how to do it
          */

	last_tic_label = (double)gwin_attr->disp_label_min.x + 
                       (((double) num_tics - 1.0) 
                       * (double)gwin_attr->disp_label_major_intv.x);
        
        if ( last_tic_label != (double)gwin_attr->disp_label_max.x)
        {
            need_end = True;
   
            last_major_tic = (int) (num_tics - 1.0);

             /* calculate the number of minor tics we need to add */

            x = gwin_attr->disp_label_max.x - last_tic_label;
            new_minor_tic_intv = ((double) gwin_attr->disp_label_major_intv.x / 
                           (double) ((int) (gwin_attr->minor_tics.x +0.5 + 1)));

	    if (new_minor_tic_intv == 0.0)
		num_new_minor_tics = 0;
	    else
                num_new_minor_tics = (int) 
                      (((double)gwin_attr->disp_label_max.x - last_tic_label) / 
                         new_minor_tic_intv);
        }


	if (gwin_attr->minor_tics.x > 0)
	{
	   num_minor_tics += (int) ((num_tics - 1) * gwin_attr->minor_tics.x);
	}

	/* malloc memory for the coords and the labels
         * add the +1 to the malloc in case we need
         * room for the end point, if we dont need room
         * then we malloced and extra point. 
         */

	tic_lines =  (Coord *)malloc((unsigned)
		      (sizeof(Coord) * 2 * ( num_new_minor_tics + 
                       num_minor_tics + (num_tics + 1))));
	text_coords = (Coord *) malloc((unsigned) 
                      (sizeof(Coord) * (num_tics + 1)));
	axes = (caddr_t *)(malloc((unsigned)
                      (sizeof(caddr_t) * (num_tics + 1))));

	half_tic2 = (2.0 * half_tic);

	/* load the coords for the axes and print the number
	 * strings into an array.
	 */
	x = (double)gwin_attr->disp_label_min.x;
	if (! xpercision_err)
	{
	   for(i=0;i<num_tics;i++)
	   {
	      bzero(tmp_str,100);
	      (void) sprintf(tmp_str, scale, (float) (x * multiplier));
	      axes[i] = (caddr_t)VStrcpy(tmp_str);
	      text_coords[i].x = (float)x;
	      text_coords[i].y = gwin_attr->disp_label_min.y - half_tic2;
   
	      x += (double)gwin_attr->disp_label_major_intv.x;
           }
 
           if (need_end) 
           {
              bzero(tmp_str,100);
              (void) sprintf(tmp_str, scale, (float) 
			((double) gwin_attr->disp_label_max.x * multiplier));
              axes[i] = (caddr_t)VStrcpy(tmp_str);
              text_coords[i].x = (float) gwin_attr->disp_label_max.x;
              text_coords[i].y = gwin_attr->disp_label_min.y - half_tic2;
           }
	}
	else 
	{
	      bzero(tmp_str,100);
	      (void) sprintf(tmp_str, scale, (float) (x * multiplier));
	      axes[0] = (caddr_t)VStrcpy(tmp_str);
	      text_coords[0].x = gwin_attr->disp_label_min.x;
	      text_coords[0].y = gwin_attr->disp_label_min.y - half_tic2;

              if (need_end) 
		index = num_tics;
              else
		index = num_tics - 1;

              bzero(tmp_str,100);
              (void) sprintf(tmp_str, scale, (float)
                         ((double) gwin_attr->disp_label_max.x * multiplier));
              axes[index] = (caddr_t)VStrcpy(tmp_str);
              text_coords[index].x = (float) gwin_attr->disp_label_max.x;
              text_coords[index].y = gwin_attr->disp_label_min.y - half_tic2;

	      x = (double)gwin_attr->disp_label_min.x 
			+ (double)gwin_attr->disp_label_major_intv.x;
	      bzero(scale,10);
	      for(i=1;i<index;i++)
              {
                 bzero(tmp_str,100);
                 (void) sprintf(tmp_str, scale, (float) (x * multiplier));
                 axes[i] = (caddr_t)VStrcpy(tmp_str);
                 text_coords[i].x = (float)x;
                 text_coords[i].y = gwin_attr->disp_label_min.y - half_tic2;

                 x += (double)gwin_attr->disp_label_major_intv.x;
              }
	}
   
	/* load the coords for the major and minor tics */
   
	x = (double)gwin_attr->disp_label_min.x;
	for(i=0; i < 2*(num_tics+num_minor_tics);)
	{
	   tic_lines[i].x = (float)x;
	   tic_lines[i++].y = gwin_attr->disp_label_min.y;
  
	   tic_lines[i].x = (float)x;
	   tic_lines[i++].y = gwin_attr->disp_label_min.y - half_tic;

	   if(gwin_attr->minor_tics.x > 0 && i < 2*(num_tics+num_minor_tics))
	   {
		minor_x = x;
		/* load in the minor tics (note I have to round up 
		 * because minor_tics is a Coord float)
		 */
		for(j=0;j<(int)(gwin_attr->minor_tics.x + 0.5);j++)
		{
		   minor_x += (double)
			(gwin_attr->disp_label_major_intv.x/(gwin_attr->minor_tics.x + 1));

		   tic_lines[i].x = (float)minor_x;
		   tic_lines[i++].y = gwin_attr->disp_label_min.y - minor_half_tic;

		   tic_lines[i].x = (float)minor_x;
		   tic_lines[i++].y = gwin_attr->disp_label_min.y;
		}
	   }
	   x += (double)gwin_attr->disp_label_major_intv.x;
        }

           /* if the end point needs to be taken care of. for the
            * major tic and the minopr tics, we do it here.
            */

        if (need_end) 
        {
             /* Need to add the major tic line for the maximum value
              * on the axis
              */

	   tic_lines[i].x = (float) gwin_attr->disp_label_max.x;
	   tic_lines[i++].y = gwin_attr->disp_label_min.y;

	   tic_lines[i].x = (float) gwin_attr->disp_label_max.x;
	   tic_lines[i++].y = gwin_attr->disp_label_min.y - half_tic;
           num_tics++;
  
           /* need to add the minor tics in between the last 
            * major interval tic and the maximum tic
            */
  
           for ( j = 0; j < num_new_minor_tics; j++)
           {
 
                minor_x = last_tic_label + 
                          ((double) j + 1.0) * new_minor_tic_intv;

               tic_lines[i].x = (float)minor_x;
               tic_lines[i++].y = gwin_attr->disp_label_min.y - minor_half_tic;

               tic_lines[i].x = (float)minor_x;
               tic_lines[i++].y = gwin_attr->disp_label_min.y;
               num_minor_tics++;
           }


           /* now check to see if we have enough room to print the
            * label for the max value without running into the
            * previous major tics value. If ok then continue,
            * otherwise delete the major tic and the label closest 
            * to the maximum value (end point on the axis)
            */
        
           last_characters_displayed = (int) (((gwin_attr->disp_label_max.x - 
                              last_tic_label)/width) - 2);

           if ( (last_characters_displayed < characters_displayed)
			&& (! xpercision_err))
           {
              bzero(scale,10);
              axes[last_major_tic] = (caddr_t)VStrcpy(scale);

              new_index = 
                   (last_major_tic + num_minor_tics - num_new_minor_tics) * 2;

              if ( gwin_attr->minor_tics.x > 0 )
              {
                  tic_lines[new_index].x = (float) last_tic_label;
                  tic_lines[new_index].y = gwin_attr->disp_label_min.y - minor_half_tic;
                  tic_lines[new_index + 1].x = (float) last_tic_label;
                  tic_lines[new_index + 1].y = gwin_attr->disp_label_min.y;
              }
              else
              {
                  tic_lines[new_index].x = (float) last_tic_label;
                  tic_lines[new_index].y = gwin_attr->disp_label_min.y;
                  tic_lines[new_index + 1].x = (float) last_tic_label;
                  tic_lines[new_index + 1].y = gwin_attr->disp_label_min.y;
              }

           }
        }
 
        if (gwin_attr->draw_axes)
        {
	   if (xp_device != xpX11)
               X3D_set_line_width(gwin->id, Fine);
	   colorindex = gwin_attr->current_colors[XAXIS_COLOR];
	   X2D_draw_segments(gwin->id, tic_lines, 2*(num_minor_tics+num_tics),
			     &Colors[colorindex]);
           if (gwin_attr->draw_box)
           {
               bot_point = tic_lines[1].y;
               for (i = 0; i < 2 * (num_minor_tics + num_tics); i += 2)
               {
                  if ( tic_lines[i].y == tic_lines[i+1].y)
                  {
                     tic_lines[i].y =  gwin_attr->disp_label_max.y;
                     tic_lines[i+1].y =  gwin_attr->disp_label_max.y;
                  }
                  else
                  {
                     tic_lines[i].y =  gwin_attr->disp_label_max.y;
                     if (fabs(tic_lines[i+1].y - bot_point) > 0.25 * half_tic)
                        tic_lines[i+1].y = gwin_attr->disp_label_max.y + minor_half_tic;
                     else
                        tic_lines[i+1].y = gwin_attr->disp_label_max.y + half_tic;
                  }
               }
	       X2D_draw_segments(gwin->id, tic_lines, 
                                 2*(num_minor_tics + num_tics),
			         &Colors[colorindex]);
           } 
        }

        if (gwin_attr->draw_numlabels)
	    label_tics(axes,text_coords,num_tics,plot_type,XNUMS_COLOR,
		       width,height,depth,direction);

        if (gwin_attr->rescale_relabel == RELABEL)
            X2D_set_wc_min_max (gwin->id, gwin_attr->disp_scale_min, 
                                          gwin_attr->disp_scale_max);

	free(tic_lines);
	free(axes);
	free(text_coords);
}



/************************************************************
*
*  MODULE NAME: ytics_xp2
*
*      PURPOSE: draws the major and minor tics on the y axis
*
*        INPUT:
*
*       OUTPUT: none
*
*    CALLED BY: draw_axis_xp2
*
*   WRITTEN BY: Mike Lang, Tom Sauer
*
*************************************************************/
ytics_xp2(plot_type)

int plot_type;
{


	Vector direction;
	Coord *tic_lines, *text_coords;
	char tmp_str[100], scale[10];
	caddr_t *axes;
	float width, height, depth = 0;
	float tic_size, half_tic, half_tic2, bot_point, minor_half_tic;
        char *get_axis_scale();
        double multiplier, last_tic_label, new_minor_tic_intv = 0.0, y, minor_y;
	int  num_tics, j=0, i=0, num_minor_tics=0, colorindex;
	int  characters_displayed, decimal_places, power_ten;
        int need_end = 0, num_new_minor_tics = 0;
        int last_major_tic, last_characters_displayed, new_index;
	int ypercision_err = False, index;

	direction.x = 0.0;
	direction.y = 1.0;
	direction.z = 0.0;

        if (gwin_attr->rescale_relabel == RELABEL)
            X2D_set_wc_min_max (gwin->id, gwin_attr->disp_label_min, 
                                          gwin_attr->disp_label_max);

	num_tics = (int)(gwin_attr->disp_label_num_tics.y);
	tic_size = 30.0;

	half_tic = (gwin_attr->disp_label_max.x - gwin_attr->disp_label_min.x)
                   / tic_size;
	minor_half_tic = 0.5 * half_tic;

	width = (gwin_attr->disp_label_max.x - gwin_attr->disp_label_min.x)
                / (1.5 * tic_size);
	height = (gwin_attr->disp_label_max.y - gwin_attr->disp_label_min.y)
                 / (1.5 * tic_size);  

	characters_displayed = (int)
	((((gwin_attr->disp_label_max.y - gwin_attr->disp_label_min.y)
                 / height) / gwin_attr->disp_label_num_tics.y) -2.0);

        if(characters_displayed > 6) characters_displayed = 6;



        find_scale_factor(characters_displayed,
                               (double)gwin_attr->disp_label_max.y,
	  		       (double)gwin_attr->disp_label_min.y,
                               (double)gwin_attr->disp_label_major_intv.y,
			       &decimal_places,&multiplier,&power_ten);

        gwin_attr->power_ten.y = (float) power_ten;

             /* for nice data this should work */
        if((characters_displayed >= 3) ||
                        (characters_displayed >= 2 && decimal_places == 0))
        {
	     sprintf(scale,"%%.%df",decimal_places);
        }
	else /* too many tics so we only draw first and last label */
	{
            /* compute a new interval since we only want to
	     * label the first and laast points,
	     * so, we say we have an 2 tics
	     */
	    characters_displayed = (int)
	    ((((gwin_attr->disp_label_max.y - gwin_attr->disp_label_min.y)
                 / height) / 2.0) -1.0);

            if(characters_displayed > 6) characters_displayed = 6;

		/* find a new scale factor based on an interval
		 * of two
		 */
	    find_scale_factor(characters_displayed,
			(double)gwin_attr->disp_label_max.y,
                        (double)gwin_attr->disp_label_min.y,
			(double)gwin_attr->disp_label_major_intv.y,
                        &decimal_places,&multiplier,&power_ten);

	    gwin_attr->power_ten.y = (float) power_ten;
	    sprintf(scale,"%%.%df",decimal_places);
	    ypercision_err = TRUE;
	}



        last_tic_label = (double) gwin_attr->disp_label_min.y +
                         (((double) num_tics - 1.0) 
                         * (double) gwin_attr->disp_label_major_intv.y);

        if ( last_tic_label != (double) gwin_attr->disp_label_max.y )
        {
            need_end = True;

              /* calculate the last major tic mark */
            last_major_tic = (int) (num_tics - 1.0);

             /* calculate the number of minor tics we need to add */

            y = gwin_attr->disp_label_max.y - last_tic_label;
            new_minor_tic_intv = ((double) gwin_attr->disp_label_major_intv.y /
                           (double) ((int) (gwin_attr->minor_tics.y +0.5 + 1)));

	    if (new_minor_tic_intv == 0.0)
		num_new_minor_tics = 0;
	    else
                num_new_minor_tics = (int)
                      (((double)gwin_attr->disp_label_max.y - last_tic_label) /
                         new_minor_tic_intv);
        }

	if (gwin_attr->minor_tics.y > 0)
	   num_minor_tics += (int) ((num_tics - 1) 
			     * gwin_attr->minor_tics.y);

        /* malloc memory for the coords and the labels
         * add the +1 to the malloc in case we need
         * room for the end point, if we dont need room
         * then we malloced and extra point.
         */

	tic_lines =  (Coord *)malloc((unsigned) 
                      (sizeof(Coord) * 2 * (num_new_minor_tics + 
                                            num_minor_tics + num_tics + 1)));

	text_coords = (Coord *) malloc((unsigned) 
                       (sizeof(Coord) * (num_tics + 1)));
	axes = (caddr_t *)(malloc((unsigned)
                       (sizeof(caddr_t) * (num_tics + 1))));

	text_coords[0].y = gwin_attr->disp_label_min.y;
	half_tic2 = 2.0 * half_tic;
	y = (double)gwin_attr->disp_label_min.y;
        if (! ypercision_err)
	{
	   for(i=0,j=0; i<num_tics; i++)
	   {
	      bzero(tmp_str,100);
	      (void) sprintf(tmp_str, scale, y*multiplier);
	      axes[i] = (caddr_t)VStrcpy(tmp_str);
	      text_coords[j].x = gwin_attr->disp_label_min.x - half_tic2;
	      text_coords[j].y = (float)y;
	      j++;
	      y += (double)gwin_attr->disp_label_major_intv.y;
	   }

           if (need_end)
           {
              bzero(tmp_str,100);
              (void) sprintf(tmp_str, scale, 
                            (double) gwin_attr->disp_label_max.y * multiplier);
              axes[i] = (caddr_t)VStrcpy(tmp_str);
              text_coords[j].x = gwin_attr->disp_label_min.x - half_tic2;
              text_coords[j].y = (float) gwin_attr->disp_label_max.y;
           }
	}
	else
	{
	      bzero(tmp_str,100);
	      (void) sprintf(tmp_str, scale, y * multiplier);
	      axes[0] = (caddr_t)VStrcpy(tmp_str);
	      text_coords[0].x = gwin_attr->disp_label_min.x - half_tic2;
	      text_coords[0].y = gwin_attr->disp_label_min.y;
              if (need_end) 
		index = num_tics;
              else
		index = num_tics - 1;
              bzero(tmp_str,100);
              (void) sprintf(tmp_str, scale, 
                         (double) gwin_attr->disp_label_max.y * multiplier);
              axes[index] = (caddr_t)VStrcpy(tmp_str);
              text_coords[index].x = gwin_attr->disp_label_min.x - half_tic2;
              text_coords[index].y = (float) gwin_attr->disp_label_max.y;

	      y = (double)gwin_attr->disp_label_min.y 
			+ (double)gwin_attr->disp_label_major_intv.y;
	      bzero(scale,10);
	      for(i=1;i<index;i++)
              {
                 bzero(tmp_str,100);
                 (void) sprintf(tmp_str, scale, y * multiplier);
                 axes[i] = (caddr_t)VStrcpy(tmp_str);
                 text_coords[i].x = gwin_attr->disp_label_min.x - half_tic2;
                 text_coords[i].y = (float)y;

                 y += (double)gwin_attr->disp_label_major_intv.y;
              }
	}
        /* load the coords for the major and minor tics */


	y = (double)gwin_attr->disp_label_min.y;
	for(i=0; i < 2*(num_tics+num_minor_tics);)
	{

	   tic_lines[i].x = gwin_attr->disp_label_min.x - half_tic;
	   tic_lines[i++].y = (float)y;

	   tic_lines[i].x = gwin_attr->disp_label_min.x;
	   tic_lines[i++].y = (float)y;

	   if(gwin_attr->minor_tics.y > 0 && i < 2*(num_tics+num_minor_tics))
	   {
		minor_y = y;
		for(j=0;j<(int)(gwin_attr->minor_tics.y + 0.5);j++)
		{
		   minor_y += (double) (gwin_attr->disp_label_major_intv.y
                                     / (gwin_attr->minor_tics.y + 1));

	    	   tic_lines[i].x = gwin_attr->disp_label_min.x-minor_half_tic;
		   tic_lines[i++].y = (float)minor_y;
		   tic_lines[i].x = gwin_attr->disp_label_min.x;
		   tic_lines[i++].y = (float)minor_y;
		}
	   }
	   y += (double)gwin_attr->disp_label_major_intv.y;

        }

        
        if (need_end)
        {
             /* Need to add the major tic line for the maximum value
              * on the axis
              */

	   tic_lines[i].x = gwin_attr->disp_label_min.x - half_tic;
           tic_lines[i++].y = gwin_attr->disp_label_max.y;

           tic_lines[i].x = (float) gwin_attr->disp_label_min.x;
           tic_lines[i++].y = (float) gwin_attr->disp_label_max.y;
           num_tics++;

           /* need to add the minor tics in between the last
            * major interval tic and the maximum tic
            */

          for ( j = 0; j < num_new_minor_tics; j++)
           {

                minor_y = last_tic_label +
                          ((double) j + 1.0) * new_minor_tic_intv;

	       tic_lines[i].x = gwin_attr->disp_label_min.x - minor_half_tic;
	       tic_lines[i++].y = (float)minor_y;

	       tic_lines[i].x = gwin_attr->disp_label_min.x;
	       tic_lines[i++].y = (float)minor_y;
               num_minor_tics++;
           }

           /* now check to see if we have enough room to print the
            * label for the max value without running into the
            * previous major tics value. If ok then continue,
            * otherwise delete the major tic and the label closest
            * to the maximum value (end point on the axis)
            */

           last_characters_displayed = (int) (((gwin_attr->disp_label_max.y -
                              last_tic_label)/height) - 2);

           if ( (! ypercision_err) 
		&& (last_characters_displayed < characters_displayed - 1))
           {
              bzero(scale,10);
              axes[last_major_tic] = (caddr_t)VStrcpy(scale);

              new_index = 
                   (last_major_tic + num_minor_tics - num_new_minor_tics) * 2;

              if ( gwin_attr->minor_tics.y > 0 )
              {
                 tic_lines[new_index].x = 
                            gwin_attr->disp_label_min.x  - minor_half_tic;
                 tic_lines[new_index].y = (float) last_tic_label;
                 tic_lines[new_index + 1].x = gwin_attr->disp_label_min.x;
                 tic_lines[new_index + 1].y = (float) last_tic_label;
              }
              else
              {
                 tic_lines[new_index].x = gwin_attr->disp_label_min.x;
                 tic_lines[new_index].y = (float) last_tic_label;
                 tic_lines[new_index + 1].x = gwin_attr->disp_label_min.x;
                 tic_lines[new_index + 1].y = (float) last_tic_label;
              }
           }
        }

        if (gwin_attr->draw_axes)
        {
	   if (xp_device != xpX11)
               X3D_set_line_width(gwin->id, Fine);
	   colorindex = gwin_attr->current_colors[YAXIS_COLOR];

	   X2D_draw_segments(gwin->id, tic_lines,2*(num_minor_tics + num_tics),
			     &Colors[colorindex]);

           if (gwin_attr->draw_box)
           {
               bot_point = tic_lines[0].x;
               for (i = 0; i < 2 * (num_minor_tics + num_tics); i += 2)
               {
                  if ( tic_lines[i].x == tic_lines[i+1].x )
                  {
                     tic_lines[i].x = gwin_attr->disp_label_max.x;
                     tic_lines[i+1].x = gwin_attr->disp_label_max.x;
                  }
                  else
                  {
                     if (fabs(tic_lines[i].x - bot_point) > 0.25 * half_tic)
                        tic_lines[i].x = 
                                gwin_attr->disp_label_max.x + minor_half_tic;
                     else
                        tic_lines[i].x = gwin_attr->disp_label_max.x + half_tic;
   
                     tic_lines[i+1].x =  gwin_attr->disp_label_max.x;
                  }
               }
	       X2D_draw_segments(gwin->id, tic_lines, 
                                 2*(num_minor_tics + num_tics),
			         &Colors[colorindex]);
           }
        } 

        if (gwin_attr->draw_numlabels)
	   label_tics(axes,text_coords,num_tics,plot_type,YNUMS_COLOR,
		      width,height,depth,direction);

        if (gwin_attr->rescale_relabel == RELABEL)
            X2D_set_wc_min_max (gwin->id, gwin_attr->disp_scale_min, 
                                          gwin_attr->disp_scale_max);
	free(tic_lines);
	free(axes);
	free(text_coords);
}
