//	Copyright 1992  Thomas A. Dilligan
//		All Rights Reserved
//
// For best results, set tabstop=4

#import "ShaderInspector.h"

int CheckExtension(char *check,char *ext)
{
	int cnt;
	int lencheck;
	int lenext;
	int good=0;
	lencheck=strlen(check);
	lenext=strlen(ext);
	if(lencheck>lenext)
	{
		lencheck-=lenext;
		for(cnt=0,good=1;cnt<lenext;cnt++)
			good=good && (check[lencheck+cnt]==ext[cnt]);
	}
	return good;
}

@implementation ShaderInspector

- fillShaders:listObj 
{
	DIR *dirstream;
	struct direct *currentdir;
	int i;
	id tid;
	char *path;
	char *paths[]={"~/Library/Shaders","/NextLibrary/Shaders","/LocalLibrary/Shaders"};
	char name[255];
	for(i=0;i<3;i++)
	{
		path=paths[i];
		dirstream=opendir(path);
		if(dirstream)
			for(currentdir=readdir(dirstream);currentdir;currentdir=readdir(dirstream))
				if(CheckExtension(currentdir->d_name,".slo"))
				{
					strcpy(name, currentdir->d_name);
					name[strlen(name)-4]=0;
					tid=[[N3DShader alloc] initWithShader:name];
					[listObj addObject:tid];
				}
	}
	return self;
}

- appDidInit:sender
{
	char text[MAX_STLN];
	char *finalSlash;
	int i,j;
	id temp=NULL;
	RtPoint point = {0.0,0.0,0.0};
	shaders=[[List alloc] initCount:0];
	strcpy(text, NXArgv[0]);
	finalSlash = rindex(text, '/');
	for(i=0;i<6;i++)
		currentShaders[i]=NULL;
	if (finalSlash)
	{
		*finalSlash = '\0';
		chdir(text);
	}
	[self fillShaders:shaders];
	for(j=0;j<6;j++)
	{
		for(i=0;i<[shaders count];i++)
			if([[shaders objectAt:i] shaderType]==SLO_TYPE_SURFACE+j)
			{
				switch(j)
				{
					case 0:
						temp=[[surfacePopUp popUpList] addItem:[[shaders objectAt:i] shader]];
					break;
					case 1:
						temp=[[lightPopUp popUpList] addItem:[[shaders objectAt:i] shader]];
					break;
					case 2:
						temp=[[displacementPopUp popUpList] addItem:[[shaders objectAt:i] shader]];
					break;
					case 3:
						temp=[[volumePopUp popUpList] addItem:[[shaders objectAt:i] shader]];
					break;
					case 4:
						temp=[[transformationPopUp popUpList] addItem:[[shaders objectAt:i] shader]];
					break;
					case 5:
						temp=[[imagerPopUp popUpList] addItem:[[shaders objectAt:i] shader]];
					break;
				}
				[temp setTarget:self];
				[temp setTag:i];
				[temp setAction:@selector(shaderChange:)];
			}
		[[inspectionButtons findCellWithTag:j] setEnabled:NO];
	}
	temp=[[surfacePopUp popUpList] addItem:"None"];
	[surfacePopUp setTitle:"None"];
	[temp setTarget:self];
	[temp setTag:-1];
	[temp setAction:@selector(shaderChange:)];
	temp=[[lightPopUp popUpList] addItem:"None"];
	[lightPopUp setTitle:"None"];
	[temp setTarget:self];
	[temp setTag:-3];
	[temp setAction:@selector(shaderChange:)];
	temp=[[displacementPopUp popUpList] addItem:"None"];
	[displacementPopUp setTitle:"None"];
	[temp setTarget:self];
	[temp setTag:-2];
	[temp setAction:@selector(shaderChange:)];
	temp=[[volumePopUp popUpList] addItem:"None"];
	[volumePopUp setTitle:"None"];
	[temp setTarget:self];
	[temp setTag:-4];
	[temp setAction:@selector(shaderChange:)];
	temp=[[transformationPopUp popUpList] addItem:"None"];
	[transformationPopUp setTitle:"None"];
	[temp setTarget:self];
	[temp setTag:-5];
	[temp setAction:@selector(shaderChange:)];
	temp=[[imagerPopUp popUpList] addItem:"None"];
	[imagerPopUp setTitle:"None"];
	[temp setTarget:self];
	[temp setTag:-6];
	[temp setAction:@selector(shaderChange:)];

	for(i=0;i<5;i++)
	{
		lights[i]=[[N3DLight alloc] init];
		switch(i)
		{
			case 0:
				[lights[0] makeAmbientWithIntensity:4.0];
			break;
			case 1:
				point[0]=1;
				point[1]=-1;
				point[2]=1;
				[lights[i] makePointFrom:point intensity:0.0];
			break;
			case 2:
				point[0]=0;
				point[1]=0;
				point[2]=3;
				[lights[i] makePointFrom:point intensity:0.0];
			break;
			case 3:
				point[0]=1;
				point[1]=1;
				point[2]=0;
				[lights[i] makePointFrom:point intensity:0.0];
			break;
			case 4:
				point[0]=-1;
				point[1]=-1;
				point[2]=3;
				[lights[i] makePointFrom:point intensity:0.0];
			break;
		}			
		[view addLight:lights[i]];
	}
	[[view window] orderFront:self];
	return self; 
}

- shaderChange:sender
{
	int i;
	if([[sender selectedCell] tag]<0)
	{
		i=-[[sender selectedCell] tag] - 1;
		currentShaders[i]=NULL;
	}
	else
	{
		i=[[shaders objectAt:[[sender selectedCell] tag]] shaderType]-5;
		currentShaders[i]=[shaders objectAt:[[sender selectedCell] tag]];
	}
	[[inspectionButtons findCellWithTag:i] setEnabled:(int)[shaders objectAt:[[sender selectedCell] tag]]];
	return self;
}

- shaderInspect:sender
{
	while(!shaderInspector)
	{
		shaderInspector=[GenericShaderInspector alloc];
		[NXApp loadNibSection:"Inspector.nib" owner:shaderInspector];	
	}
	[shaderInspector showSelfAndInspect:currentShaders[[[sender selectedCell] tag]]];	
	return self;
}

- pointLightLevelsChange:sender;
{
	[[pointLevels findCellWithTag:[[sender selectedCell] tag]] setFloatValue:[[sender selectedCell] floatValue]];
	return self;
}

- ambientLightLevelChange:sender;
{
	[ambientLevel setFloatValue:[sender floatValue]];
	return self;
}

- renderPhotoreal:sender;
{
	int i;
	for(i=0;i<5;i++)
		switch(i)
		{
			case 0:
				[lights[0] setIntensity:[ambientLevel floatValue]];
			break;
			case 1:
			case 2:
			case 3:
			case 4:
				[lights[i] setIntensity:[[pointLevels findCellWithTag:(i-1)] floatValue]];
			break;
		}
	[[view worldShape] resetShaders];
	for(i=0;i<6;i++)
		if(currentShaders[i])
			[(N3DShape *)[view worldShape] setShader:currentShaders[i]];
	[view displayPhotoreal];
	[[view worldShape] resetShaders];
	for(i=0;i<5;i++)
		[lights[i] setIntensity:0];
	return self;
}

- showInfoPanel:sender
{
	if(!infoPanel)
		infoPanel=[NXApp loadNibSection:"Info.nib" owner:self];
	[infoPanel orderFront:self];
	return self;
}

@end
