/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */

#import "WXCycleSliderComponent.h"
#import "WXIndicatorComponent.h"
#import "WXComponent_internal.h"
#import "NSTimer+Weex.h"
#import "WXSDKManager.h"
#import "WXUtility.h"
#import "WXComponent+Layout.h"
#import "WXComponent+Events.h"

typedef NS_ENUM(NSInteger, Direction) {
    DirectionNone = 1 << 0,
    DirectionLeft = 1 << 1,
    DirectionRight = 1 << 2
};

@class WXRecycleSliderView;
@class WXIndicatorView;

@protocol WXRecycleSliderViewDelegate <UIScrollViewDelegate>

- (void)recycleSliderView:(WXRecycleSliderView *)recycleSliderView didScroll:(UIScrollView *)scrollView;
- (void)recycleSliderView:(WXRecycleSliderView *)recycleSliderView didScrollToItemAtIndex:(NSInteger)index;
- (void)scrollViewWillBeginDragging:(UIScrollView *)scrollView;
- (void)scrollViewDidEndDragging:(UIScrollView *)scrollView willDecelerate:(BOOL)decelerate;
- (BOOL)requestGestureShouldStopPropagation:(UIGestureRecognizer *)gestureRecognizer shouldReceiveTouch:(UITouch *)touch;

@end


@interface WXRecycleSliderView : UIView <UIScrollViewDelegate>

@property (nonatomic, strong) WXIndicatorView *indicator;
@property (nonatomic, weak) id<WXRecycleSliderViewDelegate> delegate;
@property (nonatomic, strong) WXRecycleSliderScrollView *scrollView;
@property (nonatomic, strong) NSMutableArray *itemViews;
@property (nonatomic, assign) Direction direction;
@property (nonatomic, assign) NSInteger currentIndex;
@property (nonatomic, assign) NSInteger nextIndex;
@property (nonatomic, assign) CGRect currentItemFrame;
@property (nonatomic, assign) CGRect nextItemFrame;
@property (nonatomic, assign) BOOL infinite;

- (void)insertItemView:(UIView *)view atIndex:(NSInteger)index;
- (void)removeItemView:(UIView *)view;

@end

@implementation WXRecycleSliderView

- (id)initWithFrame:(CGRect)frame
{
    self = [super initWithFrame:frame];
    if (self) {
        _currentIndex = 0;
        _itemViews = [[NSMutableArray alloc] init];
        _scrollView = [[WXRecycleSliderScrollView alloc] init];
        if (@available(iOS 11.0, *)) {
            _scrollView.contentInsetAdjustmentBehavior = UIScrollViewContentInsetAdjustmentNever;
        }
        _scrollView.backgroundColor = [UIColor clearColor];
        _scrollView.delegate = self;
        _scrollView.showsHorizontalScrollIndicator = NO;
        _scrollView.showsVerticalScrollIndicator = NO;
        _scrollView.scrollsToTop = NO;
        [self addSubview:_scrollView];
    }
    return self;
}

- (void)dealloc
{
    if (_scrollView) {
        _scrollView.delegate = nil;
    }
}

- (void)layoutSubviews
{
    [super layoutSubviews];
    [self resetAllViewsFrame];
}

- (void)accessibilityDecrement
{
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Warc-performSelector-leaks"
    [self.wx_component performSelector:NSSelectorFromString(@"resumeAutoPlay:") withObject:@(false)];
#pragma clang diagnostic pop
    
    [self nextPage];
}

- (void)accessibilityIncrement
{
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Warc-performSelector-leaks"
    [self.wx_component performSelector:NSSelectorFromString(@"resumeAutoPlay:") withObject:@(false)];
#pragma clang diagnostic pop
    
    [self lastPage];
}

- (void)accessibilityElementDidLoseFocus
{
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Warc-performSelector-leaks"
    [self.wx_component performSelector:NSSelectorFromString(@"resumeAutoPlay:") withObject:@(true)];
#pragma clang diagnostic pop
}

#pragma mark Private Methods
- (CGFloat)height {
    return self.frame.size.height;
}

- (CGFloat)width {
    return self.frame.size.width;
}

- (UIView *)getItemAtIndex:(NSInteger)index
{
    if (self.itemViews.count > index) {
        return [self.itemViews objectAtIndex:index];
    }else{
        return nil;
    }
}

- (void)setCurrentIndex:(NSInteger)currentIndex
{
    if (currentIndex >= _itemViews.count || currentIndex < 0) {
        currentIndex = 0;
    }
    NSInteger oldIndex = _currentIndex;
    _currentIndex = currentIndex;
    if (_infinite) {
        if (_direction == DirectionRight) {
            self.nextItemFrame = CGRectMake(0, 0, self.width, self.height);
            self.nextIndex = self.currentIndex - 1;
            if (self.nextIndex < 0)
            {
                self.nextIndex = _itemViews.count - 1;
            }
        }else if (_direction == DirectionLeft) {
            self.nextItemFrame = CGRectMake(self.width * 2, 0, self.width, self.height);
            self.nextIndex = _itemViews.count?(self.currentIndex + 1) % _itemViews.count:0;
        }else {
            self.nextIndex = _itemViews.count?(self.currentIndex + 1) % _itemViews.count:0;
        }
        [self resetAllViewsFrame];
    } else {
        [_scrollView setContentOffset:CGPointMake(_currentIndex * self.width, 0) animated:YES];
    }
    [self resetIndicatorPoint];
    if (self.delegate && [self.delegate respondsToSelector:@selector(recycleSliderView:didScrollToItemAtIndex:)]) {
        if (oldIndex != _currentIndex) {
            [self.delegate recycleSliderView:self didScrollToItemAtIndex:_currentIndex];
        }
    }
}

- (void)resetIndicatorPoint
{
    [self.indicator setPointCount:self.itemViews.count];
    [self.indicator setCurrentPoint:_currentIndex];
}

#pragma mark  Scroll & Frames
- (void)setDirection:(Direction)direction {
    if (_direction == direction) return;
    _direction = direction;
    if (_direction == DirectionNone) return;
    if (_direction == DirectionRight) {
        self.nextItemFrame = CGRectMake(0, 0, self.width, self.height);
        self.nextIndex = self.currentIndex - 1;
        if (self.nextIndex < 0)
        {
            self.nextIndex = _itemViews.count - 1;
        }
        UIView *view = [self getItemAtIndex:_nextIndex];
        if (view) {
            view.frame = _nextItemFrame;
        }
    }else if (_direction == DirectionLeft){
        self.nextItemFrame = CGRectMake(self.width * 2, 0, self.width, self.height);
        self.nextIndex = _itemViews.count?(self.currentIndex + 1) % _itemViews.count:0;
        UIView *view = [self getItemAtIndex:_nextIndex];
        if (view) {
            view.frame = _nextItemFrame;
        }
    }
}

- (void)resetAllViewsFrame
{
    if (_infinite && _itemViews.count > 1) {
        self.scrollView.frame = CGRectMake(0, 0, self.width, self.height);
        self.scrollView.contentOffset = CGPointMake(self.width, 0);
        if (self.itemViews.count > 1) {
            self.scrollView.contentSize = CGSizeMake(self.width * 3, 0);
        } else {
            self.scrollView.contentSize = CGSizeZero;
        }
        _currentItemFrame = CGRectMake(self.width, 0, self.width, self.height);
        for (int i = 0; i < self.itemViews.count; i++) {
            UIView *view = [self.itemViews objectAtIndex:i];
            if (i != self.currentIndex) {
                view.frame = CGRectMake(self.frame.size.width * 3, 0, self.width, self.height);;
            }
        }
        [self getItemAtIndex:_currentIndex].frame = _currentItemFrame;
        if (_itemViews.count == 2) {
            _nextItemFrame = CGRectMake(self.width * 2, 0, self.width, self.height);
            [self getItemAtIndex:_nextIndex].frame = _nextItemFrame;
        }
    } else {
        self.scrollView.frame = self.bounds;
        self.scrollView.contentSize = CGSizeMake(self.width * _itemViews.count, self.height);
        self.scrollView.contentOffset = CGPointMake(_currentIndex * self.width, 0);
        for (int i = 0; i < _itemViews.count; i ++) {
            UIView *view = [_itemViews objectAtIndex:i];
            view.frame = CGRectMake(i * self.width, 0, self.width, self.height);
        }
        [self.scrollView setContentOffset:CGPointMake(_currentIndex * self.width, 0) animated:NO];
    }
    [self resetIndicatorPoint];
}

- (void)nextPage {
    if (_itemViews.count > 1) {
        if (_infinite) {
            [self.scrollView setContentOffset:CGPointMake(self.width * 2, 0) animated:YES];
        } else {
            // the currentindex will be set at the end of animation
            NSInteger nextIndex = self.currentIndex + 1;
            if(nextIndex < _itemViews.count) {
                [self.scrollView setContentOffset:CGPointMake(nextIndex * self.width, 0) animated:YES];
            }
        }
    }
}

- (void)lastPage
{
    NSInteger lastIndex = [self currentIndex]-1;
    if (_itemViews.count > 1) {
        if (_infinite) {
            if (lastIndex < 0) {
                lastIndex = [_itemViews count]-1;
            }
        }
        [self setCurrentIndex:lastIndex];
    }
}

- (void)resetScrollView
{
    if (WXFloatEqual(self.scrollView.contentOffset.x / self.width , 1.0))
    {
        return;
    }
    [self setCurrentIndex:self.nextIndex];
    self.scrollView.contentOffset = CGPointMake(self.width, 0);
}

#pragma mark Public Methods

- (void)setIndicator:(WXIndicatorView *)indicator
{
    _indicator = indicator;
    [_indicator setPointCount:self.itemViews.count];
    [_indicator setCurrentPoint:_currentIndex];
}

- (void)insertItemView:(UIView *)view atIndex:(NSInteger)index
{
    if (![self.itemViews containsObject:view]) {
        view.tag = self.itemViews.count;
        if (index < 0) {
            [self.itemViews addObject:view];
        } else {
            [self.itemViews insertObject:view atIndex:index];
        }
    }
    
    if (![self.scrollView.subviews containsObject:view]) {
        if (index < 0) {
            [self.scrollView addSubview:view];
        } else {
            [self.scrollView insertSubview:view atIndex:index];
        }
    }
    [self layoutSubviews];
    [self setCurrentIndex:_currentIndex];
}

- (void)removeItemView:(UIView *)view
{
    if ([self.itemViews containsObject:view]) {
        [self.itemViews removeObject:view];
    }
    
    if ([self.scrollView.subviews containsObject:view]) {
        [view removeFromSuperview];
    }
    [self layoutSubviews];
    [self setCurrentIndex:_currentIndex];
}

#pragma mark ScrollView Delegate

- (void)scrollViewDidScroll:(UIScrollView *)scrollView
{
    if (_infinite) {
        CGFloat offX = scrollView.contentOffset.x;
        self.direction = offX > self.width ? DirectionLeft : offX < self.width ? DirectionRight : DirectionNone;
    }
    if (self.delegate && [self.delegate respondsToSelector:@selector(recycleSliderView:didScroll:)]) {
        [self.delegate recycleSliderView:self didScroll:self.scrollView];
    }
}

- (void)scrollViewWillBeginDragging:(UIScrollView *)scrollView
{
    if (self.delegate && [self.delegate respondsToSelector:@selector(scrollViewWillBeginDragging:)]) {
        [self.delegate scrollViewWillBeginDragging:self.scrollView];
    }
}

- (void)scrollViewDidEndDragging:(UIScrollView *)scrollView willDecelerate:(BOOL)decelerate
{
    if (self.delegate && [self.delegate respondsToSelector:@selector(scrollViewDidEndDragging: willDecelerate:)]) {
        [self.delegate scrollViewDidEndDragging:self.scrollView willDecelerate:decelerate];
    }
}

- (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView {
    if (_infinite) {
        [self resetScrollView];
    } else {
        NSInteger index = _scrollView.contentOffset.x / self.width;
        [self setCurrentIndex:index];
    }
}

- (void)scrollViewDidEndScrollingAnimation:(UIScrollView *)scrollView {
    if (_infinite) {
        [self resetScrollView];
    } else {
        NSInteger index = _scrollView.contentOffset.x / self.width;
        [self setCurrentIndex:index];
    }
}

@end

@interface WXCycleSliderComponent () <WXRecycleSliderViewDelegate,WXIndicatorComponentDelegate>

@property (nonatomic, strong) WXRecycleSliderView *recycleSliderView;
@property (nonatomic, strong) NSTimer *autoTimer;
@property (nonatomic, assign) NSInteger currentIndex;
@property (nonatomic, assign) BOOL  autoPlay;
@property (nonatomic, assign) NSUInteger interval;
@property (nonatomic, assign) NSInteger index;
@property (nonatomic, assign) CGFloat lastOffsetXRatio;
@property (nonatomic, assign) CGFloat offsetXAccuracy;
@property (nonatomic, assign) BOOL  sliderChangeEvent;
@property (nonatomic, assign) BOOL  sliderScrollEvent;
@property (nonatomic, assign) BOOL  sliderScrollStartEvent;
@property (nonatomic, assign) BOOL  sliderScrollEndEvent;
@property (nonatomic, assign) BOOL  sliderStartEventFired;
@property (nonatomic, strong) NSMutableArray *childrenView;
@property (nonatomic, assign) BOOL scrollable;
@property (nonatomic, assign) BOOL infinite;

@end

@implementation WXCycleSliderComponent

- (void) dealloc
{
    [self _stopAutoPlayTimer];
}

- (instancetype)initWithRef:(NSString *)ref type:(NSString *)type styles:(NSDictionary *)styles attributes:(NSDictionary *)attributes events:(NSArray *)events weexInstance:(WXSDKInstance *)weexInstance
{
    if (self = [super initWithRef:ref type:type styles:styles attributes:attributes events:events weexInstance:weexInstance]) {
        _sliderChangeEvent = NO;
        _sliderScrollEvent = NO;
        _interval = 3000;
        _childrenView = [NSMutableArray new];
        _lastOffsetXRatio = 0;
        
        if (attributes[@"autoPlay"]) {
            _autoPlay = [WXConvert BOOL:attributes[@"autoPlay"]];
        }
        
        if (attributes[@"interval"]) {
            _interval = [WXConvert NSInteger:attributes[@"interval"]];
        }
        
        if (attributes[@"index"]) {
            _index = [WXConvert NSInteger:attributes[@"index"]];
        }
        _scrollable = attributes[@"scrollable"] ? [WXConvert BOOL:attributes[@"scrollable"]] : YES;
        if (attributes[@"offsetXAccuracy"]) {
            _offsetXAccuracy = [WXConvert CGFloat:attributes[@"offsetXAccuracy"]];
        }
        _infinite = attributes[@"infinite"] ? [WXConvert BOOL:attributes[@"infinite"]] : YES;
        self.flexCssNode->setFlexDirection(WeexCore::kFlexDirectionRow,NO);
    }
    return self;
}

- (UIView *)loadView
{
    return [[WXRecycleSliderView alloc] init];
}

- (void)viewDidLoad
{
    [super viewDidLoad];
    
    _recycleSliderView = (WXRecycleSliderView *)self.view;
    _recycleSliderView.delegate = self;
    _recycleSliderView.scrollView.pagingEnabled = YES;
    _recycleSliderView.exclusiveTouch = YES;
    _recycleSliderView.scrollView.scrollEnabled = _scrollable;
    _recycleSliderView.infinite = _infinite;
    UIAccessibilityTraits traits = UIAccessibilityTraitAdjustable;
    if (_autoPlay) {
        traits |= UIAccessibilityTraitUpdatesFrequently;
        [self _startAutoPlayTimer];
    } else {
        [self _stopAutoPlayTimer];
    }
     _recycleSliderView.accessibilityTraits = traits;
}

- (void)layoutDidFinish
{
    _recycleSliderView.currentIndex = _index;
}

- (void)viewDidUnload
{
    [_childrenView removeAllObjects];
}

- (void)insertSubview:(WXComponent *)subcomponent atIndex:(NSInteger)index
{
    if (subcomponent->_positionType == WXPositionTypeFixed) {
        [self.weexInstance.rootView addSubview:subcomponent.view];
        return;
    }
    
    // use _lazyCreateView to forbid component like cell's view creating
    if(_lazyCreateView) {
        subcomponent->_lazyCreateView = YES;
    }
    
    if (!subcomponent->_lazyCreateView || (self->_lazyCreateView && [self isViewLoaded])) {
        UIView *view = subcomponent.view;
        
        if(index < 0) {
            [self.childrenView addObject:view];
        }
        else {
            [self.childrenView insertObject:view atIndex:index];
        }
        
        WXRecycleSliderView *recycleSliderView = (WXRecycleSliderView *)self.view;
        if ([view isKindOfClass:[WXIndicatorView class]]) {
            ((WXIndicatorComponent *)subcomponent).delegate = self;
            [recycleSliderView addSubview:view];
            [self setIndicatorView:(WXIndicatorView *)view];
            return;
        }
        
        subcomponent.isViewFrameSyncWithCalculated = NO;
        
        if (index == -1) {
            [recycleSliderView insertItemView:view atIndex:index];
        } else {
            NSInteger offset = 0;
            for (int i = 0; i < [self.childrenView count]; ++i) {
                if (index == i) break;
                
                if ([self.childrenView[i] isKindOfClass:[WXIndicatorView class]]) {
                    offset++;
                }
            }
            [recycleSliderView insertItemView:view atIndex:index - offset];
            
            // check if should apply current contentOffset
            // in case inserting subviews after layoutDidFinish
            if (index-offset == _index && _index>0) {
                recycleSliderView.currentIndex = _index;
            }
        }
        [recycleSliderView layoutSubviews];
    }
}

- (void)willRemoveSubview:(WXComponent *)component
{
    UIView *view = component.view;
    
    if(self.childrenView && [self.childrenView containsObject:view]) {
        [self.childrenView removeObject:view];
    }
    
    WXRecycleSliderView *recycleSliderView = (WXRecycleSliderView *)_view;
    [recycleSliderView removeItemView:view];
    [recycleSliderView setCurrentIndex:0];
}

- (void)updateAttributes:(NSDictionary *)attributes
{
    if (attributes[@"autoPlay"]) {
        _autoPlay = [WXConvert BOOL:attributes[@"autoPlay"]];
        if (_autoPlay) {
            [self _startAutoPlayTimer];
        } else {
            [self _stopAutoPlayTimer];
        }
    }
    
    if (attributes[@"interval"]) {
        _interval = [WXConvert NSInteger:attributes[@"interval"]];
        [self _stopAutoPlayTimer];
        
        if (_autoPlay) {
            [self _startAutoPlayTimer];
        } 
    }
    
    if (attributes[@"index"]) {
        _index = [WXConvert NSInteger:attributes[@"index"]];
        self.currentIndex = _index;
        self.recycleSliderView.currentIndex = _index;
    }
    
    if (attributes[@"scrollable"]) {
        _scrollable = attributes[@"scrollable"] ? [WXConvert BOOL:attributes[@"scrollable"]] : YES;
        ((WXRecycleSliderView *)self.view).scrollView.scrollEnabled = _scrollable;
    }
    
    if (attributes[@"offsetXAccuracy"]) {
        _offsetXAccuracy = [WXConvert CGFloat:attributes[@"offsetXAccuracy"]];
    }
    if (attributes[@"infinite"]) {
        _infinite = [WXConvert BOOL:attributes[@"infinite"]];
    }
}

- (void)addEvent:(NSString *)eventName
{
    if ([eventName isEqualToString:@"change"]) {
        _sliderChangeEvent = YES;
    }
    if ([eventName isEqualToString:@"scroll"]) {
        _sliderScrollEvent = YES;
    }
}

- (void)removeEvent:(NSString *)eventName
{
    if ([eventName isEqualToString:@"change"]) {
        _sliderChangeEvent = NO;
    }
    if ([eventName isEqualToString:@"scroll"]) {
        _sliderScrollEvent = NO;
    }
}

- (BOOL)requestGestureShouldStopPropagation:(UIGestureRecognizer *)gestureRecognizer shouldReceiveTouch:(UITouch *)touch
{
    return [self gestureShouldStopPropagation:gestureRecognizer shouldReceiveTouch:touch];
}

#pragma mark WXIndicatorComponentDelegate Methods

-(void)setIndicatorView:(WXIndicatorView *)indicatorView
{
    NSAssert(_recycleSliderView, @"");
    [_recycleSliderView setIndicator:indicatorView];
}

- (void)resumeAutoPlay:(id)resume
{
    if (_autoPlay) {
        if ([resume boolValue]) {
            [self _startAutoPlayTimer];
        } else {
            [self _stopAutoPlayTimer];
        }
    }
}

#pragma mark Private Methods

- (void)_startAutoPlayTimer
{
    if (!self.autoTimer || ![self.autoTimer isValid]) {
        __weak __typeof__(self) weakSelf = self;
        self.autoTimer = [NSTimer wx_scheduledTimerWithTimeInterval:_interval/1000.0f block:^() {
            [weakSelf _autoPlayOnTimer];
        } repeats:YES];
        [[NSRunLoop currentRunLoop] addTimer:self.autoTimer forMode:NSRunLoopCommonModes];
    }
}

- (void)_stopAutoPlayTimer
{
    if (self.autoTimer && [self.autoTimer isValid]) {
        [self.autoTimer invalidate];
        self.autoTimer = nil;
    }
}

- (void)_autoPlayOnTimer
{
    if (!_infinite && (_currentIndex == _recycleSliderView.itemViews.count - 1)) {
        [self _stopAutoPlayTimer];
    }else {
        [self.recycleSliderView nextPage];
    }
}

#pragma mark ScrollView Delegate

- (void)recycleSliderView:(WXRecycleSliderView *)recycleSliderView didScroll:(UIScrollView *)scrollView
{
    if (_sliderScrollEvent) {
        CGFloat width = scrollView.frame.size.width;
        CGFloat XDeviation = 0;
        if (_infinite) {
            XDeviation = - (scrollView.contentOffset.x - width);
        } else {
            XDeviation = - (scrollView.contentOffset.x - width * _currentIndex);
        }
        CGFloat offsetXRatio = (XDeviation / width);
        if (fabs(offsetXRatio - _lastOffsetXRatio) >= _offsetXAccuracy) {
            _lastOffsetXRatio = offsetXRatio;
            [self fireEvent:@"scroll" params:@{@"offsetXRatio":[NSNumber numberWithFloat:offsetXRatio]} domChanges:nil];
        }
    }
}

- (void)recycleSliderView:(WXRecycleSliderView *)recycleSliderView didScrollToItemAtIndex:(NSInteger)index
{
    if (_sliderChangeEvent) {
        [self fireEvent:@"change" params:@{@"index":@(index)} domChanges:@{@"attrs": @{@"index": @(index)}}];
    }
    self.currentIndex = index;
}

- (void)scrollViewWillBeginDragging:(UIScrollView *)scrollView
{
    [self _stopAutoPlayTimer];
}

- (void)scrollViewDidEndDragging:(UIScrollView *)scrollView willDecelerate:(BOOL)decelerate
{
    if (_autoPlay) {
        [self _startAutoPlayTimer];
    }
}

@end

@implementation WXRecycleSliderScrollView
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldReceiveTouch:(UITouch *)touch
{
    WXRecycleSliderView *view = (WXRecycleSliderView *)self.delegate;
    if (![view isKindOfClass:[UIView class]]) {
        return YES;
    }
    
    if ([(id <WXRecycleSliderViewDelegate>) view.wx_component respondsToSelector:@selector(requestGestureShouldStopPropagation:shouldReceiveTouch:)]) {
        return [(id <WXRecycleSliderViewDelegate>) view.wx_component requestGestureShouldStopPropagation:gestureRecognizer shouldReceiveTouch:touch];
    }
    else{
        return YES;
    }
}
@end

