import React, { Component } from 'react';
import { Animated, findNodeHandle, Image, StyleSheet, Text, TouchableHighlight, UIManager, View } from 'react-native';
const ACCORDION_PADDING_DEFAULT = 15;
const ACCORDION_ANIMATION_DURATION_DEFAULT = 200;
const ACCORDION_ARROW_ICON_DEFAULT = require('../../assets/images/arrow.png');
const ACCORDION_TITLE_HEIGHT_DEFAULT = 50;
const AccordionStyles = StyleSheet.create({
    container: {
        borderBottomColor: '#ccc',
        borderBottomWidth: StyleSheet.hairlineWidth
    },
    content: {
        overflow: 'hidden'
    },
    titleContainer: {
        flex: 1,
        flexDirection: 'row',
        alignItems: 'center'
    },
    title: {
        flex: 1
    },
    arrowImage: {
        width: 12,
        height: 20
    },
    plusMinus: {
        fontSize: 20,
        lineHeight: 20,
        fontWeight: 'bold'
    },
    iconImage: {
        width: 15,
        height: 15
    }
});
export class Accordion extends Component {
    constructor(props) {
        super(props);
        this.animateContent = (height, shouldOpen) => {
            if (this.shouldEnableAnimation()) {
                Animated.spring(this.state.contentHeightAnimation, {
                    bounciness: 0,
                    toValue: height
                }).start();
            }
            Animated.timing(this.state.arrowTranslateAnimation, {
                toValue: shouldOpen ? -90 : 90,
                duration: this.props.animationDuration || ACCORDION_ANIMATION_DURATION_DEFAULT,
                useNativeDriver: true
            }).start();
        };
        this.contentOnLayout = (event) => {
            if (!this.state.hasMeasured &&
                !this.state.isMeasuring &&
                this.state.isOpen) {
                this.state.contentHeightAnimation.setValue(event.nativeEvent.layout.height + this.state.padding.paddingLeft);
                this.setState({ hasMeasured: true });
            }
        };
        this.shouldEnableAnimation = () => {
            return !this.props.disableAnimation && !this.props.renderContent;
        };
        this.toggleAccordion = () => {
            const isCurrentlyOpen = this.state.isOpen;
            this.setState({
                isOpen: !isCurrentlyOpen
            });
            if (isCurrentlyOpen) {
                this.animateContent(0, false);
            }
            else {
                this.setState({ isMeasuring: true }, () => {
                    requestAnimationFrame(() => {
                        const node = findNodeHandle(this.contentView.current);
                        if (node) {
                            UIManager.measure(node, (x, y, width, height) => {
                                this.setState({
                                    isMeasuring: false,
                                    hasMeasured: true
                                });
                                this.animateContent(height + this.state.padding.paddingLeft, true);
                            });
                        }
                    });
                });
            }
        };
        this.contentView = React.createRef();
        this.state = {
            arrowTranslateAnimation: new Animated.Value(props.state === 'open' ? -90 : 90),
            contentHeightAnimation: new Animated.Value(0),
            isOpen: (props.state === 'open'),
            isMeasuring: false,
            hasMeasured: false,
            padding: {
                paddingLeft: props.padding || ACCORDION_PADDING_DEFAULT,
                paddingRight: props.padding || ACCORDION_PADDING_DEFAULT
            },
            titleTouchableHighlight: {
                height: props.titleHeight || ACCORDION_TITLE_HEIGHT_DEFAULT
            }
        };
    }
    static getDerivedStateFromProps(nextProps, prevState) {
        return {
            padding: {
                paddingLeft: nextProps.padding || ACCORDION_PADDING_DEFAULT,
                paddingRight: nextProps.padding || ACCORDION_PADDING_DEFAULT
            },
            titleTouchableHighlight: {
                height: nextProps.titleHeight || ACCORDION_TITLE_HEIGHT_DEFAULT
            }
        };
    }
    render() {
        let computedContentStyle;
        if (this.shouldEnableAnimation()) {
            if (this.state.isMeasuring) {
                computedContentStyle = { position: 'absolute', opacity: 0 };
            }
            else if (this.state.hasMeasured) {
                computedContentStyle = {
                    height: this.state.contentHeightAnimation
                };
            }
            else if (this.state.isOpen) {
                computedContentStyle = {};
            }
            else {
                computedContentStyle = { height: 0 };
            }
        }
        else {
            computedContentStyle = this.state.isOpen ? {} : { height: 0 };
        }
        return (<View style={[
            AccordionStyles.container,
            this.props.style,
            this.state.isOpen && this.props.openStyle
        ]}>
        <TouchableHighlight style={this.state.titleTouchableHighlight} underlayColor={this.props.titleUnderlayColor} onPress={this.toggleAccordion}>
          <View style={[
            AccordionStyles.titleContainer,
            this.state.padding,
            this.props.titleContainerStyle
        ]}>
            <View style={[
            AccordionStyles.title,
            this.props.titleStyle,
            this.state.isOpen && this.props.openTitleStyle
        ]}>
              {this.props.title}
            </View>
            {this.renderIcon()}
          </View>
        </TouchableHighlight>
        <Animated.View ref={this.contentView} style={[
            AccordionStyles.content,
            this.state.padding,
            this.props.contentStyle,
            computedContentStyle
        ]} onLayout={this.contentOnLayout}>
          <View>
            {this.props.content}
            {this.state.isOpen && this.props.renderContent && this.props.renderContent()}
          </View>
        </Animated.View>
      </View>);
    }
    renderIcon() {
        const { arrowIconImage, closedIconImage, closedIconStyle, iconFormat, openIconImage, openIconStyle } = this.props;
        if (iconFormat === 'arrow') {
            const computedArrowStyle = {
                transform: [
                    {
                        rotate: this.state.arrowTranslateAnimation.interpolate({
                            inputRange: [-90, 90],
                            outputRange: ['-90deg', '90deg']
                        })
                    }
                ]
            };
            return (<Animated.Image source={arrowIconImage || ACCORDION_ARROW_ICON_DEFAULT} style={[
                AccordionStyles.arrowImage,
                this.props.arrowIconStyle,
                computedArrowStyle
            ]}/>);
        }
        if (iconFormat === 'image'
            && (closedIconImage || openIconImage)) {
            const { isOpen } = this.state;
            const image = isOpen ? openIconImage : closedIconImage;
            const imageStyle = isOpen ? openIconStyle : closedIconStyle;
            if (image) {
                return (<Image source={image} style={[
                    AccordionStyles.iconImage,
                    imageStyle
                ]}/>);
            }
            else {
                return null;
            }
        }
        const icon = this.state.isOpen ? '–' : '+';
        return (<Text style={[AccordionStyles.plusMinus, this.props.plusMinusStyle]}>
        {icon}
      </Text>);
    }
}
Accordion.defaultProps = {
    titleUnderlayColor: '#eee'
};
//# sourceMappingURL=Accordion.js.map