#import "Image.h"
#import <stdio.h>
#import <stdlib.h>
#import <strings.h>
#import <libc.h>
#import <zone.h>
#import <mach.h>
#import <streams/streams.h>
#import <sys/file.h>
#import <appkit/Application.h>
#import <appkit/SavePanel.h>
#import <appkit/PopUpList.h>
#import <appkit/Control.h>
#import <appkit/Matrix.h>
#import <appkit/nextstd.h>
#import <appkit/NXBitmapImageRep.h>
#import <appkit/Window.h>
#import <appkit/Panel.h>
#import <appkit/Pasteboard.h>
#import <appkit/graphics.h>
#import <appkit/tiff.h>


// Image.m 
// 
// Written by Vince DeMarco 
// 	demarco@cpsc.ucalgary.ca
//
// This program is In the Public Domain. If you make any improvements to this
// program please let me know
// 

#define XOFFSET 5.0     // Offset of subsequent windows
#define YOFFSET -20.0

@implementation Image:View

- init
{
    const char *validSendTypes[2];
    
    validSendTypes[0] = NXTIFFPboardType;
    validSendTypes[1] = NULL;
    self = [super init];
    savePanelAccessoryWindow = [NXApp loadNibSection:"savepanel.nib" owner:self];
    newZone = NXCreateZone(vm_page_size,vm_page_size,NO);
    compressionType = NX_TIFF_COMPRESSION_NONE;
    saveType = 1;
    numColors = 3;
    return(self);
}

- displayImage
{

    unsigned char *planes[4];

    NXSetRect(&temprect, 150.0, (800.0 - (double)ysize),(double)xsize, (double)ysize);

    thiswindow = [[Window allocFromZone:newZone]
		  initContent:&temprect
		  style:NX_TITLEDSTYLE
		  backing:NX_RETAINED
		  buttonMask:NX_CLOSEBUTTONMASK | NX_MINIATURIZEBUTTONMASK | NX_RESIZEBUTTONMASK
		  defer:NO];

    [thiswindow setDelegate:self];
    [thiswindow setFreeWhenClosed:YES];
    [thiswindow setTitleAsFilename:fileName];
    if (windowIconName[0]){
	[thiswindow setMiniwindowIcon:(const char *)windowIconName];
    }

    [thiswindow makeKeyAndOrderFront:nil];
    [thiswindow display];
    NXPing();

    if (r == NULL){     // Check if there is anything to display if there isn't
	return self;    // just return
    }

    planes[0] = r;
    planes[1] = g;
    planes[2] = b;
    planes[3] = a;

    tiffimage = [[NXBitmapImageRep allocFromZone:newZone]
		     initDataPlanes:  planes
		     pixelsWide:      xsize
		     pixelsHigh:      ysize
		     bitsPerSample:   8
		     samplesPerPixel: (numColors == 1 ? 3  : numColors)
		     hasAlpha:        (numColors == 4 ? YES: NO )
		     isPlanar:        YES
		     colorSpace:      NX_RGBColorSpace
		     bytesPerRow:     xsize*8
		     bitsPerPixel:    8];

    [thiswindow setContentView:self];
    [thiswindow display];
    return(self);
}

- drawSelf:(const NXRect *)rects :(int)rectCount
{
    [self getFrame:&temprect];
    temprect.origin.x = 0.0;
    temprect.origin.y = 0.0;

    [self lockFocus];
    [tiffimage drawIn:&temprect];
    [self unlockFocus];
    return self;
}

- free
{
    NX_FREE(a);
    NX_FREE(r);
    NX_FREE(g);
    NX_FREE(b);
    [super free];
    return(self);
}

- saveAsTiff:(const char *)filename usingCompression:(int)compression
{
    int fd;
    NXStream *stream;

    if ( (fd = open(filename,(O_RDWR|O_CREAT),0600)) < 0){
	return(self);
    }
    stream = NXOpenFile(fd,NX_READWRITE);
    [tiffimage writeTIFF:stream usingCompression:compression];
    NXClose(stream);
    close(fd);
    return(self);
}

- saveAsEPS:(const char *)filename
{
    int fd;
    NXStream *stream;

    if ( (fd = open(filename,(O_RDWR|O_CREAT),0600)) < 0){
	return(self);
    }
    stream = NXOpenFile(fd,NX_READWRITE);
    [self copyPSCodeInside:&temprect to:stream];
    NXClose(stream);
    close(fd);
    return(self);
}

// window Delegation methods
- windowWillClose:sender
{
    NX_FREE(a); // Free the alpha,red,green, and blue buffers
    NX_FREE(r);
    NX_FREE(g);
    NX_FREE(b);
    return(self);
}

- print:sender
{
    [self printPSCode:sender];
    return(self);
}

- save:sender
{
    savepanel = [SavePanel new];
    [savepanel setAccessoryView:savePanelAccessory];

    if (saveType == 1){
	[savepanel setRequiredFileType:"tiff"];
	[savepanel setTitle:"Save To TIFF"];
	[compPopUP setEnabled:YES];
    }else{
	[savepanel setRequiredFileType:"eps"]; 
	[savepanel setTitle:"Save To EPS"];
	[compPopUP setEnabled:NO];
    }

    if ([savepanel runModal]){
	if (saveType == 1){
	    [self saveAsTiff:[savepanel filename] usingCompression:compressionType];
	}else{
	    [self saveAsEPS:[savepanel filename]];		
	}
    }
    return(self);
}

- saveType:sender
{
    switch ([sender selectedCol]){
    case 0:
	[savepanel setRequiredFileType:"tiff"]; 
	[savepanel setTitle:"Save To TIFF"];
	[compPopUP setEnabled:YES];
	saveType = 1;
	break;
    case 1:
	[savepanel setRequiredFileType:"eps"]; 
	[savepanel setTitle:"Save To EPS"];
	[compPopUP setEnabled:NO];
	saveType = 2;
	break;
    }
    return(self);
}

- compType:sender
{
    const char *selected_Cell = [[sender selectedCell] title];

    switch(selected_Cell[0]){
	case 'L' :
	    compressionType = NX_TIFF_COMPRESSION_LZW;
	    break;
	case 'P' :
	    compressionType = NX_TIFF_COMPRESSION_PACKBITS;
	    break;
	case 'J' :
	    compressionType = NX_TIFF_COMPRESSION_JPEG;
	    break;
	case 'N' :
	    compressionType = NX_TIFF_COMPRESSION_NONE;
	    break;
    }
    return self;
}

- copy:sender
{
    NXStream *stream;
    int length,maxlen;
    char *data;
    const char *types[3];

    types[0] = NXTIFFPboardType;
    stream = NXOpenMemory(NULL,0,NX_WRITEONLY);
    [tiffimage writeTIFF:stream];
    NXGetMemoryBuffer(stream,&data,&length,&maxlen);
    [[Pasteboard new] declareTypes:types num:1 owner:[self class]];
    [[Pasteboard new] writeType:NXTIFFPboardType data:data length:length];
    NXCloseMemory(stream, NX_FREEBUFFER);
    return self;
}
@end
