require('normalize.css/normalize.css');
require('styles/App.scss');

import React from 'react';
import ReactDOM from 'react-dom';

let imageDatas = require('../data/data.json');
imageDatas = (function genImageURL(imageDataArray) {
    for (let i = 0; i < imageDataArray.length; i++) {
        let singleImage = imageDataArray[i];
        singleImage.fileURL = require('../images/' + singleImage.filename);
        imageDataArray[i] = singleImage;
    }
    return imageDataArray;
})(imageDatas);

/**
 * 获取区间内一个随机值
 * @param  {[type]} low  [description]
 * @param  {[type]} high [description]
 * @return {[type]}      [description]
 */
function getRangeRandom(low,high){
  return Math.ceil(Math.random() *(high - low) + low);
};
/**
 * 获取0~30之间的任意一个正负值
 * @return {[type]} [description]
 */
function get30DegRandom() {
  return (Math.random() > 0.5 ? '' : '-') + Math.ceil((Math.random() * 30));
}

/* 创建一个ImgFigure组件 */ 
let ImgFigure = React.createClass({
  /**
   * [handleClick imgFigure的点击处理函数]
   * @return {[type]} [description]
   */
  handleClick(e){
    // 
    if(this.props.arrange.isCenter){
      this.props.inverse();
    }else{
      this.props.center();
    }
    e.stopPropagation();
    e.preventDefault();
  },

  render() {
    let styleObj = {};
    // 如果 props 属性中指定了这张图片的位置，则使用
    if(this.props.arrange.pos){
      styleObj = this.props.arrange.pos;
    }
    // 如果 图片的旋转角度有值，添加旋转角度
    if(this.props.arrange.rotate){
      (['MozT','msT','WebkitT','t']).forEach(function(value){
        styleObj[value + 'ransform'] = 'rotate(' + this.props.arrange.rotate + 'deg)';
      }.bind(this));
    }
    if(this.props.arrange.isCenter){
      styleObj.zIndex=11;
    }
    // 
    let imgFigureClassName='img-figure';
    imgFigureClassName += this.props.arrange.isInverse ? ' is-inverse' : '';
    return ( 
      <figure className={imgFigureClassName} style={styleObj} onClick={this.handleClick} >
        <img src={this.props.data.fileURL} alt={this.props.data.title} /> 
        <figcaption>
          <h2 className="img-title">{this.props.data.title}</h2> 
          <div className="img-back" onClick={this.handleClick}>
            <p>
              {this.props.data.desc}
            </p>
          </div>
        </figcaption> 
      </figure>
    );
  }
});
/**
 * [render 控制组件]
 * @param  {[type]} ){                 return ();  }} [description]
 * @return {[type]}     [description]
 */
let ControllerUnit = React.createClass({
  handleClick(e){
    if(this.props.arrange.isCenter){
      this.props.inverse();
    }else{
      this.props.center();
    }
    e.stopPropagation();
    e.preventDefault();
  },
  render(){
    let controllerUnitClassName='controller-unit';

    if(this.props.arrange.isCenter){
      controllerUnitClassName+=' is-center';
    }
    return (
      <span className={controllerUnitClassName} onClick={this.handleClick}>
      </span>
    );
  }
});

/**
 * 
 */
class AppComponent extends React.Component {
  // ES6 的写法
  constructor(){
    super();
    this.Constant = {
      centerPos:{
        left:0,
        top:0
      },
      // 水平方向的取值范围
      hPosRange:{ 
        leftSecX:[0,0],
        rightSecX:[0,0],
        y:[0,0]
      },
      // 垂直方向的取值范围
      vPosRange:{ 
        x:[0,0],
        topY:[0,0] 
      }
    };
    this.state = {
      imgArrangeArr:[
        /*{
          pos:{
            left: 0,
            top: 0
          },
          rotate: 0, // 旋转角度
          isInverse: false, // 图片的正反面
          isCenter: false // 是否在屏幕中心
        }*/
      ]
    }
  }
  // 组件加载以后，为每张图片计算其位置范围
  componentDidMount(){
    /**
     * 首先拿到舞台的大小,ref是虚拟dom,ReactDOM.findDOMNode找到的是真实的dom
     * scrollWidth 对象的实际内容宽度，不包括滚动条等边线宽度，会随内容超过可视区而变大
     * clientWidth 对象的可视区的宽度，不包括滚动条等边线宽度，会随可视区的变化而变化
     * offsetWidth 对象整体的实际宽度，包括滚动条等边线宽度，会随可视区的变化而变化 
     */
    let stageDOM = ReactDOM.findDOMNode(this.refs.stage),
      stageW = stageDOM.scrollWidth,
      stageH = stageDOM.scrollHeight,
      halfStageW = Math.ceil(stageW / 2),
      halfStageH = Math.ceil(stageH / 2);

    // 拿到一个imageFigure的大小
    let imgFigureDOM=ReactDOM.findDOMNode(this.refs.imgFigure0),
      imgW = imgFigureDOM.scrollWidth,
      imgH = imgFigureDOM.scrollHeight,
      halfImgW = Math.ceil(imgW / 2),
      halfImgH = Math.ceil(imgH / 2);

    // 计算中心图片的位置点
    this.Constant.centerPos={
      left:halfStageW-halfImgW,
      top:halfStageH-halfImgH
    };

    // 计算 左侧区域
    this.Constant.hPosRange.leftSecX[0] = -halfImgW;
    this.Constant.hPosRange.leftSecX[1] = halfStageW - halfImgW * 3;
    // 计算 右侧区域
    this.Constant.hPosRange.rightSecX[0] = halfStageW + halfImgW;
    this.Constant.hPosRange.rightSecX[1] = stageW - halfImgW;
    // 左右侧的区域 y 取值范围
    this.Constant.hPosRange.y[0] = -halfImgH;
    this.Constant.hPosRange.y[1] = stageH - halfImgH;
    // 计算 上区域 x 取值范围
    this.Constant.vPosRange.x[0] = halfStageW - imgW;
    this.Constant.vPosRange.x[1] = halfStageW;
    // 计算 上区域
    this.Constant.vPosRange.topY[0] = -halfImgH;
    this.Constant.vPosRange.topY[1] = halfStageH - halfImgH * 3;

    this.rearrange(0);
  }

  /**
   * 翻转图片
   * @param  {[int]} index [输入当前被执行inverse的图片的索引值]
   * @return {[Function]}       [这是一个闭包函数,内部返回一个真正待被执行的函数]
   */
  inverse(index){
    return function(){
      let imgArrangeArr = this.state.imgArrangeArr;

      imgArrangeArr[index].isInverse = !imgArrangeArr[index].isInverse;

      this.setState({
        imgArrangeArr:imgArrangeArr
      })
    }.bind(this);
  }

  /**
   * 重新布局所有图片
   * @param  {[type]} centerIndex [description]
   * @return {[type]}             [description]
   */
  rearrange(centerIndex){
    // 
    let imgArrangeArr = this.state.imgArrangeArr,
      Constant = this.Constant,
      centerPos = Constant.centerPos,
      hPosRange = Constant.hPosRange,
      vPosRange = Constant.vPosRange,
      hPosRangeLeftSecX = hPosRange.leftSecX,
      hPosRangeRightSecX = hPosRange.rightSecX, 
      hPosRangeY = hPosRange.y,
      vPosRangeTopY = vPosRange.topY,
      vPosRangeX = vPosRange.x;
    // 
    let imgArrangeTopArr = [],
    // 取一个，或不取
      topImgNum = Math.floor(Math.random() * 2), 
      topImgSpliceIndex = 0;
    // 
    let imgArrangeCenterArr = imgArrangeArr.splice(centerIndex,1);
    // 首先居中 centerIndex 的图片
    imgArrangeCenterArr[0]={
      pos:centerPos,
      rotate:0,
      isCenter:true
    };

    // 取出要布局的上侧的图片状态信息
    topImgSpliceIndex = Math.ceil(Math.random() * (imgArrangeArr.length - topImgNum));
    imgArrangeTopArr = imgArrangeArr.splice(topImgSpliceIndex,topImgNum);
    // 布局上侧的图片
    imgArrangeTopArr.forEach(function(value,index){
      imgArrangeTopArr[index] = {
        pox:{
          top:getRangeRandom(vPosRangeTopY[0],vPosRangeTopY[1]),
          left:getRangeRandom(vPosRangeX[0],vPosRangeX[1])
        },
        rotate : get30DegRandom(),
        isCenter:false
      }
    });

    // 布局左右两侧的图片
    for(let i=0,j=imgArrangeArr.length,k=j / 2;i < j;i++){
      let hPosRangeLORX = null ;
      if(i < k){// 前半部分布局左侧
        hPosRangeLORX = hPosRangeLeftSecX;
      }else {// 前半部分布局右侧
        hPosRangeLORX = hPosRangeRightSecX;
      }

      imgArrangeArr[i] = {
        pos:{
          top:getRangeRandom(hPosRangeY[0],hPosRangeY[1]),
          left:getRangeRandom(hPosRangeLORX[0],hPosRangeLORX[1])
        },
        rotate: get30DegRandom(),
        isCenter:false
      }
    }
    // 
    if (imgArrangeTopArr && imgArrangeTopArr[0]) {
      imgArrangeArr.splice(topImgSpliceIndex,0,imgArrangeTopArr[0])
    }
    imgArrangeArr.splice(centerIndex,0,imgArrangeCenterArr[0]);
    // 
    this.setState({
      imgArrangeArr:imgArrangeArr
    })
  }

  // 
  /**
   * [center 利用rearrange函数， 居中对应的图片]
   * @param  {[int]} index [需要被居中的图片的索引值]
   * @return {[Function]}       [description]
   */
  center(index){
    return function(){
      this.rearrange(index);
    }.bind(this);
  }
  /**
   * 
   * @return {[type]} [description]
   */
  render() {
    let controllerUnits=[],imgFigures=[];
    // 
    imageDatas.forEach(function(value,index){
      if(this.state.imgArrangeArr&&!this.state.imgArrangeArr[index]){
        this.state.imgArrangeArr[index]={
          pos:{
            left:0,top:0
          },
          rotate:0,
          isInverse:false,
          isCenter:false
        }
      }
      imgFigures.push(
        <ImgFigure key={index} data={value} ref={'imgFigure'+index} 
        arrange={this.state.imgArrangeArr[index]} 
        inverse={this.inverse(index)}
        center={this.center(index)} />
      );
      controllerUnits.push(
        <ControllerUnit key={index} 
        arrange={this.state.imgArrangeArr[index]} 
        inverse={this.inverse(index)}
        center={this.center(index)} />
      );
    }.bind(this));
    // 
    return (
      <section className="stage" ref="stage">
        <section className="img-sec">
          {imgFigures}
        </section> 
        <nav className="controller-nav">
          {controllerUnits}
        </nav> 
      </section>
    );
  }
}

AppComponent.defaultProps = {};
export default AppComponent;
