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

#import "PDFViewController.h"
#import "PDFControlView.h"
#import "UITextStyleSettings.h"
#import "FSFileItem.h"
#import <sys/xattr.h>

#define kContentLayoutKey @"com.pdf.content_layout"

typedef struct __CGLayout {
    CGFloat offsetX;
    CGFloat offsetY;
    CGFloat zoomScale;
} CGLayout;

@interface PDFViewController (PrivateMethods)

@end

@implementation PDFViewController

- (id)initWithFileItem:(FSFileItem *)fileItem {
    self = [super init];
    if (self) {
        [self setTitle:[fileItem displayName]];
        
        _statusBarStyle = UIStatusBarStyleLightContent;
        
        NSURL *URL = [[NSURL alloc] initFileURLWithPath:[fileItem path]];
        _PDFDocument = CGPDFDocumentCreateWithURL((CFURLRef)URL);
        UIBarButtonItem *stopItem = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemStop target:self action:@selector(onClose)];
        
        [[self navigationItem] setLeftBarButtonItem:stopItem];
        _pageLabel = [[UILabel alloc] initWithFrame:RECT(0, 0, 100, 24)];
        [_pageLabel setBackgroundColor:UIColorClear];
        [_pageLabel setTextColor:UIColorWhite];
        [_pageLabel setTextAlignment:NSTextAlignmentCenter];
        [_pageLabel setFont:UIFontBold18];
        [_pageLabel setLineBreakMode:NSLineBreakByClipping];
        
        UIBarButtonItem *actionItem = [[UIBarButtonItem alloc] initWithImage:[UIImage imageNamed:@"bar/action.png"] style:UIBarButtonItemStyleDone target:self action:@selector(onAction)];
        UIBarButtonItem *flexibleItem = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemFlexibleSpace target:nil action:NULL];
        UIBarButtonItem *textItem = [[UIBarButtonItem alloc] initWithCustomView:_pageLabel];
        
        NSArray *toolbarItems = [[NSArray alloc] initWithObjects:actionItem, flexibleItem, textItem, flexibleItem, _rotationItem, nil];
        
        [self setToolbarItems:toolbarItems];
        
        _fileItem = fileItem;
    }
    return self;
}

- (void)layoutWithContentSize:(const CGSize)contentSize {
    CGFloat x, w, gapY;
    
    [_PDFView stopDecelerating];
    
    if (contentSize.width < contentSize.height) {
        x = 15;
        w = contentSize.width - 30;
        gapY = contentSize.height - 216;
    } else {
        x = 20;
        w = contentSize.width - 40;
        gapY = contentSize.height - 162;
    }
    const CGRect promptFrame = { x, (gapY - 20) / 2.f, w, 20 };
    const CGRect inputFrame = { x, promptFrame.origin.y + promptFrame.size.height + 10, w, 31 };
    
    [_promptLabel setFrame:promptFrame];
    [_textField setFrame:inputFrame];
    [_slider setFrame:RECT(contentSize.width - 28, 0, 28, contentSize.height)];
}

- (void)loadExtendedAttributes {
    NSDictionary *attributes = [theFileManager attributesOfItemAtPath:[_fileItem path] error:NULL];
    NSDictionary *extendAttributes = [attributes valueForKey:NSFileExtendedAttributes];
    
    if (extendAttributes) {
        CGLayout contentLayout = { 0 };
        NSData *layoutData = [extendAttributes valueForKey:kContentLayoutKey];
        
        if (sizeof(CGLayout) == [layoutData length]) {
            memcpy(&contentLayout, [layoutData bytes], sizeof(CGLayout));
            const CGFloat zoomScale = contentLayout.zoomScale;
            
            if (0.99 < zoomScale && zoomScale < 8.01f) {
                const CGSize contentSize = [_PDFView contentSize];
                
                if (0.f <= contentLayout.offsetX && contentLayout.offsetX < 1.f && 0.f <= contentLayout.offsetY && contentLayout.offsetY < 1.f) {
                    const CGPoint contentOffset = { contentLayout.offsetX * contentSize.width * zoomScale, contentLayout.offsetY * contentSize.height * zoomScale };
                    [_PDFView setZoomScale:zoomScale];
                    [_PDFView setContentOffset:contentOffset];
                }
            }
        }
    }
}

- (void)loadPDFView {
    const CGRect bounds = [_contentView bounds];
    
    _PDFView = [[PDFControlView alloc] initWithFrame:bounds document:_PDFDocument];
    [_PDFView setZoomViewDelegate:self];
    [_PDFView setControlViewDelegate:self];
    [_contentView setBackgroundColor:UIColorBlack];
    [_contentView setAutoresizesSubviews:YES];
    [_contentView addSubview:_PDFView];
    
    _slider = [[PDFSlider alloc] initWithFrame:CGRectZero];
    [_slider setDelegate:self];
    [_contentView addSubview:_slider];
    
    [self performSelector:@selector(loadExtendedAttributes) withObject:nil afterDelay:0];
}

- (void)loadView {
    _contentView = [[UIView alloc] initWithFrame:CGRectPortraitScreen];
    [_contentView setBackgroundColor:UIColorTexturedBackground];
    
    if (NULL == _PDFDocument) {
        UIAlert(LS(@"BAD_PDF_TITLE"), LS(@"BAD_PDF_PROMPT"));
    } else if (CGPDFDocumentIsUnlocked(_PDFDocument)) {
        [self loadPDFView];
    } else {
        _promptLabel = [[UILabel alloc] initWithFrame:CGRectZero];
        [_promptLabel setBackgroundColor:UIColorClear];
        [_promptLabel setTextColor:UIColorWhite];
        [_promptLabel setTextAlignment:NSTextAlignmentCenter];
        [_promptLabel setFont:UIFontBold16];
        [_promptLabel setText:LS(@"PASSWORD_PROMPT")];
        [_contentView addSubview:_promptLabel];
        
        _textField = [[UITextField alloc] initWithFrame:CGRectZero];
        [_textField setDelegate:self];
        [_textField setBorderStyle:UITextBorderStyleRoundedRect];
        [_textField setKeyboardAppearance:UIKeyboardAppearanceDefault];
        [_textField setKeyboardType:UIKeyboardTypeASCIICapable];
        [_textField setReturnKeyType:UIReturnKeyDone];
        [_textField setSecureTextEntry:YES];
        [_textField setAutocapitalizationType:UITextAutocapitalizationTypeNone];
        [_textField setAutocorrectionType:UITextAutocorrectionTypeNo];
        [_textField setFont:UIFontBold16];
        [_textField setContentVerticalAlignment:UIControlContentVerticalAlignmentCenter];
        [_contentView addSubview:_textField];
        
        [_textField becomeFirstResponder];
    }
    
    [self setView:_contentView];
}

- (void)viewWillDisappear:(BOOL)animated {
    [[UIPrintInteractionController sharedPrintController] dismissAnimated:animated];
}

- (void)releaseSubviews {
    const CGPoint contentOffset = [_PDFView contentOffset];
    const CGSize contentSize = [_PDFView contentSize];
    const CGLayout contentLayout = { contentOffset.x / contentSize.width, contentOffset.y / contentSize.height, [_PDFView zoomScale] };
    NSData *layoutData = [[NSData alloc] initWithBytes:&contentLayout length:sizeof(CGLayout)];
    NSDictionary *extendedAttributes = [[NSDictionary alloc] initWithObjectsAndKeys:layoutData, kContentLayoutKey, nil];
    NSDictionary *attributes = [[NSDictionary alloc] initWithObjectsAndKeys:extendedAttributes, NSFileExtendedAttributes, nil];
    NSError *error = nil;
    
    [theFileManager setAttributes:attributes ofItemAtPath:[_fileItem path] error:&error];
    DLog(@"error: %@", error);
    
    _PDFView = nil;
    _slider = nil;
    _promptLabel = nil;
    _textField = nil;
    _contentView = nil;
}

- (void)dealloc {
    if (_PDFDocument) {
        CGPDFDocumentRelease(_PDFDocument);
    }
    }

#pragma mark - UITextFieldDelegate

- (BOOL)textFieldShouldReturn:(UITextField *)textField {
    NSString *text = [textField text];
    
    if ([text length] > 0) {
        if (CGPDFDocumentUnlockWithPassword(_PDFDocument, [text UTF8String])) {
            [_textField removeFromSuperview];
            _textField = nil;
            [_promptLabel removeFromSuperview];
            _promptLabel = nil;
            [self loadPDFView];
            return YES;
        }
    }
    UIAlert(LS(@"INVALID_PASSWORD"), nil);
    return NO;
}

#pragma mark - IFZoomViewDelegate

- (void)toggleFullScreen:(IFZoomView *)zoomView {
    [self reverseFullScreen];
    
    const BOOL isFullScreen = [self isFullScreen];
    
    [_PDFView setShowsVerticalScrollIndicator:isFullScreen];
    [UIView beginAnimations:nil context:NULL];
    [UIView setAnimationDuration:0.3f];
    [_slider setAlpha:(isFullScreen ? 0.f : 1.f)];
    [UIView commitAnimations];
}

#pragma mark - Action

- (void)onAction {
    UIActionSheet *actionSheet = [[UIActionSheet alloc] initWithTitle:nil delegate:self cancelButtonTitle:LS(@"CANCEL") destructiveButtonTitle:nil otherButtonTitles:LS(@"PRINT"), nil];
    
    [actionSheet showInView:[[self navigationController] view]];
}

- (void)onClose {
    [_PDFView setScrollEnabled:NO];
    
    [[self navigationController] dismissViewControllerAnimated:YES completion:NULL];
}

#pragma mark - UIActionSheetDelegate

- (void)actionSheet:(UIActionSheet *)actionSheet clickedButtonAtIndex:(NSInteger)buttonIndex {
    if (0 == buttonIndex) {
        NSURL *URL = [[NSURL alloc] initFileURLWithPath:[_fileItem path]];
        
        if ([UIPrintInteractionController canPrintURL:URL]) {
            UIPrintInteractionController *printController = [UIPrintInteractionController sharedPrintController];
            
            [printController setShowsPageRange:YES];
            [printController setPrintingItem:URL];
            [printController presentAnimated:YES completionHandler:^(UIPrintInteractionController *printInteractionController, BOOL completed, NSError *error){
                
            }];
        } else {
            UIAlert(LS(@"CANNOT_PRINT_TITLE"), LS(@"CANNOT_PRINT_PROMPT"));
        }
        }
}

#pragma mark - PDFSliderDelegate

- (void)sliderDidBeginDragging:(PDFSlider *)slider {
    _zoomScale = [_PDFView zoomScale];
    [_PDFView setMinimumZoomScale:0.8f];
    [_PDFView setZoomScale:0.8f animated:YES];
}

- (void)sliderWillEndDragging:(PDFSlider *)slider {
    [_PDFView setMinimumZoomScale:1.f];
    [_PDFView setZoomScale:_zoomScale animated:YES];
}

- (void)slider:(PDFSlider *)slider didChangeValue:(CGFloat)value {
    const CGRect bounds = [_PDFView bounds];
    const CGSize contentSize = [_PDFView contentSize];
    CGPoint contentOffset = [_PDFView contentOffset];
    
    contentOffset.y = (contentSize.height - bounds.size.height) * value;
    [_PDFView setContentOffset:contentOffset];
}

#pragma mark - PDFControlViewDelegate

- (void)controlView:(PDFControlView *)controlView didScrollToPage:(NSInteger)page ratio:(CGFloat)ratio {
    NSString *text = [[NSString alloc] initWithFormat:@"%d / %d", page, [controlView numberOfPages]];
    
    [_pageLabel setText:text];
    [_slider setValue:ratio];
    
    }

@end
