/***************************************************************
LanceMan's quickplot --- a fast interactive 2D plotter

Copyright (C) 1998, 1999  Lance Arsenault

This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; version 2
of the License.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.

Or look at http://www.gnu.org/copyleft/gpl.html .

**********************************************************************/
/* $Id: draw_axis.c,v 1.3 1999/03/01 01:57:30 lance Exp $ */
#include <stdio.h>
#include <string.h>
#include <X11/Xlib.h> 
#include <X11/Intrinsic.h>
#include <X11/StringDefs.h>
#include <math.h>

#include "data.h"
#include "xwin.h"

#define ABS(x) ((x)>0.0?(x):(-(x)))

static void round(double *min, double *max, char *min_str, char *max_str, const char *ends)
{
  char format[20];
  int j;

  j = (*max>*min)?(int) log10(0.5*(ABS(*max)+ABS(*min))/(*max - *min)):15;
  if(j<0)
    j = 0;
  else if(j>15)
    j = 14;
  j += 2;
  sprintf(format,"%s%%.%dg%s",ends,j,ends);
  /* printf("format = %s j = %d\n",format,j); */
  sprintf(max_str,format,*max);
  sscanf(max_str,"%lf",max);

  sprintf(min_str,format,*min);
  sscanf(min_str,"%lf",min);
}


/* spagetti code at it's best */

void draw_axis(PlotXwins *win, Plot *plot, Drawable drawable, 
		      unsigned int width, unsigned int height)
{
  double xmin, xmax, ymin, ymax;
  int xmin_i, xmax_i, ymin_i, ymax_i;
  int little;


  xmin_i = (0.1)*width;
  xmax_i = width - xmin_i;

  ymax_i = (0.1)*height;
  ymin_i = height - ymax_i;

  xmin =  (
	    ( xmin_i - plot->z_shift[plot->zoom_count][X] )/
	        plot->z_scale[plot->zoom_count][X] - plot->shift[0][X]
	  ) / plot->scale[0][X];

  xmax =  (
	    (xmax_i - plot->z_shift[plot->zoom_count][X] )/
	        plot->z_scale[plot->zoom_count][X] - plot->shift[0][X]
	  ) / plot->scale[0][X];


  ymax =  (
	    (ymax_i  - plot->z_shift[plot->zoom_count][Y] )/
	        plot->z_scale[plot->zoom_count][Y] - plot->shift[0][Y]
	  ) / plot->scale[0][Y];

  ymin =  (
	    (ymin_i - plot->z_shift[plot->zoom_count][Y] )/
	        plot->z_scale[plot->zoom_count][Y] - plot->shift[0][Y]
	  ) / plot->scale[0][Y];

#if(1)
  {
    char min_str[30], max_str[30];
    int length,dist;
    int max_i, min_i;
    int j;

    round(&ymin,&ymax,min_str,max_str," ");
    max_i = ( plot->scale[0][Y]*ymax + plot->shift[0][Y] )*
		 plot->z_scale[plot->zoom_count][Y] +
		 plot->z_shift[plot->zoom_count][Y];
    if(max_i < 0)
      max_i = 0;
    min_i = ( plot->scale[0][Y]*ymin + plot->shift[0][Y] )*
		 plot->z_scale[plot->zoom_count][Y] +
		 plot->z_shift[plot->zoom_count][Y];
    if(min_i >= height)
      min_i = height-1;

    little = xmin_i/2;
    XSetForeground(win->display,win->gc,win->grey_pix);
    XDrawLine(win->display,drawable,win->gc,xmin_i - little,min_i,xmax_i + little,min_i);
    XDrawLine(win->display,drawable,win->gc,xmin_i - little,max_i,xmax_i + little,max_i);

    XSetBackground(win->display,win->gc,win->BWbackground_pix);
    XSetForeground(win->display,win->gc,win->BWforeground_pix);

    /** ymax **/
    dist = (max_i > win->font_struct->ascent/2)?
      max_i + win->font_struct->ascent/2:win->font_struct->ascent+1;
    length = strlen(max_str);
    XDrawImageString(win->display,drawable,win->gc,(int)width/2 -
		     XTextWidth(win->font_struct, max_str, length)/2
		     ,dist,max_str,length);
    /** ymin **/
    dist = (min_i + win->font_struct->ascent/2 < (int) height)?
      min_i + win->font_struct->ascent/2:(int) height - 1;
    length = strlen(min_str);
    XDrawImageString(win->display,drawable,win->gc,(int)width/2 -
		     XTextWidth(win->font_struct, min_str, length)/2
		     ,dist,min_str,length);

    round(&xmin,&xmax,min_str,max_str,"");
    max_i = ( plot->scale[0][X]*xmax + plot->shift[0][X] )*
		 plot->z_scale[plot->zoom_count][X] +
		 plot->z_shift[plot->zoom_count][X];
    if(max_i >= width)
      max_i = width -1;
    min_i = ( plot->scale[0][X]*xmin + plot->shift[0][X] )*
		 plot->z_scale[plot->zoom_count][X] +
		 plot->z_shift[plot->zoom_count][X];
    if(min_i < 0)
      min_i = 0;

    little = ymax_i/2;
    XDrawLine(win->display,drawable,win->gc,min_i,ymin_i + little,min_i,ymax_i - little);
    XDrawLine(win->display,drawable,win->gc,max_i,ymin_i + little,max_i,ymax_i - little);
        
    XSetBackground(win->display,win->gc,win->BWbackground_pix);
    XSetForeground(win->display,win->gc,win->BWforeground_pix);

    dist = height/2 + win->font_struct->ascent/2;
    /** xmax **/
    length = strlen(max_str);
    max_i -= (j = XTextWidth(win->font_struct, max_str, length))/2;
    if(max_i + j >= width)
      max_i = width - 1 - j;
    XDrawImageString(win->display,drawable,win->gc,max_i
		     ,dist,max_str,length);
    /** xmin **/
    length = strlen(min_str);
    j = XTextWidth(win->font_struct, min_str, length)/2;
    XDrawImageString(win->display,drawable,win->gc,
		     (min_i - j >= 1)?min_i - j:1
		     ,dist,min_str,length);
  }

  XFlush(win->display);
#endif

}
