//
//  PDFTiledView.m
//  PDFReader
//
//  Created by Dong Li on 12-4-8.
//  Copyright (c) 2013年 __MyCompanyName__. All rights reserved.
//

#import "PDFTiledView.h"


@implementation PDFTiledView

+ (Class)layerClass {
    return [CATiledLayer class];
}

- (id)initWithFrame:(CGRect)frame document:(CGPDFDocumentRef)document page:(CGPDFPageRef)page {
    if (self = [super initWithFrame:frame]) {
        [self setBackgroundColor:UIColorWhite];
        [self setClipsToBounds:YES];
        
		CATiledLayer *tiledLayer = (CATiledLayer *)[self layer];
		// levelsOfDetail and levelsOfDetailBias determine how
		// the layer is rendered at different zoom levels.  This
		// only matters while the view is zooming, since once the
		// the view is done zooming a new PDFTiledView is created
		// at the correct size and scale.
        static const CGSize tileSize = { 1024.f, 1024.f };
        
        [tiledLayer setBackgroundColor:CGColorWhite];
        [tiledLayer setLevelsOfDetail:4];
        [tiledLayer setLevelsOfDetailBias:3];
        [tiledLayer setTileSize:tileSize];
        
        _scale = 1.f;
        _PDFDocument = CGPDFDocumentRetain(document);
        _PDFPage = CGPDFPageRetain(page);
    }
    return self;
}

- (void)drawRect:(CGRect)rect {
    /*
     UIView uses the existence of -drawRect: to determine if it should allow its CALayer to be invalidated, which would then lead to the layer creating a backing store and -drawLayer:inContext: being called.
     Implementing an empty -drawRect: method allows UIKit to continue to implement this logic, while doing the real drawing work inside of -drawLayer:inContext:.
     */
}

- (void)drawLayer:(CALayer *)layer inContext:(CGContextRef)context {
    const CGRect bounds = [self bounds];
    
    CGContextSaveGState(context);
    
    CGContextSetRGBFillColor(context, 1.f, 1.f, 1.f, 1.f);
    CGContextFillRect(context, bounds);
    
    if (fabs(_rotate) > CGRadianPerDegree) {
        const CGRect rotatedRect = CGRectApplyAffineTransform(bounds, CGAffineTransformMakeRotation(_rotate));
        
        CGContextRotateCTM(context, _rotate);
        CGContextTranslateCTM(context, rotatedRect.origin.y, rotatedRect.origin.x);
    }
    
    CGContextTranslateCTM(context, -_offset.x, _offset.y);
    // Flip the context so that the PDF page is rendered
    // right side up.
    CGContextTranslateCTM(context, 0.0, bounds.size.height);
    // Scale the context so that the PDF page is rendered
    // at the correct size for the zoom level.
    CGContextScaleCTM(context, _scale, -_scale);
    CGContextDrawPDFPage(context, _PDFPage);
    
    CGContextRestoreGState(context);
    
}

- (void)dealloc {
    CGPDFPageRelease(_PDFPage);
    CGPDFDocumentRelease(_PDFDocument);
}


- (void)setScale:(CGFloat)scale rotate:(CGFloat)rotate offset:(CGPoint)offset {
    _scale = scale;
    _rotate = rotate;
    _offset.x = offset.x * scale;
    _offset.y = offset.y * scale;
    
    [self setNeedsDisplay];
}

@end
