/*
 *----------------------------------------------------------------------
 *
 * ConfigureBargraph --
 *
 *	This procedure is called to process an argv/argc list, plus
 *	the Tk option database, in order to configure (or
 *	reconfigure) a Bargraph widget.
 *
 * Results:
 *	The return value is a standard Tcl result.  If TCL_ERROR is
 *	returned, then interp->result contains an error message.
 *
 * Side effects:
 *	Configuration information, such as colors, border width,
 *	etc. get set for bgPtr;  old resources get freed,
 *	if there were any.
 *
 *----------------------------------------------------------------------
 */
static int
ConfigureBargraph(interp, bgPtr, objc, objv, flags)
    Tcl_Interp *interp;		    /* Used for error reporting. */
    register Bargraph *bgPtr; /* Information about widget;  may or may
				     * not already have values for some fields
				     */
     int objc;
     Tcl_Obj *CONST objv[];

    int flags;			    /* Flags to pass to Tk_ConfigureWidget. */
{
  XGCValues gcValues;
  GC newGC;
  unsigned int length;

/*	 YOU ARE HERE -- TRYING TO TCL OBJ IFY THIS ROUTINE */

/*	I see Jeff put traces to vars on the other widgets.  	*/
/*	it would be nice to have that feature here too.		*/


  
  if (Tk_ConfigureWidget(interp, bgPtr->tkwin, optionSpecs,
			 argc, argv, (char *) bgPtr, flags) != TCL_OK) {
    return TCL_ERROR;
  }

  /*
   * A few options need special processing, such as parsing the
   * orientation or setting the background from a 3-D border.
   */

  /*
   * Check for user-entered complex labels.
   * This is a list of values; each element is {value text ...}
   */
  if (!(bgPtr->alabelstr) || strcmp(bgPtr->alabelstr, bgPtr->alabelstr_u)) {
    /* There is a new value */
    length = strlen(bgPtr->alabelstr_u);
    if (bgPtr->alabelstr != NULL) {
      ckfree(bgPtr->alabelstr);
      bgPtr->alabelstr = NULL;
    }
    bgPtr->alabelstr = (char *) ckalloc(length+1);
    strcpy(bgPtr->alabelstr, bgPtr->alabelstr_u);
    if (bgPtr->alabels != NULL) {
      Tcl_Free((char *) bgPtr->alabels);
      bgPtr->alabels = NULL;
    }
    if (Tcl_SplitList(interp, bgPtr->alabelstr,
		      &bgPtr->n_alabels, &bgPtr->alabels) == TCL_ERROR) {
      Tcl_AppendResult(interp, "-alabels argument is not a proper list",
		       (char *) NULL);
      return TCL_ERROR;
    }
  }

  if (!(bgPtr->blabelstr) || strcmp(bgPtr->blabelstr, bgPtr->blabelstr_u)) {
    /* There is a new value */
    length = strlen(bgPtr->blabelstr_u);
    if (bgPtr->blabelstr != NULL) {
      ckfree(bgPtr->blabelstr);
      bgPtr->blabelstr = NULL;
    }
    bgPtr->blabelstr = (char *) ckalloc(length+1);
    strcpy(bgPtr->blabelstr, bgPtr->blabelstr_u);
    if (bgPtr->blabels != NULL) {
      Tcl_Free((char *) bgPtr->blabels);
      bgPtr->blabels = NULL;
    }
    if (Tcl_SplitList(interp, bgPtr->blabelstr,
		      &bgPtr->n_blabels, &bgPtr->blabels) == TCL_ERROR) {
      Tcl_AppendResult(interp, "-blabels argument is not a proper list",
		       (char *) NULL);
      return TCL_ERROR;
    }
  }

  /* Explicitly erase wings, in case their color was changed */
  EraseWing(bgPtr);

  /*
   * Make sure that the tick interval has the right sign so that
   * addition moves from fromVal to toVal.
   */
  bgPtr->tickInterval = fabs(bgPtr->tickInterval);

  /*
   * Make sure that the number of ticks isn't excessive: not more
   * than height/2 ticks.
   */
  if (bgPtr->tickInterval_u > 0.) {
    if ( 2.*(fabs(bgPtr->toVal_u - bgPtr->fromVal_u) /
	     bgPtr->tickInterval_u) > bgPtr->max_height) {
      Tcl_AppendResult(interp,
		       "Bad parameter combination: ",
		       "must have ((max-min)/tickInterval) < height/2",
		       (char *) NULL);
      return TCL_ERROR;
    }
  }
  bgPtr->toVal = bgPtr->toVal_u;
  bgPtr->fromVal = bgPtr->fromVal_u;
  /* Ensure that fromVal and toVal are never equal */
  if (bgPtr->toVal == bgPtr->fromVal) {
    bgPtr->toVal = 1.01 * bgPtr->fromVal;
    if (bgPtr->toVal == bgPtr->fromVal)
      bgPtr->toVal = 1.;
  }
  bgPtr->tickInterval = bgPtr->tickInterval_u;

  /*
   * Set the Bargraph value to itself;  all this does is to make sure
   * that the Bargraph's value is within the new acceptable range for
   * the Bargraph.
   */
  SetBargraphValue(bgPtr, bgPtr->value);

  Tk_SetBackgroundFromBorder(bgPtr->tkwin, bgPtr->border);

  gcValues.font = Tk_FontId(bgPtr->tkfont);
  gcValues.foreground = bgPtr->textColorPtr->pixel;
  newGC = Tk_GetGC(bgPtr->tkwin, GCForeground|GCFont, &gcValues);
  if (bgPtr->textGC != None) {
    Tk_FreeGC(bgPtr->display, bgPtr->textGC);
  }
  bgPtr->textGC = newGC;

  gcValues.font = Tk_FontId(bgPtr->Atkfont);
  gcValues.foreground = bgPtr->textColorPtr->pixel;
  newGC = Tk_GetGC(bgPtr->tkwin, GCForeground|GCFont, &gcValues);
  if (bgPtr->alabGC != None) {
    Tk_FreeGC(bgPtr->display, bgPtr->alabGC);
  }
  bgPtr->alabGC = newGC;

  gcValues.font = Tk_FontId(bgPtr->Btkfont);
  gcValues.foreground = bgPtr->textColorPtr->pixel;
  newGC = Tk_GetGC(bgPtr->tkwin, GCForeground|GCFont, &gcValues);
  if (bgPtr->blabGC != None) {
    Tk_FreeGC(bgPtr->display, bgPtr->blabGC);
  }
  bgPtr->blabGC = newGC;

  gcValues.foreground = bgPtr->tickColorPtr->pixel;
  newGC = Tk_GetGC(bgPtr->tkwin, GCForeground, &gcValues);
  if (bgPtr->tickGC != None) {
    Tk_FreeGC(bgPtr->display, bgPtr->tickGC);
  }
  bgPtr->tickGC = newGC;

  /* We draw the wings by xor'ing the stored value with the background.
   * To get the desired color value drawn, we have to store the xor'd value
   * here.
   */
  gcValues.foreground = bgPtr->wingColorPtr->pixel;
  gcValues.foreground ^= Tk_3DBorderColor(bgPtr->border)->pixel;
  gcValues.function = GXxor;
  gcValues.line_width = bgPtr->wingWidth;
  gcValues.cap_style = CapButt;
  gcValues.join_style = JoinMiter;
  newGC = Tk_GetGC(bgPtr->tkwin, GCLineWidth | GCCapStyle | GCJoinStyle |
                                GCFunction | GCForeground, &gcValues);
  if (bgPtr->wingGC != None) {
    Tk_FreeGC(bgPtr->display, bgPtr->wingGC);
  }
  bgPtr->wingGC = newGC;
  /* A line of same color as wing is drawn over the value line.
   * It differs from the above wing because there is no xor, and its width is 1.
   */
  gcValues.foreground = bgPtr->wingColorPtr->pixel;
  gcValues.function = GXcopy;
  gcValues.line_width = 1;
  newGC = Tk_GetGC(bgPtr->tkwin, GCLineWidth | GCCapStyle | GCJoinStyle |
                                GCFunction | GCForeground, &gcValues);
  if (bgPtr->wingoverlayGC != None) {
    Tk_FreeGC(bgPtr->display, bgPtr->wingoverlayGC);
  }
  bgPtr->wingoverlayGC = newGC;

  /*
   * Recompute display-related information, and let the geometry
   * manager know how much space is needed now.
   */

  ComputeBargraphGeometry(bgPtr);

  EventuallyRedrawBargraph(bgPtr, DISPLAY_ALL | CLEAR_NEEDED);
  return TCL_OK;
}
