//
//  CustomRadioGroup.m
//  JasonDevelop
//
//  Created by Jason Lee on 3/10/14.
//  Copyright (c) jasondevelop. All rights reserved.
//
@import ObjectiveC.runtime;
#import <stdarg.h>
#import "CustomRadioGroup.h"
#import "CommonUtil.h"
#import "ImageUtil.h"


@interface CustomRadioButton () {

}
@end

@implementation CustomRadioButton

@synthesize checked = _checked;

- (instancetype)initWithFrame:(CGRect)frame normalImage:(UIImage *)normalImage highlightImage:(UIImage *)highlightImage {//소스레벨에서 로드하는 경우, 초기화

    if (self = [super initWithFrame:frame]) {

        _normalImage = normalImage;
        _highlightImage = highlightImage;

        [self setImage:_normalImage forState:UIControlStateNormal];
        [self setImage:_highlightImage forState:UIControlStateHighlighted];

        [self.titleLabel setLineBreakMode:NSLineBreakByTruncatingTail];

        [self addTarget:self action:@selector(didRadioButtonTouched:) forControlEvents:UIControlEventTouchUpInside];
    }
    return self;
}

- (void)awakeFromNib {

    [super awakeFromNib];
    _normalImage = [self imageForState:UIControlStateNormal];
    _highlightImage = [self imageForState:UIControlStateHighlighted];

    _titleColorNormal = [self titleColorForState:UIControlStateNormal];
    _titleColorHighlight = [self titleColorForState:UIControlStateHighlighted] ? [self titleColorForState:UIControlStateHighlighted] : _titleColorNormal;

    [self.titleLabel setLineBreakMode:NSLineBreakByTruncatingTail];

    [self addTarget:self action:@selector(didRadioButtonTouched:) forControlEvents:UIControlEventTouchUpInside];
}

- (void)setChecked:(BOOL)checked {//
    _checked = checked;

	if (_checked) {
		[self setImage:_highlightImage forState:UIControlStateNormal];
        [self setTitleColor:_titleColorHighlight forState:UIControlStateNormal];
	} else {
		[self setImage:_normalImage forState:UIControlStateNormal];
        [self setTitleColor:_titleColorNormal forState:UIControlStateNormal];
	}

    if (_value) {
        objc_setAssociatedObject(_value, ksCustomRadioButtonStatus, [NSNumber numberWithBool:_checked], OBJC_ASSOCIATION_COPY_NONATOMIC);
    }
}

- (BOOL)getRadioStatusFromValue {
    BOOL isChecked = NO;
    if (_value) {
        isChecked = [objc_getAssociatedObject(_value, ksCustomRadioButtonStatus) boolValue];
    }
    return isChecked;
}

- (void)didRadioButtonTouched:(id)sender {

    if (self.delegate) {
        self.checked = !self.checked;
    }

    if ([self.delegate respondsToSelector:@selector(didCheckRadioButton:)]) {
        [self.delegate didCheckRadioButton:self];
    }
}

@end

@interface CustomBgRadioButton () {
//    UIImage *_bgNormalImage, *_bgHighlightImage;
//    UIEdgeInsets _bgInsets;
}

@end

#define kfRoundWidth 1.0f

@implementation CustomBgRadioButton
@dynamic checked;

- (instancetype)initWithFrame:(CGRect)frame bgNormalImage:(UIImage *)bgNormalImage bgHighlightImage:(UIImage *)bgHighlightImage rectForCapBg:(CGRect)rectForCapBg {

    if (self = [super initWithFrame:frame]) {

        _bgNormalImage = bgNormalImage;
        _bgHighlightImage = bgHighlightImage;
        _rectForCapBg = rectForCapBg;

        [self setBackgroundImage:_bgNormalImage forState:UIControlStateNormal];
        [self setBackgroundImage:_bgHighlightImage forState:UIControlStateHighlighted];

        [self setImage:_normalImage forState:UIControlStateNormal];
        [self setImage:_highlightImage forState:UIControlStateHighlighted];

        if (!CGRectEqualToRect(_rectForCapBg, CGRectZero)) {//rectForCap이 설정된 경우, 이미지를 리사이즈함.

            CGFloat top, left, bottom, right;
            top = CGRectGetMinY(_rectForCapBg);
            left = CGRectGetMinX(_rectForCapBg);
            bottom = CGRectGetHeight(_rectForCapBg);
            right = CGRectGetWidth(_rectForCapBg);

            _bgInsets = UIEdgeInsetsMake(top, left, bottom, right);

            [self setBackgroundImageStretchForState:UIControlStateNormal capInsets:_bgInsets];
            [self setBackgroundImageStretchForState:UIControlStateHighlighted capInsets:_bgInsets];

        } else {//rectForCap이 설정되지 않은 경우, 픽스된 사이즈로 이미지를 리사이즈함.

            _bgInsets = UIEdgeInsetsMake(kfRoundWidth, kfRoundWidth, kfRoundWidth, kfRoundWidth);

            [self setBackgroundImageStretchForState:UIControlStateNormal capInsets:_bgInsets];
            [self setBackgroundImageStretchForState:UIControlStateHighlighted capInsets:_bgInsets];
        }

        [self addTarget:self action:@selector(didRadioButtonTouched:) forControlEvents:UIControlEventTouchUpInside];
    }
    return self;
}

- (void)setBackgroundImageStretchForState:(UIControlState)state capInsets:(UIEdgeInsets)insets {

    UIImage *bimage = [self backgroundImageForState:state];
    bimage = [ImageUtil resizableImageWithCapInsets:insets resizingMode:UIImageResizingModeStretch img:bimage];
    [super setBackgroundImage:bimage forState:state];
}

- (void)awakeFromNib {

    _bgNormalImage = [self backgroundImageForState:UIControlStateNormal];
    _bgHighlightImage = [self backgroundImageForState:UIControlStateHighlighted];

    _normalImage = [self imageForState:UIControlStateNormal];
    _highlightImage = [self imageForState:UIControlStateHighlighted];

    _titleColorNormal = [self titleColorForState:UIControlStateNormal];
    _titleColorHighlight = [self titleColorForState:UIControlStateHighlighted] ? [self titleColorForState:UIControlStateHighlighted] : _titleColorNormal;

    if (!CGRectEqualToRect(_rectForCapBg, CGRectZero)) {//rectForCap이 설정된 경우, 이미지를 리사이즈함.

        CGFloat top, left, bottom, right;
        top = CGRectGetMinY(_rectForCapBg);
        left = CGRectGetMinX(_rectForCapBg);
        bottom = CGRectGetHeight(_rectForCapBg);
        right = CGRectGetWidth(_rectForCapBg);

        _bgInsets = UIEdgeInsetsMake(top, left, bottom, right);

        [self setBackgroundImageStretchForState:UIControlStateNormal capInsets:_bgInsets];
        [self setBackgroundImageStretchForState:UIControlStateHighlighted capInsets:_bgInsets];

    } else {//rectForCap이 설정되지 않은 경우, 픽스된 사이즈로 이미지를 리사이즈함.

        [self setBackgroundImageStretchForState:UIControlStateNormal capInsets:_bgInsets];
        [self setBackgroundImageStretchForState:UIControlStateHighlighted capInsets:_bgInsets];
    }

    [self addTarget:self action:@selector(didRadioButtonTouched:) forControlEvents:UIControlEventTouchUpInside];
}

- (void)setChecked:(BOOL)checked {
    _checked = checked;

    if (_checked) {
        [self setBackgroundImage:_bgHighlightImage forState:UIControlStateNormal];
        [self setTitleColor:_titleColorHighlight forState:UIControlStateNormal];

        if (_normalImage && _highlightImage) {
            [self setImage:_highlightImage forState:UIControlStateNormal];
            [self setImage:_normalImage forState:UIControlStateHighlighted];
        }

    } else {
        [self setBackgroundImage:_bgNormalImage forState:UIControlStateNormal];
        [self setTitleColor:_titleColorNormal forState:UIControlStateNormal];

        if (_normalImage && _highlightImage) {
            [self setImage:_normalImage forState:UIControlStateNormal];
            [self setImage:_highlightImage forState:UIControlStateHighlighted];
        }
    }

    [self setBackgroundImageStretchForState:UIControlStateNormal capInsets:_bgInsets];
    [self setBackgroundImageStretchForState:UIControlStateHighlighted capInsets:_bgInsets];

    if (self.value) {
        objc_setAssociatedObject(self.value, ksCustomRadioButtonStatus, [NSNumber numberWithBool:self.checked], OBJC_ASSOCIATION_COPY_NONATOMIC);
    }
}


@end

@interface CustomRadioGroup () {
    NSMutableArray *_btns;
    CustomRadioButton *_btnChecked;
    UIImage *_imageNormal, *_imageHighlight, *_bgImageNormal, *_bgImageHighlight;
    BOOL _isFirstLoading;
}

@end

@implementation CustomRadioGroup

- (id)init {
    if (self = [super init]) {
        _btns = [NSMutableArray new];
        _isFirstLoading = YES;
    }
    return self;
}

- (id)initWithRadioButtons:(id)buttons, ... {//라디오 버튼 그룹을 만듬, 들어오는 버튼수만큰 멤버로 할당됨.
    if (self = [super init]) {


        if (buttons) {
            _btns = [NSMutableArray new];

            if ([buttons isKindOfClass:[CustomBgRadioButton class]]) {
//                _bgImageNormal = [UIImage imageNamed:@"tp_01_img_control_bg_black"];
//                _bgImageHighlight = [UIImage imageNamed:@"tp_01_img_control_bg_active"];

                [(UIButton *)buttons setBackgroundImage:_imageHighlight forState:UIControlStateHighlighted];

            } else if ([buttons isKindOfClass:[CustomBgRadioButton class]]) {

                _imageNormal = [UIImage imageNamed:@"common_radiobox_default"];
                _imageHighlight = [UIImage imageNamed:@"common_radiobox_checked"];

                [(UIButton *)buttons setImage:_imageHighlight forState:UIControlStateHighlighted];
            }

            [buttons addTarget:self action:@selector(someRadioButtonTouched:) forControlEvents:UIControlEventTouchUpInside];
            [_btns addObject:buttons];
            _btnChecked = buttons; //첫번째 버튼을 선택상태로
            _btnChecked.checked = YES;

            va_list args;
            va_start(args, buttons);

            while ((buttons = va_arg(args, id)) != nil) {//루프 - 버튼을 그룹에 추가함.
                if ([buttons isKindOfClass:[CustomRadioButton class]]) {
                    [buttons addTarget:self action:@selector(someRadioButtonTouched:) forControlEvents:UIControlEventTouchUpInside];
                    [_btns addObject:buttons];
                }
            }

            va_end(args);
        }
    }
    return self;
}

//Do not use in resusable table
- (void)addRadioButton:(CustomRadioButton *)button {//라디오 그룹에 버튼을 추가함.

    CustomRadioButton *lBtn = [_btns lastObject];


    if ([button isKindOfClass:[CustomBgRadioButton class]]) {
        if (lBtn == nil) {//첫번째 버튼
            if (_isFirstLoading) {
                _bgImageNormal = [button backgroundImageForState:UIControlStateNormal];
                _bgImageHighlight = [button backgroundImageForState:UIControlStateHighlighted];
                _isFirstLoading = NO;
            }

            [button setBackgroundImage:_bgImageHighlight forState:UIControlStateNormal];
            [button setBackgroundImage:_bgImageNormal forState:UIControlStateHighlighted];
            _btnChecked = button;
            _btnChecked.checked = YES;
        } else {
            [button setBackgroundImage:_bgImageNormal forState:UIControlStateNormal];
            [button setBackgroundImage:_bgImageHighlight forState:UIControlStateHighlighted];
        }
    } else if ([button isKindOfClass:[CustomRadioButton class]]) {
        if (lBtn == nil) {//첫번째 버튼
            if (_isFirstLoading) {
                _imageNormal = [button imageForState:UIControlStateNormal];
                _imageHighlight = [button imageForState:UIControlStateHighlighted];
                _isFirstLoading = NO;
            }

            [button setImage:_imageHighlight forState:UIControlStateNormal];
            [button setImage:_imageNormal forState:UIControlStateHighlighted];
            _btnChecked = button;
            _btnChecked.checked = YES;
        } else {
            [button setImage:_imageNormal forState:UIControlStateNormal];
            [button setImage:_imageHighlight forState:UIControlStateHighlighted];
        }
    }

    [button addTarget:self action:@selector(someRadioButtonTouched:) forControlEvents:UIControlEventTouchUpInside];
    [_btns addObject:button];
}

- (void)reset {
    [_btns removeAllObjects];
}

- (id)valueForChecked {//선택된 Object를 반환함.
    return _btnChecked.value;
}

- (id)titleForChecked {//선택된 타이틀을 반환함.
    return _btnChecked.titleLabel.text;
}

- (NSInteger)count {
    return _btns.count;
}

- (NSArray *)rdoBtns {
    return _btns;
}

- (void)someRadioButtonTouched:(id)sender {//특정 라디오버튼이 선택된 경우, 값을 설정함.
    if (_btnChecked == sender)
        return;

    CustomRadioButton *btnSender = (CustomRadioButton *)sender;

    for (CustomRadioButton *btn in _btns) {

        if ([btnSender isEqual:btn]) {
            _btnChecked = btnSender;
            _btnChecked.checked = YES;
        } else {
            btn.checked = NO;
        }
    }

    if ([self.delegate respondsToSelector:@selector(didSomeRadioButtonTouched:)]) {
        [self.delegate didSomeRadioButtonTouched:sender];
    }
}

@end


@interface CustomRadioReusableGroup () <CustomRadioButtonDelegate> {
    NSMutableArray *_valueArray;
}
@end

@implementation CustomRadioReusableGroup

- (instancetype)init {
    if (self = [super init]) {
        _valueArray = [[NSMutableArray alloc] init];
    }
    return self;
}

- (void)addRadioButton:(CustomRadioButton *)rbtn {

    if ([_valueArray containsObject:rbtn.value]) {//동일한 오브젝트에 대한 validate
        return;
    }

    rbtn.delegate = self;

    [_valueArray addObject:rbtn.value];
}

- (NSArray *)values {
    return _valueArray;
}


- (void)someRadioButtonTouched:(CustomRadioButton *)touchedRbtn {
    NSLog(@"%@", touchedRbtn.value);
    for (id avalue in _valueArray) {
        if ([touchedRbtn.value isEqual:avalue]) {
            touchedRbtn.checked = YES;
            continue;
        }

        if ([objc_getAssociatedObject(avalue, ksCustomRadioButtonStatus) boolValue]) {
            objc_setAssociatedObject(avalue, ksCustomRadioButtonStatus, [NSNumber numberWithBool:NO], OBJC_ASSOCIATION_COPY_NONATOMIC);
        }
    }

    [_tableView reloadData];

    if ([self.delegate respondsToSelector:@selector(didSomeReuableRadioButtonTouched:)]) {
        [self.delegate didSomeReuableRadioButtonTouched:touchedRbtn];
    }
}

- (void)reset {
    [_valueArray removeAllObjects];
}

- (id)valueForChecked {
    id resultValue = nil;
    for (id avalue in _valueArray) {

        if ([objc_getAssociatedObject(avalue, ksCustomRadioButtonStatus) boolValue]) {
            resultValue = avalue;
        }
    }
    return resultValue;
}


#pragma mark - CustomRadioButton Delegate
- (void)didCheckRadioButton:(id)sender {
    [self someRadioButtonTouched:sender];
}

@end

