content: require('normalize.css/normalize.css');
  require('styles/App.scss');
  
  import React from 'react';
  import ReactDOM from 'react-dom';
  
  // 获取图片相关的数据
  let imageDatas = require('json!../data/imageDatas.json');
  // 利用自执行函数，将图片信息转成图片URL路径的信息
  imageDatas = (function genImageURL(imageDatasArr) {
    for (let i = 0, j = imageDatasArr.length; i < j; i++) {
      let singleImageData = imageDatasArr[i];
      singleImageData.imageURL = require('../images/' + singleImageData.fileName);
      imageDatasArr[i] = singleImageData;
    }
  
    return imageDatasArr;
  })(imageDatas);
  
  /**
   * 获取区间内的随机值
   * @param low 小值
   * @param high 大值
   */
  function getRangeRandom(low, high) {
    return Math.floor(Math.random() * (high - low) + low);
  }
  
  /**
   * 获取0~30°之间任意一个正负值
   */
  function get30DegRandom() {
    return (Math.random() > 0.5 ? '' : '-') + Math.floor(Math.random() * 30);
  }
  
  var ImgFigure = React.createClass({
  
    handleClick: function(e) {
  
      if (this.props.arrange.isCenter) {
        this.props.inverse();
      } else {
        this.props.center();
      }
  
      e.stopPropagation();
      e.preventDefault();
    },
  
    render: function() {
      var styleObj = {};
  
      // 如果props属性中指定了图片的位置则使用
      if (this.props.arrange.pos) {
        styleObj = this.props.arrange.pos;
      }
  
      // 如果图片的旋转角度有值且不为0则添加旋转角度
      if (this.props.arrange.rotate) {
        ['MozTransform', 'msTransform', 'WebkitTransform', 'transform'].forEach(function(value) {
          styleObj[value] = 'rotate(' + this.props.arrange.rotate + 'deg)';
        }.bind(this));
      }
  
      if (this.props.arrange.isCenter) {
        styleObj.zIndex = 11;
      }
  
      var imgFigureClassName = 'img-figure';
      imgFigureClassName += this.props.arrange.isInverse ? ' is-inverse' : '';
  
      return (
        <figure className={imgFigureClassName} style={styleObj} onClick={this.handleClick}>
          <img src={this.props.data.imageURL} 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>
      );
    }
  });
  
  // 控制组件
  var ControllerUnit = React.createClass({
  
    handleClick: function(e) {
      // 如果点击的是当前正在选中态的按钮，则翻转图片，否则将对应的图片居中
      if (this.props.arrange.isCenter) {
        this.props.inverse();
      } else {
        this.props.center();
      }
  
      e.stopPropagation();
      e.preventDefault();
    },
  
    render: function() {
  
      var controllerUnitClassName = 'controller-unit';
  
      /* 如果对应的是居中的图片，显示控制按钮的居中态
      如果同时对应的是翻转图片，显示控制按钮的翻转态 */
      if (this.props.arrange.isCenter) {
        controllerUnitClassName += ' is-center';
  
        if(this.props.arrange.isInverse) {
          controllerUnitClassName += ' is-inverse';
        }
      }
  
      return (
        <span className={controllerUnitClassName} onClick={this.handleClick}></span>
      );
    }
  });
  
  var AppComponent = React.createClass({
    Constant: {
      centerPos: {
        left: 0,
        right: 0
      },
      hPosRange: { // 水平方向取值范围
        leftSecX: [0, 0],
        rightSecX: [0, 0],
        y: [0, 0]
      },
      vPosRange: {
        x: [0, 0],
        topY: [0,0]
      }
    },
  
    /**
     * 翻转图片
     * @param index 执行翻转操作的图片index值
     * @return {Function} 真正待被执行的函数
     */
    inverse: function(index) {
      return function() {
        var imgsArrangeArr = this.state.imgsArrangeArr;
        imgsArrangeArr[index].isInverse = !imgsArrangeArr[index].isInverse;
  
        this.setState({
          imgsArrangeArr: imgsArrangeArr
        });
      }.bind(this);
    },
  
    // 组件加载以后，为每张图片计算其位置的范围
    componentDidMount: function() {
      var stageDOM = ReactDOM.findDOMNode(this.refs.stage),
        stageW = stageDOM.scrollWidth,
        stageH = stageDOM.scrollHeight,
        halfStageW = Math.ceil(stageW / 2),
        halfStageH = Math.ceil(stageH / 2);
  
      // 取得ImgFigure大小
      var 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: [-halfImgW, halfStageW - halfImgW * 3],
        rightSecX: [halfStageW + halfImgW, stageW - halfImgW],
        y: [-halfImgH, stageH - halfImgH]
      };
  
      // 计算上侧区域图片排布的位置
      this.Constant.vPosRange = {
        topY: [-halfImgH, halfStageH - halfImgH * 3],
        x: [halfStageW - imgW, halfStageW]
      };
  
      this.rearrange(0);
    },
  
    /**
     * 重新布局图片
     * @param centerIndex 指定居中排布图片的下标
     */
    rearrange: function(centerIndex) {
      var imgsArrangeArr = this.state.imgsArrangeArr,
        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,
  
        imgsArrangeTopArr = [],
        topImgNum = Math.floor(Math.random() * 2),  // 取一个或者不取
        topImgSpliceIndex = 0,
        imgsArrangeCenterArr = imgsArrangeArr.splice(centerIndex, 1);
  
        // 首先居中centerIndex图片,不需旋转
        imgsArrangeCenterArr[0] = {
          pos: centerPos,
          rotate: 0,
          isCenter: true
        };
  
        // 取出要布局上侧的图片的状态信息
        topImgSpliceIndex = Math.floor(Math.random() * (imgsArrangeArr.length - topImgNum));
        imgsArrangeTopArr = imgsArrangeArr.splice(topImgSpliceIndex, topImgNum);
  
        // 布局上侧图片
        imgsArrangeTopArr.forEach(function(value, index) {
          value = {
            pos: {
              top: getRangeRandom(vPosRangeTopY[0], vPosRangeTopY[0]),
              left: getRangeRandom(vPosRangeX[0], vPosRangeX[1])
            },
            rotate: get30DegRandom(),
            isCenter: false
          }
        });
  
        // 布局两侧图片
        for (let i = 0, j = imgsArrangeArr.length, k = j / 2; i < j; ++i) {
          var hPosRangeLORX = null;
          
          // 左边/右边
          if (i < k) {
            hPosRangeLORX = hPosRangeLeftSecX;
          } else {
            hPosRangeLORX = hPosRangeRightSecX;
          }
  
          imgsArrangeArr[i] = {
            pos: {
              top: getRangeRandom(hPosRangeY[0], hPosRangeY[1]),
              left: getRangeRandom(hPosRangeLORX[0], hPosRangeLORX[1])
            },
            rotate: get30DegRandom(),
            isCenter: false
          }
        }
  
        if (imgsArrangeTopArr && imgsArrangeTopArr[0]) {
          imgsArrangeArr.splice(topImgSpliceIndex, 0, imgsArrangeTopArr[0]);
        }
  
        imgsArrangeArr.splice(centerIndex, 0, imgsArrangeCenterArr[0]);
  
        this.setState({
          imgsArrangeArr: imgsArrangeArr
        });
    },
  
    /**
     * 利用rearrange函数居中index的图片
     * @param index 需要被居中图片所在数组下标
     * @return {Function}
     */
    center: function(index) {
      return function() {
        this.rearrange(index);
      }.bind(this);
    },
  
    getInitialState: function() {
      return {
        imgsArrangeArr: []
      };
    },
  
    render() {
      var controllerUnits = [],
          imgFigures = [];
  
      imageDatas.forEach(function(value, index) {
        if (!this.state.imgsArrangeArr[index]) {
          this.state.imgsArrangeArr[index] = {
            pos: {
              left: 0,
              top: 0
            },
            rotate: 0,
            isInverse: false,
            isCenter: false
          }
        }
  
        imgFigures.push(<ImgFigure data={value}
          key={index}
          ref={'imgFigure' + index}
          arrange={this.state.imgsArrangeArr[index]}
          inverse={this.inverse(index)}
          center={this.center(index)} />);
  
        controllerUnits.push(<ControllerUnit arrange={this.state.imgsArrangeArr[index]}
          key={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>
      );
    }
  });
  
  export default AppComponent;
  