//
//  CLResizeTool.m
//
//  Created by sho yakushiji on 2013/12/12.
//  Copyright (c) 2013年 CALACULU. All rights reserved.
//

#import "CLResizeTool.h"

static NSString* const kCLResizeToolPresetSizes = @"presetSizes";
static NSString* const kCLResizeToolLimitSize = @"limitSize";
static NSString* const kCLResizeToolHorizontalIconName = @"horizontalIconAssetsName";
static NSString* const kCLResizeToolVerticalIconName = @"verticalIconAssetsName";
static NSString* const kCLResizeToolChainOnIconName = @"chainOnIconAssetsName";
static NSString* const kCLResizeToolChainOffIconName = @"chainOffIconAssetsName";

@interface _CLResizePanel : UIView
<UITextFieldDelegate>
- (id)initWithFrame:(CGRect)frame originalSize:(CGSize)size tool:(CLResizeTool*)tool;
- (void)setImageWidth:(CGFloat)width;
- (void)setImageHeight:(CGFloat)height;
- (void)setLimitSize:(CGFloat)limit;
- (CGSize)imageSize;
@end


@implementation CLResizeTool
{
    UIImage *_originalImage;
    
    UIView *_menuContainer;
    CLToolbarMenuItem *_switchBtn;
    UIScrollView *_menuScroll;
    _CLResizePanel *_resizePanel;
}

+ (NSArray*)subtools
{
    return nil;
}

+ (NSString*)defaultTitle
{
    return [CLImageEditorTheme localizedString:@"CLResizeTool_DefaultTitle" withDefault:@"Resize"];
}

+ (BOOL)isAvailable
{
    return ([UIDevice iosVersion] >= 5.0);
}

+ (CGFloat)defaultDockedNumber
{
    return 5.5;
}

#pragma mark- optional info

+ (NSArray*)defaultPresetSizes
{
    return @[@240, @320, @480, @640, @800, @960, @1024, @2048];
}

+ (NSNumber*)defaultLimitSize
{
    return @3200;
}

+ (NSDictionary*)optionalInfo
{
    return @{
             kCLResizeToolPresetSizes:[self defaultPresetSizes],
             kCLResizeToolLimitSize:[self defaultLimitSize],
             kCLResizeToolHorizontalIconName:@"",
             kCLResizeToolVerticalIconName:@"",
             kCLResizeToolChainOnIconName:@"",
             kCLResizeToolChainOffIconName:@"",
             };
}

#pragma mark- implementation

- (void)setup
{
    _originalImage = self.editor.imageView.image;
    
    [self.editor fixZoomScaleWithAnimated:YES];
    
    _menuContainer = [[UIView alloc] initWithFrame:self.editor.menuView.frame];
    _menuContainer.backgroundColor = self.editor.menuView.backgroundColor;
    [self.editor.view addSubview:_menuContainer];
    
    _menuScroll = [[UIScrollView alloc] initWithFrame:CGRectMake(0, 0, _menuContainer.width - 70, _menuContainer.height)];
    _menuScroll.backgroundColor = [UIColor clearColor];
    _menuScroll.showsHorizontalScrollIndicator = NO;
    _menuScroll.clipsToBounds = NO;
    [_menuContainer addSubview:_menuScroll];
    
    UIView *btnPanel = [[UIView alloc] initWithFrame:CGRectMake(_menuScroll.right, 0, 70, _menuContainer.height)];
    btnPanel.backgroundColor = [_menuContainer.backgroundColor colorWithAlphaComponent:0.97];
    [_menuContainer addSubview:btnPanel];
    
    _switchBtn = [CLImageEditorTheme menuItemWithFrame:CGRectMake(0, 0, 70, btnPanel.height) target:self action:@selector(pushedSwitchBtn:) toolInfo:nil];
    _switchBtn.tag = 0;
	
    _switchBtn.iconImage = [self imageForKey:kCLResizeToolHorizontalIconName defaultImageName:@"btn_width.png"];
    [btnPanel addSubview:_switchBtn];
    
    NSNumber *limit = self.toolInfo.optionalInfo[kCLResizeToolLimitSize];
    if(limit==nil){ limit = [self.class defaultLimitSize]; }
    
    _resizePanel = [[_CLResizePanel alloc] initWithFrame:self.editor.imageView.superview.frame originalSize:_originalImage.size tool:self];
    _resizePanel.backgroundColor = [[CLImageEditorTheme toolbarColor] colorWithAlphaComponent:0.4];
    [_resizePanel setLimitSize:limit.floatValue];
    [self.editor.view addSubview:_resizePanel];
    
    [self setResizeMenu];
    
    _menuContainer.transform = CGAffineTransformMakeTranslation(0, self.editor.view.height-_menuScroll.top);
    [UIView animateWithDuration:kCLImageToolAnimationDuration
                     animations:^{
                         self->_menuContainer.transform = CGAffineTransformIdentity;
                     }];
}

- (void)cleanup
{
    [self.editor resetZoomScaleWithAnimated:YES];
    
    [_resizePanel endEditing:YES];
    [_resizePanel removeFromSuperview];
    
    [UIView animateWithDuration:kCLImageToolAnimationDuration
                     animations:^{
                         self->_menuContainer.transform = CGAffineTransformMakeTranslation(0, self.editor.view.height-self->_menuScroll.top);
                     }
                     completion:^(BOOL finished) {
                         [self->_menuContainer removeFromSuperview];
                     }];
}

- (void)executeWithCompletionBlock:(void (^)(UIImage *, NSError *, NSDictionary *))completionBlock
{
    CGSize size = _resizePanel.imageSize;
    
    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
        
        if(size.width>0 && size.height>0){
            UIImage *image = [self->_originalImage resize:size];
            
            dispatch_async(dispatch_get_main_queue(), ^{
                completionBlock(image, nil, nil);
            });
        }
        else{
            dispatch_async(dispatch_get_main_queue(), ^{
                completionBlock(nil, nil, nil);
            });
        }
    });
}

#pragma mark-

- (UIImage*)imageWithString:(NSString*)str
{
    UILabel *label = [[UILabel alloc] initWithFrame:CGRectMake(0, 0, 100, 100)];
    label.textAlignment = NSTextAlignmentCenter;
    label.text = str;
    label.font = [UIFont boldSystemFontOfSize:30];
    label.minimumScaleFactor = 0.5;
    
    label.backgroundColor = [[CLImageEditorTheme theme] toolbarTextColor];
    label.textColor = [[CLImageEditorTheme theme] toolbarColor];
    
    UIGraphicsBeginImageContextWithOptions(label.frame.size, NO, 0.0);
    [label.layer renderInContext:UIGraphicsGetCurrentContext()];
    UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();
    
    return image;
}

- (void)setResizeMenu
{
    CGFloat W = 70;
    CGFloat H = _menuScroll.height;
    CGFloat x = 0;
    
    NSArray *sizes = self.toolInfo.optionalInfo[kCLResizeToolPresetSizes];
    if(sizes==nil || ![sizes isKindOfClass:[NSArray class]] || sizes.count==0){
        sizes = [[self class] defaultPresetSizes];
    }
    
    for(NSNumber *size in sizes){
        CLToolbarMenuItem *view = [CLImageEditorTheme menuItemWithFrame:CGRectMake(x, 0, W, H) target:self action:@selector(tappedResizePanel:) toolInfo:nil];
        view.userInfo = @{@"size":size};
        view.iconImage = [self imageWithString:[NSString stringWithFormat:@"%@", size]];
        
        [_menuScroll addSubview:view];
        x += W;
    }
    _menuScroll.contentSize = CGSizeMake(MAX(x, _menuScroll.frame.size.width+1), 0);
}

- (void)pushedSwitchBtn:(UITapGestureRecognizer*)sender
{
    if(_switchBtn.tag==0){
        _switchBtn.tag = 1;
        _switchBtn.iconImage = [self imageForKey:kCLResizeToolVerticalIconName defaultImageName:@"btn_height.png"];
    }
    else{
        _switchBtn.tag = 0;
        _switchBtn.iconImage = [self imageForKey:kCLResizeToolHorizontalIconName defaultImageName:@"btn_width.png"];
    }
    
    _switchBtn.alpha = 0.2;
    [UIView animateWithDuration:kCLImageToolAnimationDuration
                     animations:^{
                         self->_switchBtn.alpha = 1;
                     }
     ];
}

- (void)tappedResizePanel:(UITapGestureRecognizer*)sender
{
    UIView *view = sender.view;
    
    NSNumber *size = view.userInfo[@"size"];
    if(size){
        if(_switchBtn.tag==0){
            [_resizePanel setImageWidth:size.floatValue];
        }
        else{
            [_resizePanel setImageHeight:size.floatValue];
        }
    }
    
    view.alpha = 0.2;
    [UIView animateWithDuration:kCLImageToolAnimationDuration
                     animations:^{
                         view.alpha = 1;
                     }
     ];
}

@end





@implementation _CLResizePanel
{
    UIView *_infoPanel;
    CGSize _originalSize;
    
    CGFloat _limitSize;
    UITextField *_fieldW;
    UITextField *_fieldH;
    
    UIButton *_chainBtn;
}

- (id)initWithFrame:(CGRect)frame
{
    self = [super initWithFrame:frame];
    if(self){
        _infoPanel = [[UIView alloc] initWithFrame:CGRectMake(0, 0, frame.size.width*0.85, 180)];
        _infoPanel.backgroundColor = [[CLImageEditorTheme toolbarColor] colorWithAlphaComponent:0.9];
        _infoPanel.layer.cornerRadius = 5;
        _infoPanel.center = CGPointMake(self.width/2, self.height/2);
        _infoPanel.autoresizingMask = UIViewAutoresizingFlexibleBottomMargin | UIViewAutoresizingFlexibleTopMargin;
        [self addSubview:_infoPanel];
        
        [self addGestureRecognizer:[[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(viewDidTap:)]];
        [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyBoardWillChange:) name:UIKeyboardWillShowNotification object:nil];
        [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyBoardWillChange:) name:UIKeyboardWillHideNotification object:nil];
    }
    return self;
}

- (void)dealloc
{
    [[NSNotificationCenter defaultCenter] removeObserver:self];
}

- (id)initWithFrame:(CGRect)frame originalSize:(CGSize)size tool:(CLResizeTool *)tool
{
    self = [self initWithFrame:frame];
    if(self){
        _originalSize = size;
        [self initInfoPanelWithTool:tool];
    }
    return self;
}

- (void)initInfoPanelWithTool:(CLResizeTool*)tool
{
    UIFont *font = [CLImageEditorTheme toolbarTextFont];
    
    CGFloat y = 0;
    UILabel *label = [[UILabel alloc] initWithFrame:CGRectMake(10, 5, _infoPanel.width-20, 30)];
	[label setTextColor:[CLImageEditorTheme toolbarTextColor]];
    label.backgroundColor = [UIColor clearColor];
    label.font = [font fontWithSize:17];
    
    label.text = [CLImageEditorTheme localizedString:@"CLResizeTool_InfoPanelTextOriginalSize" withDefault:@"Original Image Size:"];
    [_infoPanel addSubview:label];
    y = label.bottom;
    
    label = [[UILabel alloc] initWithFrame:CGRectMake(10, y, _infoPanel.width-20, 50)];
	[label setTextColor:[CLImageEditorTheme toolbarTextColor]];
    label.backgroundColor = [UIColor clearColor];
    label.font = [font fontWithSize:30];
    label.text = [NSString stringWithFormat:@"%ld x %ld", (long)_originalSize.width, (long)_originalSize.height];
    label.textAlignment = NSTextAlignmentCenter;
    [_infoPanel addSubview:label];
    //y = label.bottom;
    
    label = [[UILabel alloc] initWithFrame:CGRectMake(10, _infoPanel.height/2, _infoPanel.width-20, 30)];
	[label setTextColor:[CLImageEditorTheme toolbarTextColor]];
    label.backgroundColor = [UIColor clearColor];
    label.font = [font fontWithSize:17];
    label.text = [CLImageEditorTheme localizedString:@"CLResizeTool_InfoPanelTextNewSize" withDefault:@"New Image Size:"];
    [_infoPanel addSubview:label];
    y = label.bottom;
    /*
    label = [[UILabel alloc] initWithFrame:CGRectMake(10, y, _infoPanel.width-20, 50)];
    label.backgroundColor = [UIColor clearColor];
    label.font = [font fontWithSize:30];
    label.text = @"x";
    label.textAlignment = NSTextAlignmentCenter;
    [_infoPanel addSubview:label];
    */
    _chainBtn = [UIButton buttonWithType:UIButtonTypeCustom];
    _chainBtn.frame = CGRectMake(0, 0, 35, 35);
    _chainBtn.center = CGPointMake(label.center.x, y + 25);
	
    [_chainBtn setImage:[tool imageForKey:kCLResizeToolChainOffIconName defaultImageName:@"btn_chain_off.png"] forState:UIControlStateNormal];
    [_chainBtn setImage:[tool imageForKey:kCLResizeToolChainOnIconName defaultImageName:@"btn_chain_on.png"] forState:UIControlStateSelected];
    [_chainBtn addTarget:self action:@selector(chainBtnDidPush:) forControlEvents:UIControlEventTouchUpInside];
    _chainBtn.selected = YES;
    [_infoPanel addSubview:_chainBtn];
    
    _fieldW = [[UITextField alloc] initWithFrame:CGRectMake(_chainBtn.left - 110, y+5, 100, 40)];
	[_fieldW setTextColor:[CLImageEditorTheme toolbarTextColor]];
    _fieldW.font = [font fontWithSize:30];
    _fieldW.textAlignment = NSTextAlignmentCenter;
    _fieldW.keyboardType = UIKeyboardTypeNumberPad;
    _fieldW.layer.borderWidth = 1;
    _fieldW.layer.borderColor = [[[CLImageEditorTheme theme] toolbarTextColor] CGColor];
    _fieldW.text = [NSString stringWithFormat:@"%ld", (long)_originalSize.width];
    _fieldW.delegate = self;
    [_fieldW addTarget:self action:@selector(textFieldDidChanged:) forControlEvents:UIControlEventEditingChanged];
    [_infoPanel addSubview:_fieldW];
    
    _fieldH = [[UITextField alloc] initWithFrame:CGRectMake(_chainBtn.right + 10, y+5, 100, 40)];
	[_fieldH setTextColor:[CLImageEditorTheme toolbarTextColor]];
    _fieldH.font = [font fontWithSize:30];
    _fieldH.textAlignment = NSTextAlignmentCenter;
    _fieldH.keyboardType = UIKeyboardTypeNumberPad;
    _fieldH.layer.borderWidth = 1;
    _fieldH.layer.borderColor = _fieldW.layer.borderColor;
    _fieldH.text = [NSString stringWithFormat:@"%ld", (long)_originalSize.height];
    _fieldH.delegate = self;
    [_fieldH addTarget:self action:@selector(textFieldDidChanged:) forControlEvents:UIControlEventEditingChanged];
    [_infoPanel addSubview:_fieldH];
}

#pragma mark - gesture events

- (void)viewDidTap:(UITapGestureRecognizer*)sender
{
    [self endEditing:YES];
}

- (void)chainBtnDidPush:(UIButton*)sender
{
    sender.selected = !sender.selected;
    
    CGFloat W = _fieldW.text.floatValue;
    CGFloat H = _fieldH.text.floatValue;
    if(W>H){
        [self setImageWidth:W];
    }
    else{
        [self setImageHeight:H];
    }
}

#pragma mark - keyboard events

- (void)keyBoardWillChange:(NSNotification *)notificatioin
{
    CGRect keyboardFrame = [[notificatioin.userInfo objectForKey:UIKeyboardFrameEndUserInfoKey] CGRectValue];
    keyboardFrame = [self.superview convertRect:keyboardFrame fromView:self.window];
    
    UIViewAnimationCurve animationCurve = [[notificatioin.userInfo objectForKey:UIKeyboardAnimationCurveUserInfoKey] integerValue];
    double duration = [[notificatioin.userInfo objectForKey:UIKeyboardAnimationDurationUserInfoKey] doubleValue];
    
    [UIView animateWithDuration:duration
                          delay:0
                        options:UIViewAnimationOptionBeginFromCurrentState | (animationCurve<<16)
                     animations:^{
                         CGFloat H = MIN(self.height, keyboardFrame.origin.y - self.top);
                         self->_infoPanel.center = CGPointMake(self->_infoPanel.center.x, H/2);
                     } completion:^(BOOL finished) {
                         
                     }
     ];
}

#pragma mark- Size settings

- (void)setLimitSize:(CGFloat)limit
{
    _limitSize = limit;
    [self setImageWidth:_fieldW.text.floatValue];
}

- (void)setImageWidth:(CGFloat)width
{
    width = MIN(width, _limitSize);
    
    if(_chainBtn.selected){
        if(width>0){
            CGFloat height = MAX(1, width * _originalSize.height / _originalSize.width);
            
            if(height>_limitSize){
                [self setImageHeight:_limitSize];
            }
            else{
                _fieldW.text = [NSString stringWithFormat:@"%ld", (long)width];
                _fieldH.text = [NSString stringWithFormat:@"%ld", (long)height];
            }
        }
        else{
            _fieldH.text = @"";
        }
    }
    else if(width>0){
        _fieldW.text = [NSString stringWithFormat:@"%ld", (long)width];
    }
}

- (void)setImageHeight:(CGFloat)height
{
    height = MIN(height, _limitSize);
    
    if(_chainBtn.selected){
        if(height>0){
            CGFloat width = MAX(1, height * _originalSize.width / _originalSize.height);
            
            if(width>_limitSize){
                [self setImageWidth:_limitSize];
            }
            else{
                _fieldW.text = [NSString stringWithFormat:@"%ld", (long)width];
                _fieldH.text = [NSString stringWithFormat:@"%ld", (long)height];
            }
        }
        else{
            _fieldW.text = @"";
        }
    }
    else if(height>0){
        _fieldH.text = [NSString stringWithFormat:@"%ld", (long)height];
    }
}

- (void)textFieldDidChanged:(id)sender
{
    if(sender==_fieldW){
        [self setImageWidth:_fieldW.text.floatValue];
    }
    else if(sender==_fieldH){
        [self setImageHeight:_fieldH.text.floatValue];
    }
}

- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string
{
    if(textField==_fieldW || textField==_fieldH){
        if((string != nil) && (![@"" isEqualToString:string])){
            const char *c = [string cStringUsingEncoding:NSASCIIStringEncoding];
            if(c[0]==0){ return YES; }
            else if([textField.text length]>=4){ return NO; }
            else {return [self isNumber:string]; }
        }
    }
    return YES;
}

- (BOOL)isNumber:(NSString *)value
{
    if(value == nil || [@"" isEqualToString:value]){ return NO; }
    
    BOOL isNum = NO;
    
    for(int i=0; i<[value length]; i++){
        NSString *str = [[value substringFromIndex:i] substringToIndex:1];
        
        const char *c = [str cStringUsingEncoding:NSASCIIStringEncoding];
        isNum = ((c!=NULL)&&(c[0]>=0x30)&&(c[0]<=0x39));
        
        if(_fieldW.text.length==0 && i==0 && (c!=NULL&&c[0]==0x30)){ isNum = NO; }
        
        if(!isNum){ break; }
    }
    
    return isNum;
}

- (CGSize)imageSize
{
    __block CGSize size = CGSizeZero;
    
    safe_dispatch_sync_main(^{
        size = CGSizeMake(self->_fieldW.text.floatValue, self->_fieldH.text.floatValue);
    });
    return size;
}

@end

