content: import React from 'react';
  import {BaseMixin, ElementaryMixin, ColorSchemaMixin, SectionMixin, Tools} from '../common/common.js';
  
  import Header from './panel-header.js';
  import Body from './panel-body.js';
  
  import './panel.less';
  
  export const Panel = React.createClass({
  
    //@@viewOn:mixins
    mixins: [
      BaseMixin,
      ElementaryMixin,
      ColorSchemaMixin,
      SectionMixin
    ],
    //@@viewOff:mixins
  
    //@@viewOn:statics
    statics: {
      tagName: 'UU5.Bricks.Panel',
      classNames: {
        main: 'uu5-bricks-panel panel',
        expanded: 'uu5-bricks-panel-expanded'
      },
      defaults: {
        parentTagName: 'UU5.Bricks.Accordion',
        header: 'noHeader',
        body: 'noBody'
      }
    },
    //@@viewOff:statics
  
    //@@viewOn:propTypes
    propTypes: {
      expanded: React.PropTypes.bool,
      alwaysExpanded: React.PropTypes.bool,
      glyphiconExpanded: React.PropTypes.string,
      glyphiconCollapsed: React.PropTypes.string,
      onClick: React.PropTypes.func,
      disableHeaderClick: React.PropTypes.bool
    },
    //@@viewOff:propTypes
  
    //@@viewOn:getDefaultProps
    getDefaultProps: function () {
      return {
        expanded: false,
        alwaysExpanded: false,
        glyphiconExpanded: null,
        glyphiconCollapsed: null,
        onClick: null,
        disableHeaderClick: false
      };
    },
    //@@viewOff:getDefaultProps
  
    //@@viewOn:standardComponentLifeCycle
    getInitialState: function () {
      return {
        expanded: this.props.alwaysExpanded || this.props.expanded
      };
    },
  
    componentWillReceiveProps: function (nextProps) {
      if (nextProps.controlled) {
        if (nextProps.alwaysExpanded) {
          !this.isExpanded() && this.setState({ expanded: true });
        } else if (nextProps.expanded !== this.props.expanded && nextProps.expanded !== this.isExpanded()) {
          // new expanded != this.props.expanded because if hide or disable accordion, default props to panel set again but state in panel can be different!!!
          this._setExpandedValue(nextProps, nextProps.expanded);
        }
      }
    },
    //@@viewOff:standardComponentLifeCycle
  
    //@@viewOn:interface
    setExpandedValue: function (expanded, setStateCallback) {
      this._setExpandedValue(this.props, expanded, setStateCallback);
      return this;
    },
  
    expand: function (setStateCallback) {
      this.setExpandedValue(true, setStateCallback);
      return this;
    },
  
    collapse: function (setStateCallback) {
      this.setExpandedValue(false, setStateCallback);
      return this;
    },
  
    toggle: function (setStateCallback) {
      if (this.isExpandable()) {
        this.setState(function (state) {
          return { expanded: !state.expanded };
        }, setStateCallback);
      }
      return this;
    },
  
    isExpanded: function () {
      return this.state.expanded;
    },
  
    isExpandable: function (props) {
      return !this.isDisabled() && !(props || this.props).alwaysExpanded;
    },
    //@@viewOff:interface
  
    //@@viewOn:overridingMethods
    buildHeaderChild_: function (headerTypes) {
      var headerType = this.getHeaderType(headerTypes);
  
      var headerChild;
      if (headerType === 'contentOfStandardHeader') {
        headerChild = <Header content={headerTypes.header} />;
        headerChild = this.cloneChild(headerChild, this.expandHeaderProps(headerChild));
      }
  
      return headerChild;
    },
  
    expandHeaderProps_: function (headerChild) {
      var headerProps = headerChild.props;
      var newProps = {};
  
      // default values is used if child is set as react element so null or undefined will not set!!!
      for (var key in headerProps) {
        headerProps[key] !== null && headerProps[key] !== undefined && (newProps[key] = headerProps[key]);
      }
  
      return Tools.merge(newProps, {
        key: newProps.id,
        _onClick: this._onClickToggle,
        _glyphicon: this.isExpanded() ? this.props.glyphiconExpanded : this.props.glyphiconCollapsed,
        _disableHeaderClick: this.props.disableHeaderClick
      });
    },
    //@@viewOff:overridingMethods
  
    //@@viewOn:componentSpecificHelpers
    _setExpandedValue: function (props, expanded, setStateCallback) {
      if (this.isExpandable(props)) {
        if (this.isExpanded() === expanded) {
          typeof setStateCallback === 'function' && setStateCallback();
        } else {
          this.setState({ expanded: expanded }, setStateCallback);
        }
      }
      return this;
    },
  
    _findChildByTagName: function (tagName) {
      var children = Array.isArray(this.props.children) ? this.props.children : [this.props.children];
  
      var result = children.filter(function (child) {
        return child.type && child.type.tagName === tagName;
      });
  
      return result[0] || null;
    },
  
    _onClickToggle(e) {
      var panel = this;
      this.toggle(() => {
        var onClick;
  
        if (typeof this.props.onClick === 'function') {
          onClick = () => panel.props.onClick(this);
        }
  
        if (onClick) {
          onClick(this);
        }
      });
      return this;
    },
  
    _getBodyId: function () {
      return this.getId() + '-body';
    },
  
    _getBodyChild: function () {
      var bodyContent = this.getContent();
      !this.props.children && !bodyContent && (bodyContent = this.getDefault().body);
  
      var bodyId = this._getBodyId();
  
      var bodyProps = {
        controlled: true,
        id: bodyId,
        key: bodyId,
        content: bodyContent,
        _expanded: this.isExpanded()
      };
  
      return this.buildChildren({
        children: React.createElement(Body, bodyProps, React.Children.toArray(this.props.children))
      });
    },
  
    _getBodyHeight: function () {
      return this.getRenderedChildById(this._getBodyId()).getFullHeight();
    },
  
    _checkParentTag() {
      return this.getParent() && (this.getParent().getTagName() === this.getDefault().parentTagName);
    },
    //@@viewOff:componentSpecificHelpers
  
    // Render
    _buildChildren: function () {
      var header = this.getHeader() || this.getDefault().header;
      var headerChild = this.buildHeaderChild({ header: header });
      var bodyChild = this._getBodyChild();
  
      return [headerChild, bodyChild];
    },
  
    //@@viewOn:render
    render: function () {
      var mainProps = this.buildMainAttrs();
      this.isExpanded() && (mainProps.className += ' ' + this.getClassName().expanded);
      return (
        <div {...mainProps}>
          {this._buildChildren()}
          {this.getDisabledCover()}
        </div>
  
      );
    }
    //@@viewOff:render
  });
  
  export default Panel;