/*
 * Copyright (c) 1992, The Geometry Center
 *                     University of Minnesota 
 *                     1300 South Second Street
 *                     Minneapolis, MN  55454
 *
 * email address: software@geom.umn.edu
 *
 * This software is copyrighted as noted above.  It may be freely copied,
 * modified, and redistributed, provided that the copyright notice is
 * preserved on all copies.
 *
 * There is no warranty or other guarantee of fitness for this software,
 * it is provided solely "as is".  Bug reports or fixes may be sent
 * to the authors, who may or may not act on them as they desire.
 *
 * You may not include this software in a program or other software product
 * without supplying the source, or without informing the end-user that the
 * source is available for no extra charge.
 *
 * If you modify this software, you should include a notice giving the
 * name of the person performing the modification, the date of modification,
 * and the reason for such modification.
 *
 *     The National Science and Technology Research Center for
 *      Computation and Visualization of Geometric Structures
 */

/* Generated by Interface Builder */

#import <appkit/defaults.h>
#include <stdlib.h>
#import <zone.h>
#import <mach.h>
#include <string.h>
#import "PrefObj.h"
#import <appkit/Panel.h>
#import <appkit/Slider.h>
#import <appkit/Text.h>
#import <appkit/Matrix.h>
#import <appkit/Application.h>
#import <appkit/Button.h>
#import <appkit/NXColorWell.h>

void makeEntry (struct _NXDefault *entry, char *name, char *value)
{
  entry->name = name;
  entry->value = value;
}

char *makeString(float num, NXZone *zone)
{
  char *s = NXZoneMalloc(zone, 100);
  sprintf(s, "%f", num);
  s = NXZoneRealloc(zone, s, strlen(s)+1);
  return s;
}

char *makeCString(NXColor col, NXZone *zone)
{
  float r,g,b;
  char *s = NXZoneMalloc(zone, 100);

  NXConvertColorToRGB(col, &r, &g, &b);
  sprintf(s, "%f %f %f", r, g, b);
  s = NXZoneRealloc(zone, s, strlen(s)+1);
  return s;
}

NXColor makeColor(const char *colst)
{
  float r,g,b;
  sscanf(colst, "%f %f %f", &r, &g, &b);
  return NXConvertRGBToColor(r, g, b);
}

@implementation PrefObj

- init
{
  static NXDefaultsVector defaults =
    {
      {"amp", "11.1903"},
      {"ampB", "1"},
      {"fffa", "0.25"},
      {"fffb", "0.25"},
      {"ppc", "72.295"},
      {"segMax", "250"},
      {"segScale", "30"},
      {"sep", "0.0958"},
      {"texture", "1"},
      {"redraw", "0"},
      {"rulers", "0"},
      {"arrows", "1"},
      {"axes", "1"},
      {"vertices", "1"},
      {"anchorPoints", "1"},
      {"sparse", "10"},	
      {"segmentSounds", "1"},
      {"obnoxiousSounds", "0"},
      {"color0", "1 0 0"},
      {"color1", "0 1 0"},
      {"color2", "0 0 1"},
      {"color3", "0 1 1"},
      {"color4", "1 0 1"},
      {"color5", "1 1 0"},
      {NULL},
    };
  static char *stringname = "Linktool Geometry Center David Broman";
  mode = EDS;
  owner = stringname;
  origDefaults = defaults;
  NXRegisterDefaults(owner, defaults);
  return self;
}

- setDefaults:sender
{
  [self readPanel];      /* Read settings into register & database */
  return self;
}

- revertDefaults:sender
{
  /* Revert panel back to original defaults */
  [self writePanel:[self prepareValsFromOriginal]];
  [prefPanel display];
  return self;
}

- revertCurrent:sender
{
  /* Revert panel back to current defaults */
  [self writePanel:[self prepareValsFromCurrent]];
  [prefPanel display];
  return self;
}

- showPanel:sender
{
  /* Load panel if necessary */
  if (prefPanel == NULL)
    [NXApp loadNibSection:"Prefs.nib" owner:self
                withNames:NO fromZone:[self zone]];
  mode = ALL;
  [self writePanel:[self prepareValsFromCurrent]];
  mode = EDS;
  [modeB setTitle:"Editor settings"];
  [prefView setContentView:eSettingsView];
  [prefPanel makeKeyAndOrderFront:self];
  [prefPanel flushWindow];
  [prefPanel display];
  return self;
}

/* Put panel settings into register table & database */
- readPanel
{
  static struct _NXDefault newVals[NUM_SETTINGS+1];
  NXZone *zone = [self zone];
  switch(mode)
    {
    case TES:
      makeEntry(&newVals[0], "amp", makeString([ampSlider floatValue], zone));
      makeEntry(&newVals[1], "ampB", makeString([ampBSlider floatValue], zone));
      makeEntry(&newVals[2], "ppc" , makeString([ppcSlider floatValue], zone));
      makeEntry(&newVals[3], "texture" ,
		makeString((float) [[textureRB selectedCell] tag], zone));
      makeEntry(&newVals[4], "redraw" ,
		makeString((float) [[redrawRB selectedCell] tag], zone));
      makeEntry(&newVals[5], NULL, NULL);
      break;
    case SPS:
      makeEntry(&newVals[0], "fffa" , makeString([fffaSlider floatValue], zone));
      makeEntry(&newVals[1], "fffb" , makeString([fffbSlider floatValue], zone));
      makeEntry(&newVals[2], "segMax" , makeString([segMaxSlider floatValue], zone));
      makeEntry(&newVals[3], "segScale", makeString([segScaleSlider floatValue], zone));
      makeEntry(&newVals[4], "sep" , makeString([sepSlider floatValue], zone));
      makeEntry(&newVals[5], NULL, NULL);
      break;
    case EDS:
      makeEntry(&newVals[0], "rulers" ,
		makeString((float) [rulersB state], zone));
      makeEntry(&newVals[1], "arrows" ,
		makeString((float) [arrowsB state], zone));
      makeEntry(&newVals[2], "axes" ,
		makeString((float) [axesB state], zone));
      makeEntry(&newVals[3], "vertices" ,
		makeString((float) [verticesB state], zone));
      makeEntry(&newVals[4], "anchorPoints" ,
		makeString((float) [anchorPointsB state], zone));
      makeEntry(&newVals[5], "sparse", makeString([sparseSlider floatValue], zone));
      makeEntry(&newVals[6], NULL, NULL);
      break;
    case SOS:
      makeEntry(&newVals[0], "segmentSounds",
		makeString((float) [[soundsB findCellWithTag:0] state], zone));
      makeEntry(&newVals[1], "obnoxiousSounds",
		makeString((float) [[soundsB findCellWithTag:1] state], zone));
      makeEntry(&newVals[2], NULL, NULL);
      break;
    case COS:
      makeEntry(&newVals[0], "color0", makeCString([color0 color], zone));
      makeEntry(&newVals[1], "color1", makeCString([color1 color], zone));
      makeEntry(&newVals[2], "color2", makeCString([color2 color], zone));
      makeEntry(&newVals[3], "color3", makeCString([color3 color], zone));
      makeEntry(&newVals[4], "color4", makeCString([color4 color], zone));
      makeEntry(&newVals[5], "color5", makeCString([color5 color], zone));
      makeEntry(&newVals[6], NULL, NULL);
      break;
    }
  NXWriteDefaults(owner, newVals);
  return self;
}

/* Writes the values stored in vals to the preference views */
- writePanel:(float *) vals
{
  if (mode == TES || mode == ALL)
    {
      [ampSlider setFloatValue:vals[0]];
      [ampText setFloatValue:  vals[0]];
      [ampBSlider setFloatValue:vals[1]];
      [ampBText setFloatValue:  vals[1]];
      [ppcSlider setFloatValue:  vals[4]];
      [ppcText setFloatValue:  vals[4]];
      [textureRB selectCellWithTag:  (int) vals[8]];
      [redrawRB selectCellWithTag:(int) vals[9]];
    }
  if (mode == SPS || mode == ALL)
    {
      [fffaSlider setFloatValue:  vals[2]];
      [fffaText setFloatValue:  vals[2]];
      [fffbSlider setFloatValue:  vals[3]];
      [fffbText setFloatValue:  vals[3]];
      [segMaxSlider setFloatValue:  vals[5]];
      [segMaxText setFloatValue:  vals[5]];
      [segScaleSlider setFloatValue:  vals[6]];
      [segScaleText setFloatValue:vals[6]];
      [sepSlider setFloatValue:  vals[7]];
      [sepText setFloatValue:vals[7]];
    }
  if (mode == EDS || mode == ALL)
    {
      [rulersB setState:(int)vals[10]];
      [arrowsB setState:(int)vals[11]];
      [axesB setState:(int)vals[12]];
      [verticesB setState:(int)vals[13]];
      [anchorPointsB setState:(int)vals[14]];
      [sparseSlider setFloatValue:  vals[15]];
      [sparseText setFloatValue:  vals[15]];
    }
  if (mode == SOS || mode == ALL)
    {
      [[soundsB findCellWithTag:0] setState:(int)vals[16]];
      [[soundsB findCellWithTag:1] setState:(int)vals[17]];
    }
  if (mode == COS || mode == ALL)
    {
      [color0 setColor:makeColor((const char *) ((int) vals[18]))];
      [color1 setColor:makeColor((const char *) ((int) vals[19]))];
      [color2 setColor:makeColor((const char *) ((int) vals[20]))];
      [color3 setColor:makeColor((const char *) ((int) vals[21]))];
      [color4 setColor:makeColor((const char *) ((int) vals[22]))];
      [color5 setColor:makeColor((const char *) ((int) vals[23]))];
    }
  return self;
}

- (float *) prepareValsFromOriginal
{
  static float vals[NUM_SETTINGS];
  int i;
  for (i=0; i<18; i++)
    vals[i] = atof(origDefaults[i].value);
  for (i=18; i<NUM_SETTINGS; i++)
    vals[i] = (float) ((int) origDefaults[i].value);
  return vals;
}

- (float *) prepareValsFromCurrent
{
  static float vals[NUM_SETTINGS];
  vals[0] = atof(NXGetDefaultValue(owner, "amp"));
  vals[1] = atof(NXGetDefaultValue(owner, "ampB"));
  vals[2] = atof(NXGetDefaultValue(owner, "fffa"));
  vals[3] = atof(NXGetDefaultValue(owner, "fffb"));
  vals[4] = atof(NXGetDefaultValue(owner, "ppc"));
  vals[5] = atof(NXGetDefaultValue(owner, "segMax"));
  vals[6] = atof(NXGetDefaultValue(owner, "segScale"));
  vals[7] = atof(NXGetDefaultValue(owner, "sep"));
  vals[8] = atof(NXGetDefaultValue(owner, "texture"));
  vals[9] = atof(NXGetDefaultValue(owner, "redraw"));
  vals[10] = atof(NXGetDefaultValue(owner, "rulers"));
  vals[11] = atof(NXGetDefaultValue(owner, "arrows"));
  vals[12] = atof(NXGetDefaultValue(owner, "axes"));
  vals[13] = atof(NXGetDefaultValue(owner, "vertices"));
  vals[14] = atof(NXGetDefaultValue(owner, "anchorPoints"));
  vals[15] = atof(NXGetDefaultValue(owner, "sparse"));
  vals[16] = atof(NXGetDefaultValue(owner, "segmentSounds"));
  vals[17] = atof(NXGetDefaultValue(owner, "obnoxiousSounds"));
  vals[18] = (float) ((int) NXGetDefaultValue(owner, "color0"));
  vals[19] = (float) ((int) NXGetDefaultValue(owner, "color1"));
  vals[20] = (float) ((int) NXGetDefaultValue(owner, "color2"));
  vals[21] = (float) ((int) NXGetDefaultValue(owner, "color3"));
  vals[22] = (float) ((int) NXGetDefaultValue(owner, "color4"));
  vals[23] = (float) ((int) NXGetDefaultValue(owner, "color5"));
  
  return vals;
}

/*** View manipulations ***/

- EditorS:sender
{
  mode = EDS;
  [modeB setTitle:"Editor settings"];
  [prefView setContentView:eSettingsView];
  [prefPanel display];
  return self;
}

- SoundsS:sender
{
  mode = SOS;
  [modeB setTitle:"Sounds"];
  [prefView setContentView:soundsView];
  [prefPanel display];
  return self;
}

- SpliningS:sender
{
  mode = SPS;
  [modeB setTitle:"Splining settings"];
  [prefView setContentView:spliningView];
  [prefPanel display];
  return self;
}

- TextureS:sender
{
  mode = TES;
  [modeB setTitle:"Texture settings"];
  [prefView setContentView:textureView];
  [prefPanel display];
  return self;
}

- ColorS:sender
{
  mode = COS;
  [modeB setTitle:"Colors"];
  [prefView setContentView:colorView];
  [prefPanel display];
  return self;
}

/*** Extractor methods for global settings ***/

- (NXColor *) get_colors
{
  static NXColor color[6];
  color[0] = makeColor(NXGetDefaultValue(owner, "color0"));
  color[1] = makeColor(NXGetDefaultValue(owner, "color1"));
  color[2] = makeColor(NXGetDefaultValue(owner, "color2"));
  color[3] = makeColor(NXGetDefaultValue(owner, "color3"));
  color[4] = makeColor(NXGetDefaultValue(owner, "color4"));
  color[5] = makeColor(NXGetDefaultValue(owner, "color5"));
  return color;
}

- (int) get_segmentSounds
{
  return atoi(NXGetDefaultValue(owner, "segmentSounds"));
}

- (int) get_obnoxiousSounds
{
  return atoi(NXGetDefaultValue(owner, "obnoxiousSounds"));
}

@end
