content: /*
   * Copyright (C) Pootle contributors.
   *
   * This file is a part of the Pootle project. It is distributed under the GPL3
   * or later license. See the LICENSE file for a copy of the license and the
   * AUTHORS file for copyright and authorship information.
   */
  
  'use strict';
  
  import cx from 'classnames';
  import React from 'react';
  import _ from 'underscore';
  
  import ItemTable from './ItemTable';
  
  
  let Search = React.createClass({
  
    propTypes: {
      fields: React.PropTypes.array.isRequired,
      onSearch: React.PropTypes.func.isRequired,
      onSelectItem: React.PropTypes.func.isRequired,
      items: React.PropTypes.object.isRequired,
      selectedItem: React.PropTypes.object,
      searchLabel: React.PropTypes.string.isRequired,
      searchPlaceholder: React.PropTypes.string.isRequired,
      resultsCaption: React.PropTypes.string.isRequired,
      searchQuery: React.PropTypes.string.isRequired,
    },
  
    /* Lifecycle */
  
    getInitialState() {
      return {
        isLoading: false,
      };
    },
  
  
    /* State-changing callbacks */
  
    fetchResults(query) {
      this.setState({isLoading: true});
      this.props.onSearch(query).then(this.onResultsFetched);
    },
  
    onResultsFetched(data) {
      this.setState({isLoading: false});
    },
  
    loadMore() {
      this.fetchResults(this.props.searchQuery);
    },
  
  
    /* Layout */
  
    render() {
      let { isLoading } = this.state;
      let { items } = this.props;
      let loadMoreBtn;
  
      if (items.count > 0 && items.length < items.count) {
        loadMoreBtn = <button className="btn" onClick={this.loadMore}>
                      {gettext('Load More')}
                      </button>;
      }
  
      let resultsClassNames = cx({
        'search-results': true,
        'loading': isLoading
      });
  
      return (
        <div className="search">
          <div className="hd">
            <h2>{this.props.searchLabel}</h2>
          </div>
          <div className="bd">
            <div className="search-box">
              <SearchBox
                onSearch={this.props.onSearch}
                placeholder={this.props.searchPlaceholder}
                searchQuery={this.props.searchQuery} />
            </div>
            <div className={resultsClassNames}>
            {isLoading && this.props.items.length === 0 ?
              <div>{gettext('Loading...')}</div> :
              <div>
                <ItemTable
                  fields={this.props.fields}
                  items={items}
                  resultsCaption={this.props.resultsCaption}
                  selectedItem={this.props.selectedItem}
                  onSelectItem={this.props.onSelectItem} />
                {loadMoreBtn}
              </div>
            }
            </div>
          </div>
        </div>
      );
    }
  
  });
  
  
  let SearchBox = React.createClass({
  
    propTypes: {
      onSearch: React.PropTypes.func.isRequired,
      placeholder: React.PropTypes.string,
      searchQuery: React.PropTypes.string,
    },
  
    /* Lifecycle */
  
    getInitialState() {
      return {
        // XXX: review, prop should be explicitly named `initialSearchQuery`
        searchQuery: this.props.searchQuery
      };
    },
  
    componentWillReceiveProps(nextProps) {
      if (nextProps.searchQuery !== this.state.searchQuery) {
        this.setState({searchQuery: nextProps.searchQuery});
      }
    },
  
    componentWillMount() {
      this.handleSearchDebounced = _.debounce(function () {
        this.props.onSearch.apply(this, [this.state.searchQuery]);
      }, 300);
    },
  
    componentDidMount() {
      React.findDOMNode(this.refs.input).focus();
    },
  
  
    /* Handlers */
  
    handleKeyUp(e) {
      let key = e.nativeEvent.keyCode;
      if (key === 27) {
        React.findDOMNode(this.refs.input).blur();
      }
    },
  
    handleChange() {
      this.setState({searchQuery: React.findDOMNode(this.refs.input).value});
      this.handleSearchDebounced();
    },
  
  
    /* Layout */
  
    render() {
      return (
        <input
          type="text"
          ref="input"
          value={this.state.searchQuery}
          onChange={this.handleChange}
          onKeyUp={this.handleKeyUp}
          {...this.props}
        />
      );
    }
  
  });
  
  
  export default Search;
  