#import "CustomVideoView.h"
#import <dpsclient/event.h>
#import <appkit/Application.h>
#import <appkit/OpenPanel.h>
#import <appkit/NXImage.h>
#import <appkit/NXBitmapImageRep.h>
#import <appkit/Button.h>
#import <appkit/Control.h>
#import <appkit/SavePanel.h>
#import <appkit/tiff.h>
#import <dpsclient/psops.h>
#import <dpsclient/wraps.h>
#import <sys/param.h>
#import <stdio.h>
#import <strings.h>
#include <sys/time_stamp.h>
#include "libc.h"

#define MAXGRABS 100
#define MAXHEIGHT 200
#define MAXWIDTH 320


id myGrabImage[MAXGRABS];

@implementation CustomVideoView


- setVideoSize:sender {
	[msizeField setIntValue:(int) (frames*
	    myGrabSize.height*
	    myGrabSize.width*3/1000)];
	return self;
}

- setWidth:sender {
	myGrabSize.width=[sender intValue];
	[widthField setIntValue:myGrabSize.width];
	[self setVideoSize:self];
	return self;
}

- setHeight:sender {
	myGrabSize.height=[sender intValue];
	[heightField setIntValue:myGrabSize.height];
	[self setVideoSize:self];
	return self;
}

- setFrames:sender {
	frames=[sender intValue];
	[frameField setIntValue:frames];
	[self setVideoSize:self];
	return self;
}

- initFrame:(NXRect *)theFrame
{
  int i;
  
  [super initFrame:theFrame];


// Get it to allocate the NXImage ahead of time so it will stop fast.
  [self setGrabOnStop:YES];
  theMode = NX_FROMINPUT;
  actualSize = YES;

  frames=20;
  myGrabSize.width=120;
  myGrabSize.height=100;
[self setVideoSize:self];
  for(i=0;i<MAXGRABS;i++) {
  	myGrabImage[i]=nil;
  }
	
  theImage = [NXImage findImageNamed:"AppIcon"];
  [theImage setScalable:YES];
  [theImage getSize:&imageSize];
  imagePoint.x = bounds.origin.x + (bounds.size.width - imageSize.width)/2.0;
  imagePoint.y = bounds.origin.y + (bounds.size.height-imageSize.height)/2.0;
  changed = YES;
  return self;
}

- mouseDown:(NXEvent *)theEvent
{
  NXEvent anEvent = *theEvent;
  NXPoint point1 = theEvent->location,point2;
  int oldMask;
  BOOL dragged = NO;
  oldMask = [window addToEventMask:NX_LMOUSEDRAGGEDMASK];
  if(theMode==NX_FROMINPUT)
  {
    // Set Grab rectangle.
    while(anEvent.type!=NX_MOUSEUP)
    {
      NXGetOrPeekEvent(DPSGetCurrentContext(),
        &anEvent, NX_MOUSEUPMASK|NX_LMOUSEDRAGGEDMASK,NX_FOREVER,10,0);
      if(anEvent.type==NX_MOUSEDRAGGED)
      {
        dragged = YES;
        point2 = anEvent.location;
        if(point1.x<point2.x)
          {grabRect.origin.x=point1.x;grabRect.size.width=point2.x - point1.x;}
        else
          {grabRect.origin.x=point2.x;grabRect.size.width=point1.x - point2.x;}
        if(point1.y<point2.y)
        {
          grabRect.origin.y=point1.y;
	grabRect.size.height=point2.y - point1.y;
        }
        else
        {
          grabRect.origin.y=point2.y;
	grabRect.size.height=point1.y - point2.y;
        }
	
	if(grabRect.size.width>myGrabSize.width)
		grabRect.size.width=myGrabSize.width;
	if(grabRect.size.height>myGrabSize.height)
		grabRect.size.height=myGrabSize.height;
        [self display];
    
      }
    }
    if(!dragged) grabRect.size.width = 0;
    [self display];
  }
  else
  {
    float dx=0,dy=0;
//    if(actualSize)		// Move Image around
    {
      NXRect imageFrame,oldFrame;
      imageFrame.origin = imagePoint;imageFrame.size = imageSize;
      oldFrame = imageFrame;
      if(NXMouseInRect(&theEvent->location,&imageFrame,NO))
      {
        dx = theEvent->location.x - imagePoint.x;
        dy = theEvent->location.y - imagePoint.y;
        while(anEvent.type!=NX_MOUSEUP)
        {
          NXGetOrPeekEvent(DPSGetCurrentContext(),&anEvent,
	  NX_MOUSEUPMASK|NX_LMOUSEDRAGGEDMASK,NX_FOREVER,10,0);
          if(anEvent.type==NX_MOUSEDRAGGED)
          {
	  imagePoint.x = anEvent.location.x -dx;
	  imagePoint.y = anEvent.location.y -dy;
	  imageFrame.origin = imagePoint;
	  
	  NXUnionRect(&imageFrame,&oldFrame);
            [self display:&oldFrame :1];
          }
        }
      }
    }
  }
  [window setEventMask:oldMask];
  return self;
}

- grab:sender
{
  NXRect myGrabDest;
  int i,res;
  id mySavePanel = [SavePanel new];
  char filename[MAXPATHLEN+1];
  char dirname[MAXPATHLEN+1];
  char *cp;		
  
  	NXSetRect(&myGrabDest, 0.0, 0.0, myGrabSize.width,myGrabSize.height);
  	for(i=0;i<frames;i++) {
 		if(myGrabImage[i]!=nil)
			[myGrabImage[i] free];
  		myGrabImage[i]=[[NXImage alloc] initSize:
		    (NXSize *)&myGrabSize];
	}

	for(i=0;i<frames;i++) {
		[myGrabImage[i] setSize:&grabRect.size];
		[self grabIn:myGrabImage[i] 
		    fromRect:&grabRect toRect:&myGrabDest];
	}
					
    	res=[mySavePanel runModal];
	if(res==1) {
		sprintf(dirname,"%s.anim",[mySavePanel filename]);
      		mkdir(dirname,0777);
		cp=rindex(dirname,'.');
		*cp='\0';
		if((cp=rindex(dirname,'/'))==NULL)
			cp=dirname;
		else
			cp=cp+1;
	}	
	for(i=0;i<frames;i++) {

    		if((res==1)&&([mySavePanel filename])) {
      			NXStream *s=NXOpenMemory(NULL,0,NX_READWRITE);
      			cp=rindex(dirname,'/');
			cp=cp+1;
			sprintf(filename,"%s.anim/%s.%d.tiff",
			    dirname,cp,i+1);
			if (s) {
				[myGrabImage[i] writeTIFF:s];
				NXFlush (s);
				if (NXSaveToFile(s,filename))
					NXRunAlertPanel(
					    "Error Saving File",
					    "Filename: %s","OK",
					    NULL,NULL,filename);
				NXCloseMemory (s, NX_FREEBUFFER);
      			}
		}
		if(myGrabImage[i]!=nil) {
			[myGrabImage[i] free];
			myGrabImage[i]=nil;
		}
	}
  	return self;
}



- drawSelf:(const NXRect *)rects :(int)rectCount
{
  if(theMode==NX_FROMVIEW)
  {
    NXRectClip(rects);
    NXEraseRect(&rects[0]);
    if(!theImage) return self;
    if(actualSize)
    {
      if(changed) {[theImage setSize:&imageSize];changed = NO;}
      [theImage composite:NX_SOVER toPoint:&imagePoint];
    }
    else
    {
      if(changed) {[theImage setSize:&bounds.size];changed = NO;}
      [theImage composite:NX_SOVER toPoint:&bounds.origin];
    }
  }
  else
  {
   [super drawSelf:rects :rectCount];
   PSsetgray(NX_WHITE);
   PSsetalpha(1.0);
   if(grabRect.size.width!=0) NXFrameRect(&grabRect);
  }
  return self;
}


@end
