import * as THREE from 'three';

import PropTypes from 'react/lib/ReactPropTypes';

import MaterialDescriptorBase from './MaterialDescriptorBase';
import UniformContainer from '../../UniformContainer';

class ShaderMaterialDescriptor extends MaterialDescriptorBase {
  constructor(react3RendererInstance) {
    super(react3RendererInstance);

    [
      'vertexShader',
      'fragmentShader',
    ].forEach((propName) => {
      this.hasProp(propName, {
        type: PropTypes.string,
        update: this.triggerRemount,
      });
    });

    this.hasProp('uniforms', {
      type: PropTypes.any,
      simple: true,
      default: undefined,
    });

    this.hasWireframe();
  }

  getMaterialDescription(props) {
    const materialDescription = super.getMaterialDescription(props);

    if (props.hasOwnProperty('uniforms')) {
      materialDescription.uniforms = props.uniforms;
    }

    if (props.hasOwnProperty('vertexShader')) {
      materialDescription.vertexShader = props.vertexShader;
    }

    if (props.hasOwnProperty('fragmentShader')) {
      materialDescription.fragmentShader = props.fragmentShader;
    }

    return materialDescription;
  }

  construct(props) {
    const materialDescription = this.getMaterialDescription(props);

    return new THREE.ShaderMaterial(materialDescription);
  }

  invalidChildInternal(child) {
    return !(child instanceof UniformContainer || super.invalidChildInternal(child));
  }

  applyInitialProps(threeObject, props) {
    super.applyInitialProps(threeObject, props);

    if (!props.hasOwnProperty('uniforms')) {
      threeObject.uniforms = {};
    }
  }
}

module.exports = ShaderMaterialDescriptor;
