
/* TODO:
   make drawing to TessView be done to an NXimage and define new drawSelf: method
*/

/* Generated by Interface Builder */

#import "TessSketch.h"
#import "aGroup-inter.h"
#import "Underlay.h"
#import "SketchPad.h"

const char *const types[3] = { "tiff","eps",NULL};

@implementation TessSketch
- initFrame: (const NXRect *) theframe
{
  [super initFrame: theframe];
  mode = TIFF_MODE;
  fprintf(stderr,"TessSketch: new\n");
  [self initGroups];
  underlay = [ Underlay new ]; 
  [self addSubview: underlay];
  [underlay  initFrame: &frame];
  [underlay setAutosizing: NX_WIDTHSIZABLE | NX_HEIGHTSIZABLE];
  sketchView = [ SketchPad new ];
  /*   [sketchView initFrame: &frame]; */
  generator = [GeneratorOverlay new];
  [generator init];
  [generator setUnderlay: underlay];
  [self addSubview: generator : NX_ABOVE relativeTo: underlay];

  [self useGroup: P1];
  return self;
}  

-init
{
#ifdef DEBUG
  fprintf(stderr,"INit\n");
#endif
  return self;
}

- currentGroup
{
  return currentGroup;
}

- initGroups
{
/*   int i; */
  [aGroup setup];
/*  for(i=P1;i<P6M;i++)
    grouplist[i] = [GroupClasses[i] new];
*/
  grouplist[P1] = [[p1 new] init];
  grouplist[P2] = [[p2 new] init ];
  grouplist[PM] = [[pm new] init ];
  grouplist[PG] = [[pg new] init ];
  grouplist[CM] = [[cm new] init ];
  grouplist[PMM] = [[pmm new] init ];
  grouplist[PMG] = [[pmg new] init ];
  grouplist[PGG] = [[pgg new] init ];
  grouplist[CMM] = [[cmm new] init ];
  grouplist[P4] = [[p4 new] init ];
  grouplist[P4M] = [[p4m new] init ];
  grouplist[P4G] = [[p4g new] init ];
  grouplist[P3] = [[p3 new] init ];
  grouplist[P3M1] = [[p3m1 new] init ];
  grouplist[P31M] = [[p31m new] init ];
  grouplist[P6] = [[p6 new] init ];
  grouplist[P6M] = [[p6m new] init ];
  return self;
}

- getOutputView
{
  return outputView;
}

- doPaste:sender
{
  if (mode != TIFF_MODE)
    [self switchToTiffMode];
  return self;
}

- switchToTiffMode
/* This sets up tiff mode which allows only translating
   the image over the generator */
{
  /* set up subviews */
  //[sketchView removeFromSuperview];
  responder = generator;
//  [self addSubview: generator : NX_ABOVE relativeTo: underlay];
  [generator setupGenerator: currentGroup];
  return self;
}

- setupOutputView
{
  NXRect afrm;
  id pahoehoe;

  [outputView getFrame: &afrm];
  pahoehoe = [[NXImage alloc] initSize: &afrm.size];
  if(![pahoehoe useCacheWithDepth: NX_DefaultDepth]) 
    fprintf(stderr,"Can't create cached image\n");
  if([pahoehoe lockFocus]){
    [outputView display];
    [pahoehoe unlockFocus];
    [outputView setImage: pahoehoe];
  } else {
    fprintf(stderr,"Could not lock init outView image\n");
  }
  return self;
}

- copy:sender
{
    return self;
}

- printPSCode: sender
{
  [outputView printPSCode: self];
  return self;
}

- tesselate:sender
{
  id img;
  NXRect fr;
  if(![outputView getImage])
    [self setupOutputView];
  img = [outputView getImage];
#ifdef DEBUG
  if([img lockFocus]){
    fprintf(stderr,"Locked on outImg\n");
    [img unlockFocus];
  } else
    fprintf(stderr,"Couldn't lock on outImg\n");
#endif
  [outputView getFrame: &fr];
  [img setSize: &(fr.size)];
#ifdef DEBUG
  if([img lockFocus]){
    fprintf(stderr,"Locked on outImg after setsiz\n");
    [img unlockFocus];
  } else
    fprintf(stderr,"Couldn't lock on outImg after setsiz\n");
#endif
  [currentGroup performTesselation: self];
  [outputView display];
  return self;
}

- toolResponse:sender
{
    return self;
}

- clearPad:sender
{
  NXRect fr;

  [generator getFrame: &fr];
  [scratchPad lockFocus];
  [currentGroup makeLatticeUnitAt: &(fr.origin) fromImage:  [underlay getImage]];
  [scratchPad unlockFocus];

  [outputView lockFocus];
  [scratchPad composite: NX_COPY toPoint: &(bounds.origin)];
  [outputView unlockFocus]; 

  [outputView display];
  return self;
}

- setGroup:sender
{
  [self useGroup: [[sender selectedCell] tag]];
  return self;
}

- drawImage
{
  /* underlay locks focus and calls this method */
  /* I am supposed to draw a picture here */
  PSmoveto(0.0,0.0);
  PSlineto(300.0,300.0);
  PSsetlinewidth(4.0);
  PSstroke();
  return self;
}

- useGroup: (int) idnum
{
#ifdef DEBUG
  fprintf(stderr,"Changing to group %d\n",idnum);
#endif
  currentGroup = grouplist[idnum];
  [generator setupGenerator: currentGroup];
  if (mode == SKETCH_MODE)
    [underlay setImage: currentGroup];
  [self display];
  return self;
}

- loadTiff:sender
/* load a tiff image into the underlay */
{
  NXSize asize;
  const char *const *filenames;
  static char fn[1024];
  if(opener == nil)
    opener = [OpenPanel new];
  [opener allowMultipleFiles: NO];
/*  [underlay clear]; */
  [self switchToTiffMode];
  [opener runModalForDirectory: "/LocalLibrary/Images" file: "" types: types];
  filenames = [opener filenames];
  if(filenames && *filenames){
    sprintf(fn,"%s/%s",[opener directory],*filenames);
#ifdef DEBUG
    fprintf(stderr,"Filename %s\n",fn);
#endif
    [underlay setImageFromFile: fn];
  }
  else {
    [underlay setImageFromFile: "audrey5.tiff"];
  }
#ifdef DEBUG
  fprintf(stderr,"Finishing loadTiff:\n");
#endif
  [mywin close];
  [[underlay getImage] getSize: &asize];
  [mywin sizeWindow: asize.width:asize.height];
  [underlay sizeTo: asize.width:asize.height];
  [self sizeTo:asize.width:asize.height];
  [self display];
  [mywin makeKeyAndOrderFront: self];
  return self;
}

- saveSettings:sender
{
  char *fn;
  NXStream *st;
  if(!saver)
    saver = [SavePanel new];
  [saver setRequiredFileType: "tiff"];
  [saver runModal];
  if(fn = [saver filename]){
#ifdef DEBUG
    fprintf(stderr,"Opening %s\n",fn);
#endif
    if(st = NXOpenMemory(NULL,0,NX_WRITEONLY)){
      [[outputView getImage] writeTIFF: st]; 
      NXSaveToFile(st,fn);
      NXCloseMemory(st,NX_FREEBUFFER);
    } else
      fprintf(stderr,"Couldn't open file %s for writing!\n",fn);
  }
  return self;
}

- getImageView:(id *) iview withOffset: (NXPoint *) apoint
/* provide view & offset for compositing */
{
  if(mode == TIFF_MODE){
    *iview = underlay;
    [generator getGeneratorOffset: apoint];
  } else {
    *iview = sketchView;
    [currentGroup getGeneratorOffset: apoint];
  }
  return self;
}

-cut:sender { return self;};
- windowDidResize: sender
{
  [self tesselate: self];
  [sender display];
  return self;
}
- awin { return anglewin; };
- a1box { return angle1box; };
- a2box { return angle2box; };
- a1slide { return angle1slide; };
- a2slide { return angle2slide; };

@end

