
#import "FtpBrowserCell.h"
#import "FtpFile.h"
#import "FtpDirectory.h"
#import "NXmystd.h"

#define IMAGEMARGIN 0.0
#define FILESIZEWIDTH 32.0

#undef LEFT // filesize in the right

static NXAtom convertSize(long lsize)
{
	char buf[1000];
	char letter;
	double size = lsize;
	if (lsize == -1)
		return NXUniqueString("???");
	#if 0  // too big for 32bit :(
	else if (size > 900e9) // Tera :)
	{
		size = size / (1024L*1024*1024*1024);
		letter = 'T';
	}
	#endif
	else if (size > 900e6)
	{
		size = size / (1024*1024*1024);
		letter = 'G';
	}
	else if (size > 900e3)
	{
		size = size / (1024*1024);
		letter = 'M';
	}
	else // if (size > 900)
	{
		size = size / 1024;
		letter = 'K';
	}
	/*
	else
	{
		letter = 0x80;
	}
	*/
	//if (size < 1)
	//	size = 1;
	sprintf(buf,"%0f",size);
	buf[3] = letter;
	buf[4] = '\0';
	//fprintf(stderr,"%f = %s\n",size,buf);
	
	if (buf[2] == '0')
	{
		if (buf[1] == '0')
		{
			if (buf[0] == '.')
			{
				buf[0] = '0';
				buf[1] = letter;
				buf[2] = '\0';
			}
		}
		else if (buf[1] == '.')
		{
			buf[1] = letter;
			buf[2] = '\0';
		}
		else if (buf[0] == '.')
		{
			buf[2] = letter;
			buf[3] = '\0';
		}			
	}
	else if (buf[2] == '.')
	{
		buf[2] = letter;
		buf[3] = '\0';
	}
	return NXUniqueString(buf);
}


@implementation FtpBrowserCell

- initTextCell:(const char *)aString;
{
	needsUpdate = NO;
	parentNeedsUpdate = NO;
	isNew = NO;
	myFile = nil;
	return [super initTextCell:aString];
}

- setFile:aFile;
{
	myFile = aFile;
	return self;
}

- file;
{
	return myFile;
}

- setFileSize:(long) size;
{
	filesize = convertSize(size);
	return self;
}

- setParentNeedsUpdate:(BOOL) flag;
{
	parentNeedsUpdate = flag;
	return self;
}

- (BOOL) parentNeedsUpdate;
{
	return parentNeedsUpdate;
}

- setNeedsCheck:(BOOL) flag;
{
	needsCheck = flag;
	return self;
}

- (BOOL) needsCheck;
{
	return needsCheck;
}

- setNeedsUpdate:(BOOL) flag;
{
	needsUpdate = flag;
	return self;
}

- (BOOL) needsUpdate;
{
	return needsUpdate;
}

- setNeedsFirstUpdate:(BOOL) flag;
{
	needsFirstUpdate = flag;
	return self;
}

- (BOOL) needsFirstUpdate;
{
	return needsFirstUpdate;
}

- setNew:(BOOL)flag;
{
	isNew = flag;
	return self;
}

- (BOOL) isNew;
{
	return isNew;
}

- drawInside:(const NXRect *)cellFrame inView:controlView;
{
    /* every CustomCell needs these */
    static id knobImage = nil;
    static id arrowImage = nil;
    static id doubleArrowImage = nil;
    static id newImage = nil;
    static id dimpleImage = nil;
    static id sharedTextCell = nil;
    static id sharedFixedFont = nil;
	static int sharedfilesizewidth = 0;
	id theImage = nil;

    NXRect rect = *cellFrame;
	NXRect filesizerect;
    NXPoint imageOrigin;
    NXSize imageSize;
        
    if (!knobImage) {
	knobImage = [NXImage findImageNamed:"knob_nib"];
    }
    if (!arrowImage) {
	arrowImage = [NXImage findImageNamed:"arrow"];
    }
    if (!doubleArrowImage) {
	doubleArrowImage = [NXImage findImageNamed:"DBDoubleArrow"];
    }
    if (!newImage) {
	newImage = [NXImage findImageNamed:"connectIcon_nib"];
    }
    if (!dimpleImage) {
	dimpleImage = [NXImage findImageNamed:"dimple_nib"];
    }
	
	if ([myFile transferStatus] && ([myFile isFile] || [myFile shouldTransferIfNeeded]))
	{
		theImage = knobImage;
	}
	else if ([self isNew])
	{
		theImage = dimpleImage;
	}
	[knobImage getSize:&imageSize];

  /* erase the cell */
    PSsetgray((cFlags1.state || cFlags1.highlighted) ? NX_WHITE : NX_LTGRAY);
    NXRectFill(cellFrame);

  /* draw the left image */
    imageOrigin.x = NX_X(cellFrame) + IMAGEMARGIN;
    imageOrigin.y = NX_Y(cellFrame) + NX_HEIGHT(cellFrame) -
    		    (NX_HEIGHT(cellFrame) - imageSize.height) / 2.0;

    [theImage composite:NX_SOVER toPoint:&imageOrigin];
      
    NX_WIDTH(&rect) -= (imageSize.width + IMAGEMARGIN * 2.0);// - NX_X(&rect));
    NX_X(&rect) += imageSize.width; // + IMAGEMARGIN * 2.0;

  /* draw the right image */
	if (![self isLeaf])
	{
		if ([self needsFirstUpdate])
			theImage = newImage;
		else if ([self needsUpdate])
			theImage = doubleArrowImage;
		else if ([self needsCheck])
			theImage = doubleArrowImage;
		else
			theImage = arrowImage;
			
		[theImage getSize:&imageSize];
		
		imageOrigin.x = NX_X(cellFrame) + NX_WIDTH(cellFrame) - IMAGEMARGIN - imageSize.width;
		imageOrigin.y = NX_Y(cellFrame) + NX_HEIGHT(cellFrame) -
					(NX_HEIGHT(cellFrame) - imageSize.height) / 2.0;
	
		[theImage composite:NX_SOVER toPoint:&imageOrigin];
			
		NX_WIDTH(&rect) -= (imageSize.width + IMAGEMARGIN * 2.0);// - NX_X(&rect));
	}
	
    if (!sharedTextCell) {
        sharedTextCell = [[Cell alloc] init];
		[sharedTextCell setWrap:NO];
    }
    if (!sharedFixedFont) {
        sharedFixedFont = [Font newFont:"Ohlfs" size:10 matrix:NX_FLIPPEDMATRIX];
    }
    /*if (0 == sharedfilesizewidth) {
        sharedfilesizewidth = [sharedFixedFont getWidthOf:"XXXX"];
    }*/


	if ([myFile isFile]&&![myFile isDummy])
	{
		static NXSize minSize;
		[sharedTextCell setStringValue:filesize];
		[sharedTextCell setAlignment:NX_RIGHTALIGNED];
		[sharedTextCell setFont:sharedFixedFont];
    	[sharedTextCell setEnabled:NO];
		[sharedTextCell calcCellSize:&minSize];
		sharedfilesizewidth = minSize.width;
		NX_WIDTH(&filesizerect) = sharedfilesizewidth;
		NX_HEIGHT(&filesizerect) = NX_HEIGHT(&rect);
		#ifdef LEFT
		NX_X(&filesizerect) = NX_X(&rect);
		#else
		NX_X(&filesizerect) = NX_MAXX(&rect) - NX_WIDTH(&filesizerect);
		#endif
		NX_Y(&filesizerect) = NX_Y(&rect)+2;
		[sharedTextCell drawInside:&filesizerect inView:controlView];
		if (!strchr(filesize,'K'))
		{
			NX_X(&filesizerect)--;
			[sharedTextCell drawInside:&filesizerect inView:controlView];
		}
		#ifndef LEFT
		NX_WIDTH(&rect) -= sharedfilesizewidth;
		#endif
    }
	#ifdef LEFT
	NX_X(&rect) += sharedfilesizewidth;
	NX_WIDTH(&rect) -= sharedfilesizewidth;
	#endif
    [sharedTextCell setStringValue:[self stringValue]];
	[sharedTextCell setAlignment:NX_LEFTALIGNED];
	//[sharedTextCell setFont:[Font userFontOfSize:10 matrix:NX_FLIPPEDMATRIX]];
    [sharedTextCell setFont:[self font]];
    [sharedTextCell setEnabled:[self isEnabled]];
    [sharedTextCell drawInside:&rect inView:controlView];

	
  /* all drawing from now on will be in dark gray */
    PSsetgray(NX_DKGRAY);
    
  /* draw the two dark gray lines above and below the cell */
    if (cFlags1.state || cFlags1.highlighted) {
        NXRect rectArray[2];
      /*
       * draw 1-pixel tall rectangles instead of lines (this is faster than
       * PSmoveto(); PSlineto()).
       */
	NXSetRect(&(rectArray[0]), NX_X(cellFrame), NX_Y(cellFrame),
		NX_WIDTH(cellFrame), 1.0);
	NXSetRect(&(rectArray[1]), NX_X(cellFrame), NX_MAXY(cellFrame) - 1.0,
		NX_WIDTH(cellFrame), 1.0);

      /* using NXRectFillList is faster than separate calls to NXRectFill */
	NXRectFillList(rectArray, 2);
    }

    return self;
}

- highlight:(const NXRect *)cellFrame inView:controlView lit:(BOOL)flag
{
    if (cFlags1.highlighted != flag) {
	cFlags1.highlighted = flag;
	[self drawInside:cellFrame inView:controlView];
    }
    return self;
}

@end
