
/* Copyright (C) 1992  AHPCRC, Univeristy of Minnesota
 *
 * 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; either version 2 of the License, or
 * (at your option) any later version.
 *
 * 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 in a file named 'Copying'; if not, write to
 * the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139.
 */

/* Author:
 *	Ken Chin-Purcell (ken@ahpcrc.umn.edu)
 *	Army High Performance Computing Research Center (AHPCRC)
 *	Univeristy of Minnesota
 *
 * $Header: /usr/people/ken/gvl/icol/RCS/abar.c,v 2.1 92/10/19 16:59:25 ken Exp $
 *
 * $Log:	abar.c,v $
 * Revision 2.1  92/10/19  16:59:25  ken
 * *** empty log message ***
 * 
 * Revision 1.1  92/10/19  16:58:08  ken
 * Initial revision
 * 
 */

#include <stdio.h>
#include <string.h>
#include <malloc.h>
#include <math.h>

#include <X11/Intrinsic.h>
#include <X11/StringDefs.h>

#include "util.h"
#include "xtutil.h"
#include "rgb.h"
#include "cbar.h"
#include "abar.h"

#define	NSTEP	32


void AxisBarResize(AxisBar *abar)
{
    Display	*display;
    Widget	w;
    Dimension	wdim, hdim;
    int		depth;
    Pixmap	map;
    int		i, j;
    int		x, width;

    if (!abar->valid)
	return;

    w = abar->bar[0].w;
    display = XtDisplay(w);

    if (!abar->gc) {
	XGCValues	gcv;
	
	GetValue(XtNbackground, &gcv.background, w);
	abar->gc = XCreateGC(display, XtWindow(w), GCBackground, &gcv);
    }

    GetValue(XtNdepth,  &depth, (Widget) NULL);
    GetValue(XtNwidth,  &wdim,  (Widget) NULL);
    GetValue(XtNheight, &hdim,  w);

    for (i = 0; i < 3; ++i) {
	w = abar->bar[i].w;
	map = XCreatePixmap(display, XtWindow(w), wdim, hdim, depth);

	width = 1 + wdim / NSTEP;
	for (j = 0; j < NSTEP; ++j) {
	    x = (j * wdim) / NSTEP;
	    XSetForeground(display, abar->gc, abar->bar[i].xcolor[j].pixel);
	    XFillRectangle(display, map, abar->gc, x, 0, width, hdim);
	}
	
	XSetWindowBackgroundPixmap(display, XtWindow(w), map);
	XFreePixmap(display, map);
    }
}


void AxisBarSetColors(AxisBar *abar, float cin[3], ColorMode rgbmode, 
		      Colormap cmap)
{
    int		i, j;
    XColor	*xc;
    float	r, g, b;
    float	channel[3];
    float	cscale = 0xffff;

    for (i = 0; i < 3; ++i) {

	for (j = 0; j < 3; ++j)
	    channel[j] = cin[j];
	
	for (j = 0; j < NSTEP; ++j) {
	    channel[i] = ((float) j + 0.5) / (float) NSTEP;
	    switch (rgbmode) {
	      case RGB_MODE:
		r = channel[0];
		g = channel[1];
		b = channel[2];
		break;
	      case HSV_MODE:
		hsv2rgb(channel[0], channel[1], channel[2], &r, &g, &b);
		break;
	      case YUV_MODE:
	      case ALPHA_MODE:
		yuv2rgb(channel[0], channel[1], channel[2], &r, &g, &b);
		break;
	    }
	    
	    xc = abar->bar[i].xcolor + j;
	    xc->red   = r * cscale;
	    xc->green = g * cscale;
	    xc->blue  = b * cscale;
	}
    
	XStoreColors(XtDisplay(abar->bar[i].w), cmap, 
		     abar->bar[i].xcolor, NSTEP);
    }
}


AxisBar *AxisBarNew(Widget *wl)
{
    AxisBar	*abar = MallocType(AxisBar);
    Pixel	holdPix[NSTEP*3];
    Colormap	cmap;
    int		i, j;

    MemCheck(abar);
    ZeroType(abar, AxisBar);
    
    GetValue(XtNcolormap, &cmap, wl[0]);
    
    if (!XAllocColorCells(XtDisplay(wl[0]), cmap, 0, NULL, 0, 
			  holdPix, NSTEP*3))
	return abar;
    
    for (i = 0; i < 3; ++i) {
	abar->bar[i].w = wl[i];
	abar->bar[i].xcolor = CallocType(XColor, NSTEP);
	MemCheck(abar->bar[i].xcolor);
    }

    for (i = 0; i < 3; ++i)
	for (j = 0; j < NSTEP; ++j) {
	    abar->bar[i].xcolor[j].pixel = holdPix[i*NSTEP + j];
	    abar->bar[i].xcolor[j].flags = DoRed | DoGreen | DoBlue;
	}
    
    abar->valid = 1;

    return abar;
}


