var React = require('react');
var CategoryHeader = require('./category-header.jsx');
var AppList = require('./app-list.jsx');
var AnimateMixin = require('../mixins/animate');
var actions = require('../../actions');
var connect = require('react-redux').connect;
var debug = require('../../util/debug')('launcher-view');

var DEFAULT_PROFILE = './default-profile.json';

var LauncherView = React.createClass({

  mixins: [AnimateMixin],

  getInitialState: function() {
    return {
      currentItemPath: '',
      currentItem: null
    };
  },

  componentDidMount: function() {
    var profilePath = this.props.processOpts.profile || DEFAULT_PROFILE;
    this.props.dispatch(actions.launcher.loadProfile(profilePath));
  },

  componentWillReceiveProps: function(nextProps) {
    if( nextProps.profile && !this.state.currentItem ) {
      this.setState({ currentItem: nextProps.profile });
    }
  },

  render: function() {

    var currentItem = this.state.currentItem;
    var items = currentItem && currentItem.items ? currentItem.items : [];
    var currentItemPath = this.state.currentItemPath;

    var header = currentItemPath !== '' ?
      ( <CategoryHeader
          onBackClick={this.onBackClick}
          item={currentItem}
          itemPath={currentItemPath} /> ) :
      null
    ;

    return (
      <div className="launcher">
        {header}
        <AppList ref="appList"
          items={items}
          parentPath={currentItemPath}
          onItemClick={this.onItemClick} />
      </div>
    );

  },

  onBackClick: function(itemPath) {

    var parentPath = this._normalizeItemPath(itemPath).slice(0, -1);
    var parentItem = this._getItemByPath(parentPath, this.props.profile);

    this.play(this.refs.appList, 'slide-out-right 250ms ease-in-out')
      .then(function() {
        this.setState({currentItem: parentItem, currentItemPath: parentPath.join('.')});
        return this.play(this.refs.appList, 'slide-in-left 250ms ease-in-out');
      }.bind(this))
    ;

  },

  onItemClick: function(evt, itemPath, item) {

    if(item.exec) {

      debug('Launching application "'+item.exec+'"...');
      var el = evt.currentTarget;
      el.classList.add('pulse');

      this.props.dispatch(actions.launcher.runApp(item.exec))
        .then(function() {
          el.classList.remove('pulse');
        })
        .catch(function() {
          el.classList.remove('pulse');
        })
      ;

    } else {
      this.play(this.refs.appList, 'slide-out-left 250ms ease-in-out')
        .then(function() {
          this.setState({ currentItemPath: itemPath, currentItem: item });
          return this.play(this.refs.appList, 'slide-in-right 250ms ease-in-out');
        }.bind(this))
      ;
    }

  },

  _getItemByPath: function(itemPath, rootItem) {

    itemPath = this._normalizeItemPath(itemPath);

    var itemIndex = itemPath[0];

    if(itemIndex === undefined) {
      return rootItem;
    }

    if(!('items' in rootItem)) {
      return undefined;
    }

    var subItem = rootItem.items[itemIndex];

    if(itemPath.length === 0) {
      return subItem;
    }

    return this._getItemByPath(itemPath.slice(1), subItem);

  },

  _normalizeItemPath: function(itemPath) {

    if( Array.isArray(itemPath) ) return itemPath;

    if((typeof itemPath === 'string' && itemPath.length === 0) || !itemPath) return [];

    return itemPath.split('.').reduce(function(arr, index) {
      if(index !== '') {
        arr.push(+index);
      }
      return arr;
    }, []);

  }

});


function select(state) {
  return {
    processOpts: state.processOpts,
    profile: state.profile
  };
}


module.exports = connect(select)(LauncherView);
