#import "theBrain.h"

#define Normal 0
#define SetNorthPalace 1
#define SetGreatPalace 2

// Rendre les groupes bleus lorsque = au maximum
// Changer les exˇdents pour 0F, et non FF
// Changer le dialogue aussi
// Demander de saver avant de quitter

@implementation theBrain

const char hex[16] = "0123456789abcdef";

- (void)awakeFromNib
{
	currentTool = [[NSMutableString alloc] initWithCapacity:5];
	path = [[NSMutableString alloc] initWithCapacity:64];
	[scrollView setLineScroll:32];
	editState = Normal;
}

- (IBAction)loadWest:(id)sender
{
	if (offSet != 0x506C) {
		offSet = 0x506C; max = 801;
		offSetPalaces = 0x479F; maxPalaces = 4;
		[self loadMap];
	}
}

- (IBAction)loadEast:(id)sender
{
	if (offSet != 0x9056) { offSet = 0x9056; max = 794; [self loadMap]; }
}

// Instead of all this, use p[4]
// 0 = Palace
// 1 = Skip (North Palace)
// 2 = Hidden palace (6th Palace)

- (IBAction)loadDM:(id)sender
{
	if (offSet != 0x665C) { offSet = 0x665C; max = 1000; [self loadMap]; }   // max = 668
}

// New ! Max is almost infinite for DM !
// Not limited to 668

- (void)loadMap
{
	NSRange rn = { offSet , max };
	if (regionData) [regionData release];
	regionData = [[NSData alloc] initWithData:[romData subdataWithRange:rn]];
	[map renewRows:1 columns:64];
	
	NSMutableString *temp = [NSMutableString string];
	const unsigned char *buf = [regionData bytes];
	unsigned char b1,b2;	// b1 : High Byte   b2 : Low Byte
	
	int c = 0;
	int r = 0;
	int i,j;
	
	for (i=0; i<max; i++) {
		
		b1 = buf[i] >> 4;
		b2 = hex[ buf[i] & 0x0F ];
		[temp setString:[NSString stringWithFormat:@"tile%c",b2]];
		
		for (j=0; j<(b1+1); j++) {
			[[map cellAtRow:r column:c] setImage:[NSImage imageNamed:temp]];
			c++;
			if (c == [map numberOfColumns] && (i < max-1)) {
				c=0; r++;
				[map addRow];
			}
		}
	}
	
	[map sizeToCells];
	[map display];
	[self calc];
}

- (IBAction)open:(id)sender
{
	int r,i;
	NSOpenPanel *op = [NSOpenPanel openPanel];
	r = [op runModalForTypes:nil];
	if (r = NSOKButton) {
		
		[path setString:[[op filenames] lastObject]];
		romData = [[NSMutableData alloc] initWithContentsOfFile:path];
		[self loadWest:nil];
		
	}
	
	for (i=0; i<16; i++) { [[tools cellWithTag:i] setBordered:NO]; }
	[currentTool setString:@"tile0"];
	[[tools cellWithTag:0] setBordered:YES];
}

- (IBAction)save:(id)sender
{
	int i = NSOKButton; BOOL r;
	
	if (g > max) {
		i = NSRunAlertPanel(@"You exceed the number of groups allowed. Save anyway ?",
                            @"You will lose some data at the end in the process.",
                            @"Yes",@"No",nil);
	} else if (g < max) {
		i = NSRunAlertPanel(@"You did not use all the allowed bytes. Save anyway ?",
                            @"The unused bytes will be set to FF (spider).",
                            @"Yes",@"No",nil);
	}
	
	if (i == NSOKButton) {
		[self palacePointers];
		NSRange rn = { offSet,max };
		[romData replaceBytesInRange:rn withBytes:b];
		r = [romData writeToFile:path atomically:YES];
		if (r == YES) NSLog(@"Success !");
		else NSLog(@"Error !");
	}
}

- (void)palacePointers
{
	int c = 0;
	unsigned short i,f,r;
	unsigned short s[3];
	unsigned short *ptr;
	ptr = &s[0];
	
	for (i=0; i<max; i++) {
		if (b[i] == 0x02) {
			f = (i + 0x7C00);
			r = ( (f << 8) | (f >> 8) );
			NSLog(@"f : %X",f);
			NSLog(@"r : %X",r);
			if ( (offSet == 0x506C) && (c != 1) ) {
				*ptr = r;
				NSLog(@"*ptr : %X",*ptr);
				ptr++;
			}
			c++;
		}
		if (c == maxPalaces) break;
	}
	ptr -= 3;
	NSRange rn = { offSetPalaces , 6 };
	[romData replaceBytesInRange:rn withBytes:ptr];
}

// West Hyrule		palace 1, skip, palace 2, palace 3		maxPalaces = 4, skip = 1
// East Hyrule		palace 5, skip, palace 6 hidden			maxPalaces = 3, skip = 1, check hidden (?)
// DM / MI			palace 4								maxPalaces = 1, skip = -1

// Offset Palace + 7C00
// (5084 - 506C) + 7C00 = 7C18 = 31768
// (51E2 - 506C) + 7C00 = 7D76 = 32118
// (5356 - 506C) + 7C00 = 7EEA = 32490

- (IBAction)clickMap:(id)sender
{
	[[map selectedCell] setImage:[NSImage imageNamed:currentTool]];
	[self calc];
}

- (IBAction)changeTool:(id)sender
{
	int i;
	for (i=0; i<16; i++) { [[tools cellWithTag:i] setBordered:NO]; }
	[[tools selectedCell] setBordered:YES];
	NSString *str = [NSString stringWithFormat:@"tile%c",hex[ [[tools selectedCell] tag] ]];
	[currentTool setString:str];
}

- (void)calc
{
	g = 0;
	int i,j;
	int r = 0;
	
	NSString *h = @"0123456789abcdef";
	NSRange rn;
	NSMutableString *tile = [NSMutableString stringWithCapacity:5];
	
    for (i=0; i<[map numberOfRows]; i++) {
		[tile setString:[[[map cellAtRow:i column:0] image] name] ];
        for (j=1; j<[map numberOfColumns]; j++) {
			
			if ( [tile isEqualTo:[[[map cellAtRow:i column:j] image] name] ] ) {
				r++;
				if (r == 16) {
					
					rn = [h rangeOfString:[tile substringWithRange:NSMakeRange(4,1)]];
					b[g] = (15*16) + rn.location;
					
					g++;
					r = 0;
				}
			} else {
				
				if ([[map cellAtRow:i column:j] image] == nil) break;
				
				rn = [h rangeOfString:[tile substringWithRange:NSMakeRange(4,1)]];
				b[g] = (r*16) + rn.location;
				
				g++;
				r = 0;
				
				[tile setString:[[[map cellAtRow:i column:j] image] name] ];
			}
		}
		
		rn = [h rangeOfString:[tile substringWithRange:NSMakeRange(4,1)]];
		b[g] = (r*16) + rn.location;
		
		g++;
		r = 0;
	}
	
	[groups setStringValue:[NSString stringWithFormat:@"%d / %d",g,max]];
    if (g > max) [groups setTextColor:[NSColor redColor]];
    else {
		[groups setTextColor:[NSColor blackColor]];
		for (i=g; i<max; i++) {
			b[i] = 0xFF;
		}
	}
}

- (void)dealloc
{
	[romData release];
}

@end

@implementation NSMatrix (NSMatrixPlus)

- (BOOL)acceptsFirstMouse:(NSEvent *)ev
{
	return NO;
}

/*- (void)calc
{
    int i,j; NSMutableString *ima = [NSMutableString stringWithCapacity:5]; int gr=0, ra=0;
    for (i=0; i<[map numberOfRows]; i++) {
        for (j=0; j<[map numberOfColumns]; j++) {
            
            if ( ![ima isEqualTo:[[[map cellAtRow:i column:j] image] name] ] ) {
                gr++; ra = 0;
                [ima setString:[[[map cellAtRow:i column:j] image] name] ];
            } else {
            	ra++;
                if (ra == 16) { gr++; ra = 0; }
            }
        }
        [ima setString:@"e"];
    }
    [groups setStringValue:[NSString stringWithFormat:@"%d / %d",gr,max]];
    if (gr > max) [groups setTextColor:[NSColor redColor]];
    else [groups setTextColor:[NSColor blackColor]];
} */

/*i = NSRunAlertPanel(@"Warning",
					@"Do you want to save changes before you switch map ?",
					@"Yes",@"No",@"Cancel");
*/

@end


