'use strict';

Object.defineProperty(exports, "__esModule", {
    value: true
});

var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();

var _react = require('react');

var _react2 = _interopRequireDefault(_react);

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }

function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }

function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }

var Plank = function (_React$Component) {
    _inherits(Plank, _React$Component);

    function Plank(props) {
        _classCallCheck(this, Plank);

        // Cache when heights have been set at particular breakpoints. Don't execute the callback since the
        // parent will already have a cached value.
        // TODO -- This will need to be bypassed when new content comes in and height actually changes.

        var _this = _possibleConstructorReturn(this, Object.getPrototypeOf(Plank).call(this, props));

        _this.state = {
            plankWidth: null, // Cache the current width. Use to determine responsiveness.
            breakpointsRendered: {}
        };
        return _this;
    }

    /**
     * plankWidth doesn't get set here since the initial render will have no relevant data from the parent
     * plank container
     */


    _createClass(Plank, [{
        key: 'componentDidMount',
        value: function componentDidMount() {
            if (!this.props.children.props.hasImage) {
                this.handleHeightSet();
            }
        }
    }, {
        key: 'componentWillReceiveProps',
        value: function componentWillReceiveProps(nextProps) {
            // Indicates a responsive resize has occurred.
            if (this.state.plankWidth !== nextProps.plankWidth) {
                // console.log('[SINGLE PLANK INDEX ' + this.props.index + '] setting plank width to: ' + nextProps.plankWidth);
                this.setState({ plankWidth: nextProps.plankWidth });
                if (!this.state.breakpointsRendered[this.state.plankWidth]) {
                    if (this.props.handleLastPlank()) {
                        // console.log('[SINGLE PLANK INDEX ' + this.props.index + '] last hidden plank rendered');
                    };
                }
            }
        }

        /**
         * Determines when a responsive re-size has occurred. 
         */

    }, {
        key: 'componentDidUpdate',
        value: function componentDidUpdate(prevProps, prevState) {
            if (prevState.plankWidth === null) {
                return; // Do nothing when the component first loads.
            }

            if (prevState.plankWidth !== this.state.plankWidth) {
                if (!this.previouslyRendered()) {
                    this.updateBreakpointRenderings();
                    // console.log('[SINGLE PLANK INDEX ' + this.props.index + '] new width detected... sending new height to planks container...');
                    this.sendHeightToPlanksContainer();
                } else {
                    // console.log('[SINGLE PLANK INDEX ' + this.props.index + '] change in width detected. previously rendered. nothing to do here.');
                }
            }
        }

        /**
         * @return Boolean
         */

    }, {
        key: 'previouslyRendered',
        value: function previouslyRendered() {
            return this.state.breakpointsRendered[this.state.plankWidth] !== undefined;
        }
    }, {
        key: 'updateBreakpointRenderings',
        value: function updateBreakpointRenderings() {
            var updatedBreakpointRenderings = this.state.breakpointsRendered;

            updatedBreakpointRenderings[this.state.plankWidth] = true;
            this.setState({ breakpointsRendered: updatedBreakpointRenderings });
        }
    }, {
        key: 'handleHeightSet',
        value: function handleHeightSet() {
            var _this2 = this;

            window.requestAnimationFrame(function () {
                // console.log('[SINGLE PLANK INDEX ' + this.props.index + '] height being set (requestAnimationFrame)');
                // If we're here, this assumes that the height has not been previously set for this breakpoint/plank width.
                _this2.updateBreakpointRenderings();
                _this2.sendHeightToPlanksContainer();
            });
        }
    }, {
        key: 'sendHeightToPlanksContainer',
        value: function sendHeightToPlanksContainer() {
            this.props.updateChildHeight(this.props.index, this.elRef.offsetHeight);
        }
    }, {
        key: 'handleImageLoad',
        value: function handleImageLoad() {
            // console.log('[SINGLE PLANK INDEX ' + this.props.index + '] image loaded!');
            this.sendHeightToPlanksContainer();
        }

        /**
         * Same for now as this.handleImageLoad but we might want to do something different in the future e.g. hide the
         * broken image icon.
         */

    }, {
        key: 'handleImageLoadError',
        value: function handleImageLoadError() {
            // console.log('[SINGLE PLANK INDEX ' + this.props.index + '] error loading image');
            this.sendHeightToPlanksContainer();
        }

        /**
         * For optimization there are 3 general conditions for rendering invidivual planks:
         *      1. plank width is first set and visibility is hidden since height is unknown
         *      2. plank height has been set and our owner, <Planks />, has determined our position
         *      3. responsive re-size has occurred, potentially starting (1) and (2) over again unless cached
         */

    }, {
        key: 'render',
        value: function render() {
            var _this3 = this;

            // console.log('[SINGLE PLANK INDEX ' + this.props.index + '] single plank rendering...');
            // console.log('[SINGLE PLANK INDEX ' + this.props.index + '] visibility: ' + this.props.plankStyles.visibility);
            return _react2.default.createElement(
                'div',
                {
                    onLoad: this.handleImageLoad.bind(this),
                    onError: this.handleImageLoadError.bind(this),
                    className: 'plank',
                    style: this.props.plankStyles,
                    ref: function ref(c) {
                        return _this3.elRef = c;
                    }
                },
                this.props.children
            );
        }
    }]);

    return Plank;
}(_react2.default.Component);

exports.default = Plank;