/* Copyright (c) 2011 Artjom Popov */

#import "UTDerivedResource.h"
#import "UTGeometry.h"
#import "UTDerivedImage.h"
#import "UIImage+Additions.h"

@implementation UTDerivedImage

- (id)initWithURL:(NSURL *)url revision:(NSString *)revision size:(CGSize)size
{
	return [self initWithURL:url revision:revision size:size zoom:1.0F focus:CGPointMake(0.0F, 0.0F)];
}

- (id)initWithURL:(NSURL *)url revision:(NSString *)revision size:(CGSize)size zoom:(CGFloat)zoom focus:(CGPoint)focus
{
	self = [super init];
	
	if(self) {
		NSDictionary *key = [NSDictionary dictionaryWithObjectsAndKeys:
							 [NSString stringWithFormat:@"%i", (NSInteger)size.width], @"width", 
							 [NSString stringWithFormat:@"%i", (NSInteger)size.height], @"height", 
							 [NSString stringWithFormat:@"%@", url], @"url", 
							 [NSString stringWithFormat:@"%@", (revision) ? revision : @"0"], @"revision",nil];


		NSData *data = [NSData dataWithContentsOfURL:url];
		self->m_image = [[UIImage alloc] initWithData:data];
		
		self->m_size = size;
		self->m_focus = focus;
		self->m_zoom = zoom;
		self->m_resource = [[UTDerivedResource alloc] initWithKey:key];

	}
	
	return self;
}

@synthesize size = m_size;
@synthesize focus = m_focus;
@synthesize zoom = m_zoom;
@synthesize glossEffect = m_glossEffect;
@synthesize aspectFitSize = m_aspectFitSize;
@synthesize image = m_image;

- (void)load
{
	if(self->m_resource.exists) {
		[self->m_image release];
		self->m_image = [[UIImage imageWithARGBData:self->m_resource.data size:self->m_size] retain];
	} else {
		UIImage *image = self->m_image;
		CGSize sizeToFit = UTGeometryAspectFitSize(image.size, self->m_size);
		CGRect rect = UTGeometryAlignedRectangle(self->m_aspectFitSize ? sizeToFit : self->m_size, CGSizeMake(image.size.width, image.size.height), self->m_focus, self->m_zoom, self->m_aspectFitSize ? sizeToFit : self->m_size);
		image = [image imageTransform:UTGeometryTransform(rect, CGRectMake(0.0F, 0.0F, image.size.width, image.size.height))];

		int width = self->m_size.width;
		int height = self->m_size.height;
		
		CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
		void *data = malloc(sizeof(UInt8) * width * height * 4);
		CGContextRef context = CGBitmapContextCreate(data, width, height, 8, 4 * width, colorSpace, kCGImageAlphaPremultipliedFirst);
		CGContextClearRect(context, CGRectMake(0, 0, width, height));
		
		if(self->m_glossEffect) EPImageAddGlossEffect(context, CGRectMake(0.0F, 0.0F, width, height), image.CGImage, 10.0F, 10.0F);
		
		rect = self->m_aspectFitSize ? CGRectMake((self->m_size.width - sizeToFit.width)/2, (self->m_size.height - sizeToFit.height)/2, sizeToFit.width, sizeToFit.height)
		: CGRectMake(0, 0, width, height);
		
		CGContextDrawImage(context, rect, image.CGImage);
		
		CGContextRelease(context);
		CGColorSpaceRelease(colorSpace);
		
		NSData *newData = [NSData dataWithBytesNoCopy:data length:sizeof(UInt8) * width * height * 4];
		self->m_resource.data = newData;
		
		[self->m_image release];
		self->m_image = [[UIImage imageWithARGBData:newData size:self->m_size] retain];
		
	}
	
}

#pragma mark NSObject

- (void)dealloc
{
	[self->m_resource release];
	[self->m_image release];
	[super dealloc];
}

@end
