/**************************************************
 * SynthBuilder
 * Copyright 1993 Nick Porcaro All Rights Reserved
 **************************************************/

/*
 * NodeView.h
 * Eric Jordan, independent work, Spring, 1992
 */

#import <dpsclient/psops.h>
#import <dpsclient/wraps.h>
#import <stdlib.h>
#import <appkit/Panel.h>
#import "NodeView.h"
#import "FakeSynthPatch.h"
#import "FakePatchPoint.h"
#import "Controller.h"

@implementation NodeView

+ initialize
 /* Set the version. This can be used in a later version to distinguish older
  * formats when unarchiving documents. 
  */
{
  [NodeView setVersion:2];
  return self;
}


-init
{
  [super init];
  redirectNextMouseUp = NO;
  return self;
}

-setPatch:aPatch
{
  thePatch = aPatch;
  return self;
}

- getPatch
{
  thePatch = [[Controller theController] theSP];
  return self;
}

-setTag:(int)newTag
{
  tag = newTag;
  return self;
}

-(int)getTag
{
  return tag;
}

- (BOOL) isAnOutput
{
  id aFakeUG;
  aFakeUG = [self superview];

  if ([aFakeUG isMethodAnOutput:tag])
    {	
      return YES;
    }
  else
    {	
      return NO;
    }
}


-(NXRect)frame
{
  return frame;
}

-(BOOL)acceptsFirstMouse
{
  return YES;
}

-drawSelf:(const NXRect *)rects :(int)rectCount
{
/*
  NXRect *rect = (NXRect *)NXZoneMalloc([self zone], sizeof (*rect));
  rect->origin.x = frame.origin.x;
  rect->origin.y = frame.origin.y;
  rect->size.width = frame.size.width;
  rect->size.height = frame.size.height;
  [self convertRectFromSuperview:rect];
  PSsetgray(NX_BLACK);
  NXRectFill(rect);
  NXPing();
*/
  return self;
}

-mouseDown:(NXEvent *)theEvent
{
  [self getPatch];
  redirectNextMouseUp = YES;
  [window addToEventMask:NX_LMOUSEDRAGGEDMASK];
  [thePatch setFrom:self];
  return self;
}

-mouseDragged:(NXEvent *)theEvent
{
  NXPoint otherEndPoint;
  NXPoint thisEndPoint;

  [self getPatch];

  [[superview superview] lockFocus];
  otherEndPoint.x = frame.origin.x+frame.size.width/2;
  otherEndPoint.y = frame.origin.y+frame.size.height/2;
  [[superview superview] convertPoint:&otherEndPoint fromView:superview];
  thisEndPoint = theEvent->location;
  [[superview superview] convertPoint:&thisEndPoint fromView:nil];
  PSnewinstance();
  PSsetinstance(YES);
  PSmoveto(thisEndPoint.x, thisEndPoint.y);
  PSlineto(otherEndPoint.x, otherEndPoint.y);
  if ([thePatch getXMemory])
    PSsetgray(NX_DKGRAY);
  else
    PSsetgray(NX_BLACK);
  PSsetlinewidth(LINEWIDTH);
  PSstroke();
  PSsetinstance(NO);
  [[superview superview] unlockFocus];
  [window flushWindow];
  NXPing();
  return self;
}

-mouseUp:(NXEvent *)theEvent
{
  [self getPatch];

  if (redirectNextMouseUp)
    {
      id ReturnValue;
      NXPoint location = theEvent->location;
      [[superview superview] lockFocus];
      PSnewinstance();
      [[superview superview] unlockFocus];
      redirectNextMouseUp = NO;
      ReturnValue=[[[superview superview] hitTest:&location] mouseUp:theEvent];
      [thePatch setFrom:nil];
      [window removeFromEventMask:NX_LMOUSEDRAGGEDMASK];
      return ReturnValue;
    }
  [thePatch connect:self];
  return self;
}

-write:(NXTypedStream *) stream
{
  [super write:stream];
  NXWriteTypes(stream, "ic@", &tag, &redirectNextMouseUp);
  return self;
}

-read:(NXTypedStream *) stream
{
  int version;
  [super read:stream];

  version = NXTypedStreamClassVersion(stream, "NodeView");
  switch (version)
    {
      case(2):
	{
	  NXReadTypes(stream, "ic@", &tag, &redirectNextMouseUp);
	  break;
	}
      default:
        {
	  /* Older versions */
	  NXReadTypes(stream, "ic", &tag, &redirectNextMouseUp);
	}
    }

  return self;
}

@end
