var React = require('react');
var Classable = require('../../mixins/classable');
var Dom = require('../../utils/dom');
var RippleCircle = require('./circle');

var TouchRipple = React.createClass({

	mixins: [Classable],

	propTypes: {
		centerRipple: React.PropTypes.bool,
		className: React.PropTypes.string
	},

	getInitialState: function() {
		return {
			ripples: [{
				key: 0,
				started: false,
				ending: false
			}] 
		};
	},

	render: function() {

		var classes = this.getClasses('dig-touch-ripple');

		return (
			<div
				onMouseUp={this._handleMouseUp}
				onMouseDown={this._handleMouseDown}
				onMouseOver={this._handleMouseOver}
				onMouseOut={this._handleMouseOut}
				onTouchStart={this._handleTouchStart}
				onTouchEnd={this._handleTouchEnd}>
				<div className={classes}>
					{this._getRippleElements()}
				</div>
				{this.props.children}
			</div>
		);
	},

	start: function(e) {
	  var ripples = this.state.ripples;
	  var nextKey = ripples[ripples.length-1].key + 1;
	  var style = !this.props.centerRipple ? this._getRippleStyle(e) : {};
	  var ripple;

	  //Start the next unstarted ripple
	  for (var i = 0; i < ripples.length; i++) {
	    ripple = ripples[i];
	    if (!ripple.started) {
	      ripple.started = true;
	      ripple.style = style;
	      break;
	    }
	  };

	  //Add an unstarted ripple at the end
	  ripples.push({
	    key: nextKey,
	    started: false,
	    ending: false
	  });

	  //Re-render
	  this.setState({
	    ripples: ripples
	  });
	},

	end: function() {
	  var ripples = this.state.ripples;
	  var ripple;
	  var endingRipple;

	  //End the the next un-ended ripple
	  for (var i = 0; i < ripples.length; i++) {
	    ripple = ripples[i];
	    if (ripple.started && !ripple.ending) {
	      ripple.ending = true;
	      endingRipple = ripple;
	      break;
	    }
	  };

	  //Only update if a ripple was found
	  if (endingRipple) {
	    //Re-render
	    this.setState({
	      ripples: ripples
	    });

	    //Wait 2 seconds and remove the ripple from DOM
	    setTimeout(function() {
	      ripples.shift();
	      if (this.isMounted()) {
	        this.setState({
	          ripples: ripples
	        });
	      }
	    }.bind(this), 2000);
	  }
	},

	_handleMouseDown: function(e) {
	  //only listen to left clicks
	  if (e.button === 0) this.start(e);
	},

	_handleMouseUp: function(e) {
	  this.end();
	},

	_handleMouseOver: function(e) {
	  //this.start(e);
	},

	_handleMouseOut: function(e) {
	  this.end();
	},

	_handleTouchStart: function(e) {
	  this.start(e);
	},

	_handleTouchEnd: function(e) {
	  this.end();
	},

	_getRippleStyle: function(e) {
	  var style = {};
	  var el = this.getDOMNode();
	  var elHeight = el.offsetHeight;
	  var elWidth = el.offsetWidth;
	  var offset = Dom.offset(el);
	  var pageX = e.pageX == undefined ? e.nativeEvent.pageX : e.pageX;
	  var pageY = e.pageY == undefined ? e.nativeEvent.pageY : e.pageY;
	  var pointerX = pageX - offset.left;
	  var pointerY = pageY - offset.top;
	  var topLeftDiag = this._calcDiag(pointerX, pointerY);
	  var topRightDiag = this._calcDiag(elWidth - pointerX, pointerY);
	  var botRightDiag = this._calcDiag(elWidth - pointerX, elHeight - pointerY);
	  var botLeftDiag = this._calcDiag(pointerX, elHeight - pointerY);
	  var rippleRadius = Math.max(
	    topLeftDiag, topRightDiag, botRightDiag, botLeftDiag
	  );
	  var rippleSize = rippleRadius * 2;
	  var left = pointerX - rippleRadius;
	  var top = pointerY - rippleRadius;

	  style.height = rippleSize + 'px';
	  style.width = rippleSize + 'px';
	  style.top = top + 'px';
	  style.left = left + 'px';

	  return style;
	},

	_calcDiag: function(a, b) {
	  return Math.sqrt((a * a) + (b * b));
	},

	_getRippleElements: function() {
	  return this.state.ripples.map(function (ripple) {
	  	return (
	  		<RippleCircle 
		  		key={ripple.key} 
		  		started={ripple.started} 
		  		ending={ripple.ending} 
		  		style={ripple.style} />
		  	);
	  }.bind(this));
	}

});

module.exports = TouchRipple;