//
//  PhotoLayer.m
//  OminoGobo
//
//  Created by David Van Brink on 1/11/14.
//  Copyright (c) 2014 omino. All rights reserved.
//

#import "PhotoLayer.h"
#import <AssetsLibrary/AssetsLibrary.h>
#import <ImageIO/ImageIO.h>
#import "Util.h"

@implementation PhotoLayer


- (id) init
{
    self = [super init];
    
    self->oldPhotoUrl = nil;
    
    return self;
}


- (void) setStageItem:(OGStageItem *)newStageItem
{
    [super setStageItem:newStageItem];
    
    OGPhoto *op = (OGPhoto *)newStageItem; // cast
    [self loadUpImage:op];
}

- (void) loadUpImage:(OGPhoto *)op
{
    [self updateFromItem];
}

- (void) assetLoadBg
{
    OGPhoto *pi = (OGPhoto *)self->stageItem;
    ALAssetsLibrary *assetLibrary=[[ALAssetsLibrary alloc] init];
    [assetLibrary assetForURL:pi.photo resultBlock:^(ALAsset *asset) {
        ALAssetRepresentation *rep = [asset defaultRepresentation];
        
        UIImage *image = [UIImage imageWithCGImage:[rep fullScreenImage] scale:[rep scale] orientation:0];
        image = [self processImage:image];
        self->loadedImage = image;
        [self assetLoadBgDone]; // the callback.
        
    } failureBlock:^(NSError *err) {
        NSLog(@"Error: %@",[err localizedDescription]);
    }];
}

- (void) assetLoadFg
{
    // And do this finish-up in main (UI) thread.
    UIImage *image = self->loadedImage;
    if(image && image.CGImage)
    {
        CGImageRef cgImage = image.CGImage;
        CGFloat width = CGImageGetWidth(cgImage);
        CGFloat height = CGImageGetHeight(cgImage);
        
        height = 40 * height / width;
        width = 40;
        self.layer.bounds = CGRectMake(0,0,width,height);
        
        self.layer.contents = (__bridge id)cgImage;
    }
    [self updateFromItem];
}

- (void) updateFromItem
{
    [super updateFromItem];
    
    // do this all in bg...
    
    OGPhoto *pi = (OGPhoto *)self->stageItem;
    if(!objEqual(self->oldPhotoUrl,pi.photo))
    {
        [self needsAssetLoad];
        self->oldPhotoUrl = pi.photo;
    }

    
    
    self.layer.backgroundColor = nil;
}

// Make the image transparent where it is dark.
- (UIImage *) processImage:(UIImage *)image
{
    CGContextRef context;
    NSUInteger width;
    NSUInteger height;
    unsigned char *rawData;

    {
        // http://brandontreb.com/image-manipulation-retrieving-and-updating-pixel-values-for-a-uiimage
        // gives this explanation
        CGImageRef imageRef = image.CGImage;
        width = CGImageGetWidth(imageRef);
        height = CGImageGetHeight(imageRef);
        CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
        rawData = malloc(height * width * 4);
        NSUInteger bytesPerPixel = 4;
        NSUInteger bytesPerRow = bytesPerPixel * width;
        NSUInteger bitsPerComponent = 8;
        context = CGBitmapContextCreate(rawData, width, height,
                                                     bitsPerComponent, bytesPerRow, colorSpace,
                                                     kCGImageAlphaPremultipliedLast | kCGBitmapByteOrder32Big);
        CGColorSpaceRelease(colorSpace);
        
        CGContextDrawImage(context, CGRectMake(0, 0, width, height), imageRef);
    }
    

    {
        // darken the edges...
        CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
        
        CGContextSetFillColorSpace(context,colorSpace);
        CGContextSetStrokeColorSpace(context,colorSpace);

        CGColorSpaceRelease(colorSpace);
        
        CGFloat edgeWi = (width / 16);
        if(edgeWi < 10)
            edgeWi = 10;
        CGRect outside = CGRectMake(0,0,width,height);
        CGContextSetLineWidth(context, 2.0);
        CGFloat co[4] = {0,0,0,0};
        for(int ix = 0; ix <= edgeWi; ix++)
        {
            CGFloat a = (edgeWi - ix) / edgeWi;
            co[3] = a;
            CGContextSetStrokeColor(context,co);
            CGContextStrokeRect(context,outside);
            outside = CGRectInset(outside, 1, 1);
        }
    }

    


    {
        // process
        unsigned char *w = rawData;
        for (int ii = 0 ; ii < width * height ; ++ii)
        {
            w[3] = (w[0] + w[1] + w[2]) / 3;
            w += 4;
        }
        
        // did.
        CGImageRef imageRef = CGBitmapContextCreateImage (context);
        UIImage* outImage = [UIImage imageWithCGImage:imageRef];
        
        CGImageRelease(imageRef);
    
        free(rawData);
        CGContextRelease(context);
        return outImage;
    }
    
}


@end
