/*
* @Author: zhouningyi
* @Date: 2016-12-26 11:55:57
*/
import React, { Component, PropTypes } from 'react';
import './index.css';
import Utils from './../../lib/utils';
import EditorFloatTag from './../editors/EditorFloatTag';
import SettingIcon from 'material-ui/svg-icons/action/settings';
import HelpIcon from 'material-ui/svg-icons/action/help';
import {emphasize} from 'material-ui/utils/colorManipulator';
import SvgIcon from 'material-ui/SvgIcon';
import FloatTag     from './../subcoms/FloatTag';
import {Tooltips}     from './../subcoms/FloatTag';



import _ from 'lodash';
// import FileCloudDownload from 'material-ui/svg-icons/file/cloud-download';

const empty = () => null;

export function getStyles(props, context) {
  const { palette } = context.muiTheme;
  const { style = {}, depth} = props;
  const height = style.height || 48;
  return {
    main: {
      normal: {
        height: height,
        background: style.background || style.backgroundColor || palette.alternateTextColor,
      },
      hover: {
        background: emphasize(palette.alternateTextColor, palette.emphasize1 || 0.05),
      }
    },
    name: {
      color: (props.nameStyle || {}).color || emphasize(palette.textColor, 0.4),
    },
    end: {
      flexGrow:(props.endStyle || {}).flexGrow || 1
    },
    depth:  {
      flexGrow: (props.depthGrow || 0.4) * depth || 0,
      minWidth: '10px'
    },
    body: {
      flexGrow: (props.bodyStyle || {}).flexGrow || 8,
    },
    helpIcon: {
      width:  height * 0.3,
      height: height * 0.3,
      color: emphasize(palette.textColor, 0.3)
    },
    helpIconHover: {
      color: emphasize(palette.textColor, 0.5)
    },
    floatTag: {
      boxSizing: 'border-box',
      fontSize: '12px',
      left: '0px'
    }
  };
}

export default class UiBase extends Component {
  static propTypes = {
    data:     PropTypes.object.isRequired,
    onChange: PropTypes.func.isRequired,
    onUITypeChange: PropTypes.func,
    children: PropTypes.array,
    editable: PropTypes.boolean,
    depth:    PropTypes.number,
    isBorder: PropTypes.boolean,
  }
  static defaultProps = {
    editable: true,
    disable:  false,
    onFinishChange: () => console.error('替换 props.onFinishChange'),
    onChange: () => console.error('替换 props.onChange'),
    heightPhi: 0.6,
    widthPhi:  0.9
  }
  static contextTypes = {
    muiTheme: PropTypes.object.isRequired,
  };
  constructor(props: any) {
    super(props)
    props = this.props;
    this.state = {
      isOpenEditor: props.isOpenEditor,
      isActive: false,
      isIconHover: false,
    };
  }
  componentWillMount(){
    this._extendState();
  }
  _getDepthStyle(){
    return getStyles(this.props, this.context).depth;
  }
  componentWillReceiveProps(newprops){
    const {isOpenEditor, data} = newprops;
    this.setState({
      data, isOpenEditor
    });
  }
  componentWillUpdate(newprops){
    return !_.isEqual(newprops.data, this.state.data) || !_.isEqual(newprops.uiThemeId, this.props.uiThemeId);
  }
  //为了一部分的重布局计算
  componentDidMount(){
    this._redraw();
    this._addEventResize();
    this._addEventKeyboard();
    // if(this.state.data.value) this.onChange(this.state.data);
  }
  _redraw = () => {
    this.setState({});
  }
  _extendState(){
    this.state = Object.assign(this.state, {
      data: _.cloneDeep(this.props.data)
    });
  }
  _genEditorIcon(){
    if(!this.props.editable) return null;

    const styleIcon = {
      fontSize: 10,
      transform: 'scale(0.8)',
      transformOrigin: '50% 50%',
      color: 'rgba(150,150,150,0.5)'
    };

    return (
      <SettingIcon 
        style={styleIcon} 
        onMouseOver={this.onEditorIconMouseOver}
        onMouseOut={this.onEditorIconMouseOut}
      />
    )
  }
  _genUI (){
    console.warn('必须继承这个方法')
  }
  _getDataObject(v){
    const {key} = this.state.data;
    return {[key]: v};
  }
  _getDefaultHeight(){
    return getStyles(this.props, this.context).main.normal.height;
  }
  _getSelectorStyle(){
    const width = `${Math.floor(this.props.widthPhi * 100)}%`;
    return { width, maxWidth: width };
  }
  onMouseOut = (e) => {
    this._unActive();
  }
  onMouseOver = () => {
    this._active();
  }
  _addEventResize(){
    //不是特别好实现，大部分组件也不需要
  }
  //键盘事件
  _addEventKeyboard(){
    Utils.onKeydown('Escape', () => {
      if(this.state.isOpenEditor) this.setState({isOpenEditor:false});
    });
  }
  _active(){
    if (!this.state.isActive) this.setState({isActive: true});
  }
  _unActive(){
    if (this.state.isActive)  this.setState({isActive: false});
  }

  onOpenEditClick = (e) => {
    if (!this.props.editable) return;
    this.setState({
      isOpenEditor: !this.state.isOpenEditor,
      isActive: false
    });
  }
  onEditorChange = (d) => {
    if (this.state.data.uiType !== d.uiType){
      return this.props.onUITypeChange(d, this.state.isOpenEditor);
    }
    this.setState({
      data: Utils.deepMerge(this.state.data, d)
    });
  }
  onEditorIconMouseOver = d => {
  }
  onEditorIconMouseOut = d => {
  }
  onChange = (...v) => {
    let value = v[v.length - 1];
    this.setState({
      data: Object.assign({}, this.state.data, {value})
    });
    //
    if(this._genFunc && this.props.compileFunction) value = this._genFunc();
    const d = this._getDataObject(value);
    (this.props.onChange || empty)(d, this.state.data, value);
  }
  _genEditor(){
    const editable = this.props.editable;
    if(!editable) return null;
    const controlEndStyle = {
      minWidth: this._getDefaultHeight(),
      opacity: this.state.isActive  ? 1 : 0,
    };
    return (
      <div className="z_control-end"
        onClick={this.onOpenEditClick}
        style={controlEndStyle}
      >
        {this._genEditorIcon()}
      </div>
    );
  }
  onIconMouseOut = () => {
    this.setState({
      isIconHover: false
    });
  }
  onIconMouseOver = () => {
    this.setState({
      isIconHover: true
    });
  }
  _genName(style){
    const {desc} = this.state.data;
    let iconStyle = this.state.isIconHover ? style.helpIcon : style.helpIconHover;
    iconStyle = Object.assign({}, style.helpIcon, iconStyle);
    const descHTML = desc ? (
      <div 
        className="z_desc_incon"
        ref="helpNode"
      >
        <HelpIcon  
          style={iconStyle}
          onMouseOver={this.onIconMouseOver}
          onMouseOut={this.onIconMouseOut}
        />
        {
        <FloatTag
          style={style.floatTag}
          isActive={this.state.isIconHover}
          component={this.refs.helpNode}
          direction="top"
        >
        {desc}
        </FloatTag>
        }
        {
          // <Tooltips 
          //   label={desc}
          //   show={this.state.isIconHover}
          //   node={this.refs.helpNode}
          // />
        }
      </div>) : null;
    return (
      <div 
        className="z_name_wrapper"
      >
        {this.state.data.name}
        {descHTML}
      </div>
    );
  }
  _getContainerStyle(){
    const lineN = 1;
    return this.props.style;
  }
  render() {
    const ui = this._genUI();
    const {state, props, context} = this;
    const totalStyle  = getStyles(props, context);
    const {main}  = totalStyle;
    const bgStyle = state.isActive || state.isOpenEditor ? Object.assign({}, main.normal, main.hover): main.normal;
    const heightScale = props.heightScale || 1;
    const style = Object.assign(bgStyle, this._getContainerStyle());

    //如果是普通的选择器 中间有一个分划线
    // const borderWidth = props.isBorder ? 1 : 0;
    // Object.assign(style, {borderTop: `${borderWidth}px solid rgba(255, 255, 255, 0.05)`});
    //深层嵌套的时候，左边有空间


    return (
      <div className="z_control-container" 
        style={style} 
        onMouseOut={this.onMouseOut}
        onMouseOver={this.onMouseOver}
        ref="mainContainer"
      > 
        <div className="z_control-depth-space" style={totalStyle.depth}> </div>
        <div className="z_control-name" style={totalStyle.name} title={state.data.name}> 
          {this._genName(totalStyle)}
        </div>
        <div className="z_control-body" style={totalStyle.body} ref="controlBody"> {ui} </div>
        {this._genEditor()}
        <EditorFloatTag 
          data={state.data}
          component={this.refs.mainContainer}
          isOpen={state.isOpenEditor}
          onBgClick={this.onOpenEditClick}
          onFinishChange={this.onEditorChange}
          onMouseOver={() => false}
          onMouseOut={() => false}
        />
      </div>
    );
  }
}
