//
//  TKResource.m
//  ThemeKit
//
//  Created by Colin Cornaby on Mon Dec 08 2003.
//  Copyright (c) 2003 Carpe Stellarem. All rights reserved.
//
//  This library is free software; you can redistribute it and/or
//  modify it under the terms of the GNU Lesser General Public
//  License as published by the Free Software Foundation; either
//  version 2.1 of the License, or (at your option) any later version.
//
//  This library is distributed in the hope that it will be useful,
//  but WITHOUT ANY WARRANTY; without even the implied warranty of
//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
//  Lesser General Public License for more details.

//  You should have received a copy of the GNU Lesser General Public
//  License along with this library; if not, write to the Free Software
//  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA

#import "TKResource.h"
#import "TKTheme.h"

@implementation TKResource

void scramble(unsigned long key, const unsigned char *src, unsigned char *dst, size_t size);

//Just some accessor methods

-(id)delegate
{
	return delegate;
}

-(void)setDelegate:(id)newDelegate
{
	delegate = newDelegate;
}

-(void)setResourceName:(NSString *)theName
{
	[self setValue:theName forKey:@"name"];
}

-(NSString *)resourceName{
	NSString *flavorName = [self valueForKey:@"name"];
	if(flavorName==nil)
		return @"Untitled Resource";
	return flavorName;
}

-(NSString *)owner{
	[self willAccessValueForKey:@"owner"];
	id owner = [self primitiveValueForKey:@"owner"];
	[self didAccessValueForKey:@"owner"];
	return owner;
}

- (int)endianness 
{
    NSNumber * tmpValue;
    
    [self willAccessValueForKey: @"endianness"];
    tmpValue = [self primitiveValueForKey: @"endianness"];
    [self didAccessValueForKey: @"endianness"];
    
    return [tmpValue intValue];
}

-(void)setResourceID:(int)passedResID{
	[self setValue:[NSNumber numberWithInt:passedResID] forKey:@"id"];
}

-(int)resourceID{
	NSNumber *value = [self valueForKey:@"id"];
	if(value ==nil)
		return -1;
	return [value intValue];
}

-(NSNumber *)resourceIDAsNumber{
	NSNumber *value = [self valueForKey:@"id"];
	return value;
}

-(void)setStatus:(NSNumber *)status
{
	[self willChangeValueForKey:@"status"];
    [self setPrimitiveValue:status forKey:@"status"];
    [self didChangeValueForKey:@"status"];
}

-(NSNumber *)status
{
	[self willAccessValueForKey:@"status"];
    NSNumber *n = [self primitiveValueForKey:@"status"];
    [self didAccessValueForKey:@"status"];
    return n;
}

-(void)setOriginalResourceHash:(NSData *)appVersion
{
	[self willChangeValueForKey:@"originalResourceHash"];
    [self setPrimitiveValue:appVersion forKey:@"originalResourceHash"];
    [self didChangeValueForKey:@"originalResourceHash"];
}

-(NSData *)originalResourceHash
{
	[self willAccessValueForKey:@"originalResourceHash"];
    NSData *n = [self primitiveValueForKey:@"originalResourceHash"];
    [self didAccessValueForKey:@"originalResourceHash"];
    return n;
}

/*-(void)setOriginalResourceHash:(NSData *)appVersion
{
	[self willChangeValueForKey:@"originalResourceHash"];
    [self setPrimitiveValue:appVersion forKey:@"originalResourceHash"];
    [self didChangeValueForKey:@"originalResourceHash"];
}*/

-(void)setAppVersion:(NSString *)appVersion
{
	[self willChangeValueForKey:@"appVersion"];
    [self setPrimitiveValue:appVersion forKey:@"appVersion"];
    [self didChangeValueForKey:@"appVersion"];
}

-(NSString *)appVersion
{
	[self willAccessValueForKey:@"appVersion"];
    NSString *n = [self primitiveValueForKey:@"appVersion"];
    [self didAccessValueForKey:@"appVersion"];
    return n;
}

-(NSData *)resourceData{
	return [[self valueForKey:@"data"] valueForKey:@"data"];
}

-(void)setResourceData:(NSData *)someData dataEndianness:(TKEndianness)endianness
{
	[self willAccessValueForKey:@"endianness"];
	[self setValue:[NSNumber numberWithInt:endianness] forKey:@"endianness"];
	[self didAccessValueForKey:@"endianness"];
	[self setResourceData:someData];
}

-(void)setResourceData:(NSData *)someData
{
	if([self valueForKey:@"data"]==nil)
	{
		[self setValue:[NSEntityDescription insertNewObjectForEntityForName:@"TKResourceData" inManagedObjectContext:[self managedObjectContext]] forKey:@"data"];
	}
	[[self valueForKey:@"data"] setValue:someData forKey:@"data"];
	//[[[self managedObjectContext] undoManager] registerUndoWithTarget:self
    //            selector:@selector(setResourceData:)
      //          object:oldData];
        [[[self managedObjectContext] undoManager] setActionName:@"Edit Resource"];
}

-(void)setData:(id)data
{
	//id owner = [self valueForKey:@"owner"];
	//NSData *finalData = data;
	/*if([owner metadataForKey:@"TKDRMKey"]!=nil)
	{
		int dataLength = [data length];
		char dest[dataLength];
		//scramble([[owner currentDRMKey] bytes] ,[data bytes], dest, dataLength);
		finalData = [NSData dataWithBytes:dest length:dataLength];
	}*/
	[self willChangeValueForKey:@"data"];
	[self setPrimitiveValue:data  forKey:@"data"];
    [self didChangeValueForKey:@"data"];
	if([[delegate class] instancesRespondToSelector:@selector(resourceDidChange)])
		[delegate performSelector:@selector(resourceDidChange) withObject:nil];
}

void scramble(unsigned long key, const unsigned char *src, unsigned char *dst, size_t size)
{
    // seed our generator function
    srandom(key);

    // while data remains in src
    while (size) {
        // pull an unsigned 32-bit value
        unsigned long scrambler = random();

        // scramble!
        if (size > 4) {
            *(unsigned long*)dst = *(unsigned long*)src ^ scrambler;
            src += 4; dst += 4; size -= 4;
        } else {
            unsigned char *scr = (unsigned char*)&scrambler;
            while (size) {
                *dst++ = (*src++) ^ (*scr++);
                size -= 1;
            }
        }
    }

    // clear our generator function
    srandom(0);
}

-(NSString *)humanReadableType
{
	return [self className];
}

-(NSData *)resourceDataForPlatform:(int)platform
{
	return [self resourceData];
}

- (void)setValue:(id)value forKey:(NSString *)key
{
	if([(TKTheme *)[self managedObjectContext] isMutableContext])
		[super setValue:value forKey:key];
}

-(id)super
{
	if([(TKTheme *)[self managedObjectContext] isAllowedToAccessSuper])
		return [self super];
	return nil;
}

@end
