"use strict";

exports.__esModule = true;
exports.default = exports.SongSorter = exports.sort = exports.SongSorterSelect = exports.SongSorterProperties = void 0;

var _react = _interopRequireWildcard(require("react"));

var _propTypes = _interopRequireDefault(require("prop-types"));

var _Box = _interopRequireDefault(require("@material-ui/core/Box"));

var _Button = _interopRequireDefault(require("@material-ui/core/Button"));

var _Input = _interopRequireDefault(require("@material-ui/core/Input"));

var _InputLabel = _interopRequireDefault(require("@material-ui/core/InputLabel"));

var _MenuItem = _interopRequireDefault(require("@material-ui/core/MenuItem"));

var _FormHelperText = _interopRequireDefault(require("@material-ui/core/FormHelperText"));

var _FormControl = _interopRequireDefault(require("@material-ui/core/FormControl"));

var _Select = _interopRequireDefault(require("@material-ui/core/Select"));

var _mdiMaterialUi = require("mdi-material-ui");

var _utils = require("subfirelib/utils/utils");

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

function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== "function") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function (nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); }

function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(nodeInterop); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; }

function _extends() { _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }

const SongSorterProperties = {
  unsorted: 'Unsorted',
  title: 'Title',
  path: 'Path',
  album: 'Album',
  artist: 'Artist',
  year: 'Year',
  created: 'Date Added',
  duration: 'Length',
  genre: 'Genre',
  random: 'Random'
};
exports.SongSorterProperties = SongSorterProperties;
const numericProps = ['year', 'duration'];

const numericProp = prop => numericProps.includes(prop);

const SongSorterSelect = props => {
  const {
    classes = {},
    onChange,
    sortProperty = 'unsorted',
    sortDirection = 'asc',
    fullWidth,
    native,
    ...rest
  } = props;

  const theOnChange = evt => {
    onChange(evt.target.value, sortDirection);
  };

  const theSortDirChange = evt => {
    onChange(sortProperty, sortDirection === 'asc' ? 'desc' : 'asc', true);
  };

  const SortIcon = sortDirection === 'asc' ? _mdiMaterialUi.SortAscending : _mdiMaterialUi.SortDescending;
  return /*#__PURE__*/_react.default.createElement(_Box.default, {
    display: "flex",
    flexDirection: "row",
    flexWrap: "nowrap",
    justifyContent: "flex-start",
    alignItems: "flex-end"
  }, /*#__PURE__*/_react.default.createElement(_Box.default, {
    flexGrow: 1
  }, /*#__PURE__*/_react.default.createElement(_FormControl.default, {
    className: classes.formControl,
    fullWidth: fullWidth
  }, /*#__PURE__*/_react.default.createElement(_InputLabel.default, {
    shrink: true,
    htmlFor: "sortby-label-placeholder"
  }, props.label || 'Sort By'), /*#__PURE__*/_react.default.createElement(_Select.default, _extends({
    value: sortProperty,
    onChange: theOnChange,
    input: /*#__PURE__*/_react.default.createElement(_Input.default, {
      name: "sortby-input",
      id: "sortby-label-placeholder"
    }),
    displayEmpty: true,
    name: "sortby",
    className: classes.selectEmpty
  }, rest), Object.entries(SongSorterProperties).map(([k, v]) => {
    return native ? /*#__PURE__*/_react.default.createElement("option", {
      key: k,
      value: k
    }, v) : /*#__PURE__*/_react.default.createElement(_MenuItem.default, {
      key: k,
      value: k
    }, v);
  })), props.helperText && /*#__PURE__*/_react.default.createElement(_FormHelperText.default, null, props.helperText))), /*#__PURE__*/_react.default.createElement(_Box.default, {
    flexGrow: 0
  }, /*#__PURE__*/_react.default.createElement(_Button.default, {
    size: "small",
    onClick: theSortDirChange
  }, /*#__PURE__*/_react.default.createElement(SortIcon, null))));
};

exports.SongSorterSelect = SongSorterSelect;
SongSorterSelect.propTypes = {
  classes: _propTypes.default.object,
  label: _propTypes.default.string,
  helperText: _propTypes.default.string,
  sortProperty: _propTypes.default.string,
  fullWidth: _propTypes.default.bool,
  onChange: _propTypes.default.func,
  sortDirection: _propTypes.default.string,
  native: _propTypes.default.bool
};

const removeArticles = str => {
  const words = str.split(' ');
  if (words.length <= 1) return str;
  if (words[0] === 'a' || words[0] === 'the' || words[0] === 'an') return words.splice(1).join(' ');
  return str;
};

const compare = (a, b, dir, isNumericProp) => {
  if (isNumericProp) {
    a = (a || 0) * 1;
    b = (b || 0) * 1;
    return dir === 'asc' ? a - b : b - a;
  }

  let aTitle = a.toLowerCase(),
      bTitle = b.toLowerCase();
  aTitle = removeArticles(aTitle);
  bTitle = removeArticles(bTitle);
  let rv = aTitle.localeCompare(bTitle);
  if (dir === 'desc') rv = rv * -1;
  return rv;
};

const sortFunction = (prop, dir, prop2, prop3, contentProp, isNumericProp, a, b) => {
  const av = ((contentProp ? a[contentProp][prop] : a[prop]) || '') + '';
  const bv = ((contentProp ? b[contentProp][prop] : b[prop]) || '') + '';
  const c = compare(av, bv, dir, isNumericProp);
  if (c !== 0) return c;
  return prop2 ? sortFunction(prop2, dir, prop3, null, contentProp, numericProp(prop2), a, b) : 0;
};

const sort = (prop, dir, songList, contentProp) => {
  let prop2 = null;
  let prop3 = null;

  if (prop === 'album') {
    prop2 = 'track';
  }

  if (prop === 'artist') {
    prop2 = 'album';
    prop3 = 'track';
  }

  if (prop === 'year') {
    prop2 = 'artist';
    prop3 = 'album';
  }

  const rv = songList.slice().sort(sortFunction.bind(sortFunction, prop, dir, prop2, prop3, contentProp, numericProp(prop)));
  return rv;
};

exports.sort = sort;

const SongSorter = props => {
  const {
    songList,
    setSongList,
    OptionsRenderer = SongSorterSelect,
    optionsRendererProps = {},
    contentProp = null,
    sortProperty,
    sortDirection = 'asc'
  } = props;

  const onChange = (newSortProperty, newSortDirection, forceReverse) => {
    let newSongList = songList;

    if (newSortProperty === 'unsorted') {
      if (forceReverse) {
        newSongList = [...songList.reverse()];
      }
    } else if (newSortProperty === 'random') {
      newSongList = (0, _utils.arrayShuffle)(songList);
    } else {
      newSongList = sort(newSortProperty, newSortDirection, songList, contentProp);
    }

    newSortProperty = newSortProperty === 'random' ? 'unsorted' : newSortProperty;
    setSongList(newSongList.slice(), newSortProperty, newSortDirection);
  };

  return /*#__PURE__*/_react.default.createElement(OptionsRenderer, _extends({
    onChange: onChange,
    sortProperty: sortProperty,
    sortDirection: sortDirection
  }, optionsRendererProps));
};

exports.SongSorter = SongSorter;
SongSorter.propTypes = {
  songList: _propTypes.default.array.isRequired,
  setSongList: _propTypes.default.func.isRequired,
  OptionsRenderer: _propTypes.default.elementType,
  optionsRendererProps: _propTypes.default.object,
  contentProp: _propTypes.default.string,
  sortProperty: _propTypes.default.string,
  sortDirection: _propTypes.default.string
};
var _default = SongSorter;
exports.default = _default;