import React from 'react';
import joinClasses from 'react/lib/joinClasses';
import rcUtil from 'rc-util';

function getScroll(w, top) {
  let ret = w['page' + (top ? 'Y' : 'X') + 'Offset'];
  let method = 'scroll' + (top ? 'Top' : 'Left');
  if (typeof ret !== 'number') {
    let d = w.document;
    //ie6,7,8 standard mode
    ret = d.documentElement[method];
    if (typeof ret !== 'number') {
      //quirks mode
      ret = d.body[method];
    }
  }
  return ret;
}

function getOffset(element) {
  let rect = element.getBoundingClientRect();
  let body = document.body;
  let clientTop = element.clientTop || body.clientTop || 0;
  let clientLeft = element.clientLeft || body.clientLeft || 0;
  let scrollTop = getScroll(window, true);
  let scrollLeft = getScroll(window);

  return {
    top: rect.top + scrollTop - clientTop,
    left: rect.left + scrollLeft - clientLeft
  };
}

let Affix = React.createClass({

  getDefaultProps() {
    return {
      offset: 0
    };
  },

  propTypes: {
    offset: React.PropTypes.number
  },

  getInitialState() {
    return {
      affix: false,
      affixStyle: null
    };
  },

  handleScroll() {
    let affix = this.state.affix;
    let scrollTop = getScroll(window, true);
    let elemOffset = getOffset(this.getDOMNode());

    if (!affix && (elemOffset.top - this.props.offset) < scrollTop) {
      this.setState({
        affix: true,
        affixStyle: {
          top: this.props.offset,
          left: elemOffset.left,
          width: this.getDOMNode().offsetWidth
        }
      });
    }

    if (affix && (elemOffset.top - this.props.offset) > scrollTop) {
      this.setState({
        affix: false,
        affixStyle: null
      });
    }
  },

  componentDidMount() {
    this.scrollEvent = rcUtil.Dom.addEventListener(window, 'scroll', this.handleScroll);
    this.resizeEvent = rcUtil.Dom.addEventListener(window, 'resize', this.handleScroll);
  },

  componentWillUnmount() {
    if (this.scrollEvent) {
      this.scrollEvent.remove();
    }
    if (this.resizeEvent) {
      this.resizeEvent.remove();
    }
  },

  render() {
    let affix = this.state.affix ? 'ant-affix' : '';
    let className = this.props.className;

    return (
      <div {...this.props}>
        <div className={joinClasses(className, affix)} style={this.state.affixStyle}>
          {this.props.children}
        </div>
      </div>
    );
  }

});

module.exports = Affix;
