// Copyright (c) 2018 Dominic Masters
//
// MIT License
//
// Permission is hereby granted, free of charge, to any person obtaining
// a copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to
// permit persons to whom the Software is furnished to do so, subject to
// the following conditions:
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

import React from 'react';
import { connect } from 'react-redux';
import { bindActionCreators } from 'redux';
import { CSSTransition, TransitionGroup } from 'react-transition-group';
import { Button } from './../input/Input';
import Language from './../language/Language';
import { openModal, closeModal } from './../actions/ModalActions';
import { Heading4 } from './../typography/Typography';
import Keyboard from './../keyboard/Keyboard';

class Modal extends React.Component {
  constructor(props) {
    super(props);
  }

  componentDidMount() {
    Keyboard.addListener(this);
  }

  componentWillUnmount() {
    Keyboard.removeListener(this);
  }

  onKeyUp(e) {
    if(!Keyboard.isEscape()) return;
    this.props.closeModal();
  }

  render() {
    //Add necessary buttons
    let buttons = [];
    if(this.props.buttons) {
      if(Array.isArray(buttons)) {
        buttons.concat(this.props.buttons);
      } else {
        buttons.push(this.props.buttons);
      }
    }

    if(this.props.close) {
      buttons.push(<Button key="close" onClick={this.props.closeModal}>{ Language.get("modal.close") }</Button>);
    }

    //Inner divs
    let heading,body,footer;
    if(this.props.title) {
      heading = (
        <div className="o-modal__box-heading">
          <Heading4 className="o-modal__title">
            { this.props.title }
          </Heading4>
        </div>
      );
    }

    if(this.props.children) {
      body = (
        <div className="o-modal__box-body">
          { this.props.children }
        </div>
      );
    }

    if(buttons) {
      footer = (
        <div className="o-modal__box-footer">
          { buttons }
        </div>
      );
    }

    //Create our modal contents
    let contents = (
      <div className="o-modal">
        <div className="o-modal__inner">
          {/* Provides both a good overlay, and a nice clickable area  */}
          <div className="o-modal__backdrop" onClick={this.props.closeModal}>
          </div>

          {/* Box itself, has a background and a shadow */}
          <div className={"o-modal__box" + (this.props.large ? " is-large":"")}>
            { heading }
            { body }
            { footer }
          </div>
        </div>
      </div>
    );

    //Display?
    let displayedContents = <div></div>;

    if(this.props.modal.open) {
      displayedContents = (
        <CSSTransition
          appear={true}
          timeout={200}
          classNames="o-modal__transition"
          mountOnEnter={ true }
          unmountOnExit={ true }
          key="modal"
        >
          { contents }
        </CSSTransition>
      );
    }

    //Wrap entire contents of modal in transitional container.
    return (
      <TransitionGroup className="o-modal__transition-container">
        { displayedContents }
      </TransitionGroup>
    );
  }
}

const mapStateToProps = (state) => {
  return {
    modal: state.modal,
    language: state.language
  };
}

const mapDispatchToProps = (dispatch) => {
  return bindActionCreators({
    openModal: openModal,
    closeModal: closeModal
  },dispatch);
}

export default connect(mapStateToProps, mapDispatchToProps)(Modal);