#import "ImageOpCtr.h"
#import "ImageOpr.h"
#import <appkit/Application.h>
#import <appkit/publicWraps.h>
#import <appkit/Control.h>
#import <appkit/Panel.h>
#import <appkit/MenuCell.h>
#import <appkit/PopUpList.h>
#import <appkit/TextField.h>
#import <objc/NXBundle.h>
#import <defaults/defaults.h>
#import <stdio.h>
#import <stdlib.h>
#import <string.h>
#import <streams/streams.h>
#import "TVController.h"
#import "ToyWin.h"
#import "ToyWinEPS.h"
#import "ToyView.h"
#import "common.h"
#import "getpixel.h"
#import "strfunc.h"
#import "ImageOpr.bproj/MonoCtr.h"

@implementation ImageOpCtr

/* Local Method */
- loadBundle
{
	char bdir[MAXFILENAMELEN];
	id bundle;
	int n;
	static id classImgOp = nil;

	if (classImgOp && imageOpr)
		return self;
	n = dircopy(bdir, NXArgv[0], YES);
	strcpy(&bdir[n], "ImageOpr.bundle");
	bundle = [[NXBundle alloc] initForDirectory: bdir];
	if (bundle == nil) /* ERROR */
		return nil;
	classImgOp = [bundle classNamed:"ImageOpr"];
	if (classImgOp == nil) /* ERROR */
		return nil;
	imageOpr = [[classImgOp alloc] init];
	return self;
}

/* Local Method */
- loadNib:(int)op
{
	int	tag = 0;
	id	cview = nil;
	static id currentView;

	if (monoPanel == nil) {
		[NXApp loadNibSection:"ImageOpr.nib" owner:self];
		currentView = nil;
	}
	if (op == NoOperation && currentView == nil)
		op = Monochrome;
	switch (op) {
	case NoOperation:
		cview = currentView;
		break;
	case Rotation:
		cview = [rotatePanel contentView];
		[angleText selectText:self];
		tag = 0;
		break;
	case Monochrome:
	case Gray2Bits:
	case BiLevel:
	case Brightness:
		cview = [monoPanel contentView];
		tag = 1;
		break;
	case ColorTone:
		cview = [clrTonePanel contentView];
		tag = 2;
		break;
	case Enhance:
	case Emboss:
		cview = [enhancePanel contentView];
		tag = 3;
		break;
	case ColorChange:
		cview = [clrChangePanel contentView];
		tag = 4;
		break;
	case RandomPttn:
		cview = [randomPanel contentView];
		tag = 5;
		break;
	case SoftFrame:
		cview = [sframePanel contentView];
		tag = 6;
		break;
	case Posterize:
		cview = [posterizePanel contentView];
		tag = 7;
		break;
	default:
		return self;
	}
	if (currentView != cview) {
		id tg;
		if (currentView == nil)
			[toolView addSubview:cview];
		else
			[toolView replaceSubview:currentView with:cview];
		currentView = cview;
		[cview windowChanged: toolPanel];
		tg = [[toolButton target] findCellWithTag:tag];
		[toolButton setTitleNoCopy: [tg title]];
		[toolPanel display];
	}
	[toolPanel makeKeyAndOrderFront: self];
	[toolPanel setFloatingPanel: YES];
	return self;
}

- loadNewTool: sender
{
	static unsigned char tab[] = {
		Rotation, Monochrome, ColorTone,
		Enhance, ColorChange, RandomPttn,
		SoftFrame, Posterize };
	return [self loadNib: tab[ [sender selectedTag] ]];
}

- forward:(SEL)aSelector :(marg_list)argFrame
{
	[self loadBundle];
	if ( [imageOpr respondsTo:aSelector] )
		return [imageOpr performv:aSelector :argFrame];
	[self doesNotRecognize:aSelector];
	return self;	/* never */
}


- activateToolPanel: sender
{
	static int ops[] = {
		NoOperation, Monochrome, ColorTone,
		Enhance, ColorChange, RandomPttn, SoftFrame, Posterize };
	int tag = [sender selectedTag];
	[self loadBundle];
	[self loadNib: ops[tag]];
	return self;
}

- rotate: sender
{
	static int tagAngles[] = { 0, 90, 270, 180 };
	int tag;

	[self loadBundle];
	tag = [sender selectedTag];
	if (tag == 0) {
		[self loadNib: Rotation];
		return self;
	}
	return [imageOpr doRotateFlipClip:Rotation to:tagAngles[tag]];
}

- rotateAngle: sender
{
	int angle = [angleText intValue];
	[angleText selectText:self];
	if (angle == 0) {
		NXBeep();
		return self;
	}else if (angle < 0)
		angle += 360;
	return [imageOpr doRotateFlipClip:Rotation to:angle];
}

- flip: sender
{
	static int flipkind[] = { Horizontal, Vertical, Clip, Negative };

	[self loadBundle];
	return [imageOpr doRotateFlipClip:
			flipkind[[sender selectedTag]] to:0];
}

- randomize: sender
{
	[imageOpr setRandom:[randomFreqSlider floatValue]
				:[randomMagSlider floatValue]];
	[imageOpr doRotateFlipClip:RandomPttn to:0];
	return self;
}

- newBitmap: sender
{
	[self loadBundle];
	[imageOpr newBitmap: sender];
	return self;
}

- EPSResize: sender
{
	[self loadBundle];
	[imageOpr EPSResize: sender];
	return self;
}

- reduce: sender
{
	[self loadBundle];
	[imageOpr reduceUsing: 0];
	return self;
}

- reduceSelect: sender
{
	[self loadBundle];
	[imageOpr reduceUsing: [sender selectedTag]];
	return self;
}

- cutDownBits: sender
{
	[self loadBundle];
	[imageOpr cutDownBitsTo: [sender selectedTag]];
	return self;
}

- colorHalftone: sender
{
	int n;
	static int cols[] = { 256, 64, 8 };

	[self loadBundle];
	n = [sender selectedTag];
	[imageOpr colorHalftoneWith: cols[n % 3] method:(n < 3)];
	return self;
}

- changeEnhance: sender
{
	char buf[16];
	float v = [enhanceSlider floatValue];
	sprintf(buf, "%4.1f", v);
	[enhanceText setStringValue:buf];
	return self;
}

- enhance: sender
{
	return [imageOpr enhanceWith: [enhanceSlider floatValue]];
}

- changeEmboss: sender
{
	char buf[16];
	float v = [embossSlider floatValue];
	sprintf(buf, "%4.2f", v);
	[embossText setStringValue:buf];
	return self;
}

- emboss: sender
{
	return [imageOpr embossWith: [enhanceSlider floatValue]
			and:[embossSlider floatValue]];
}

- posterize: sender
{
	return [imageOpr posterizeWith: [posterDiffSlider floatValue]
			and:[posterCtrlSlider floatValue]];
}


static ToyWin *commWin = nil;

- editComment: sender
{
	int i, x;
	commonInfo *cinf;
	const char *p;
	char commmsg[MAX_COMMENT];

	if ((commWin = [theController keyWindow]) == nil) {
		NXBeep();
		return self;
	}
	cinf = [[commWin toyView] commonInfo];
	for (p = [commWin filename], i = x = 0; p[i]; i++)
		if (p[i] == '/') x = i + 1;
	sprintf(commmsg, "%s: ", &p[x]);
	for (p = cinf->memo, i = 0; p[i] && p[i] != ':'; i++) ;
	strncat(commmsg, p, i);
	[commentMsg setStringValue:commmsg];
	if (p[i] == ':') {
		while (p[++i] == ' ') ;
		[commentText setStringValue: &p[i]];
	}else
		[commentText setStringValue: ""];
	[commentPanel makeKeyAndOrderFront: self];
	return self;
}

- writeComment: sender
{
	commonInfo *cinf;
	int i, last;
	char *p;
	const char *q;
	id tv;

	if ([sender selectedTag] == 0) { /* OK */
		if ([theController checkWindow: commWin delete:NO] == nil) {
			NXBeep();
			return self;
		}
		cinf = [(tv = [commWin toyView]) commonInfo];
		last = 0;
		for (p = cinf->memo, i = 0; p[i] && p[i] != ':'; i++)
			if (p[i] != ' ') last = i;
		if ((q =[commentText stringValue]) != NULL && *q) {
			strcpy(&p[last + 1], " : ");
			comm_cat(p, q);
		}else
			p[last + 1] = 0;
		[tv rewriteComment];
	}
	[commentPanel performClose: self];
	return self;
}

@end
