// Single line text display that can animate and hold multiple registers
import React from 'react';
import {connect} from 'react-redux';

import {getTimeStr} from '../utils';

const getBalanceText = (balance) => {
  if (balance === 0) {
    return 'Balance: Center';
  }
  const direction = balance > 0 ? 'Right' : 'Left';
  return `Balance: ${Math.abs(balance)}% ${direction}`;
};

const getVolumeText = (volume) => `Volume: ${volume}%`;

const getPositionText = (duration, seekToPercent) => {
  const newElapsedStr = getTimeStr(duration * seekToPercent / 100);
  const durationStr = getTimeStr(duration);
  return `Seek to: ${newElapsedStr}/${durationStr} (${seekToPercent}%)`;
};

const getMediaText = (name, duration) => {
  return `${name} (${getTimeStr(duration)})  ***  `;
};

const getDoubleSizeModeText = (enabled) => {
  return `${enabled ? 'Disable' : 'Enable'} doublesize mode`;
};

const isLong = (text) => text.length > 30;

// Given text and step, how many pixels should it be shifted?
const stepOffset = (text, step) => {
  if (!isLong(text)) {
    return 0;
  }
  return (step % text.length) * 5;
};

// Format an int as negative pixels
const negativePixels = (pixels) => `-${pixels}px`;

// If text is wider than the marquee, it needs to loop
const loopText = (text) => isLong(text) ? text + text : text;

import CharacterString from './CharacterString.jsx';

class Marquee extends React.Component {
  constructor(props) {
    super(props);
    this.state = {stepping: true};
    this.handleMouseDown = this.handleMouseDown.bind(this);
    this.getText = this.getText.bind(this);
  }

  componentDidMount() {
    const step = () => {
      setTimeout(() => {
        if (this.state.stepping) {
          this.props.dispatch({type: 'STEP_MARQUEE'});
        }
        step();
      }, 220);
    };
    step();
  }

  getText() {
    switch (this.props.userInput.focus) {
      case 'balance':
        return getBalanceText(this.props.media.balance);
      case 'volume':
        return getVolumeText(this.props.media.volume);
      case 'position':
        return getPositionText(this.props.media.length, this.props.userInput.scrubPosition);
      case 'double':
        return getDoubleSizeModeText(this.props.display.doubled);
      default:
        break;
    }
    if (this.props.media.name) {
      return getMediaText(this.props.media.name, this.props.media.length);
    }
    return 'Winamp 2.91';
  }

  handleMouseDown() {
    this.setState({stepping: false});
    document.addEventListener('mouseup', () => {
      // TODO: Remove this listener
      setTimeout(() => {
        this.setState({stepping: true});
      }, 1000);
    });
  }

  render() {
    const text = this.getText();
    const offset = stepOffset(text, this.props.display.marqueeStep);
    return <div id='marquee' className='text' onMouseDown={this.handleMouseDown}>
      <CharacterString style={{marginLeft: negativePixels(offset)}} >
        {loopText(text)}
      </CharacterString>
    </div>;
  }
}

export {
  getBalanceText,
  getVolumeText,
  getPositionText,
  getMediaText,
  getDoubleSizeModeText,
  negativePixels,
  stepOffset,
  loopText,
  Marquee
};
export default connect((state) => state)(Marquee);
