import React, {Component} from 'react'
import { Button } from 'antd';
import { PageContainer } from '@ant-design/pro-components';
import QueenEngine, {kQueenBeautyType, kQueenBeautyParams, kQueenBeautyMakeupType, kQueenBeautyFaceShapeType, kQueenBeautyBlend,} from "../../queensdk"
import styles from './index.less';
import { EMsgid, tracker } from '@/utils/stat';
class TexturePage extends Component{
  private queenEngine: any;
  private queenEnabled: boolean;
  private progObj: any;
  constructor(props:any) {
    super(props)
    this.queenEngine = null;
    this.progObj = null;
    this.queenEnabled = false;
    this.state = {
     
    }
  }

  /**
   * 基于纹理渲染，初始化时需要显示指定渲染的canvas
   */
  queenInitialize = () =>{
    const self = this;
    const queenCanvasId = "queenCanvas";
    const startTime = performance.now();
    this.queenEngine = new QueenEngine();
    this.queenEngine.initialize("./", "", function(){
      tracker.queenInitReport({ms: performance.now() - startTime});
      window.setInterval(()=>{
        self.renderEffect();
      }, 33);
    }, function(progress: number){
      self.setState({loadProgress: progress});
    }, queenCanvasId);
  }

  queenEffect = ()=>{
    this.testBaseFaceBeauty();
    this.testAdvancedFaceBeauty();
  }

  /**
   * 基础美颜
   */
  testBaseFaceBeauty() {
    this.queenEnabled = true;
    // 打开磨皮锐化功能开关
    this.queenEngine.setQueenBeautyType(kQueenBeautyType.SkinBuffing, true);
    // 设置磨皮系数
    this.queenEngine.setQueenBeautyParams(kQueenBeautyParams.SkinBuffing, 0.9);
    // 设置锐化系数
    this.queenEngine.setQueenBeautyParams(kQueenBeautyParams.Sharpen, 0.5);

    // 打开美白功能开关
    this.queenEngine.setQueenBeautyType(kQueenBeautyType.SkinWhiting, true);

    // 设置美白系数
    this.queenEngine.setQueenBeautyParams(kQueenBeautyParams.Whitening, 0.5);
  }

  /**
   * 高级美颜
   */
  testAdvancedFaceBeauty() {
    this.queenEnabled = true;
    //高级美颜
    this.queenEngine.setQueenBeautyType(kQueenBeautyType.FaceBuffing, true);
    // 设置去眼袋系数
    this.queenEngine.setQueenBeautyParams(kQueenBeautyParams.Pouch, 0.9);
    // 设置去法令纹系数
    this.queenEngine.setQueenBeautyParams(kQueenBeautyParams.NasolabialFolds, 0.9);
    // 设置白牙系数
    this.queenEngine.setQueenBeautyParams(kQueenBeautyParams.WhiteTeeth, 0.9);
    // 设置口红系数
    this.queenEngine.setQueenBeautyParams(kQueenBeautyParams.Lipstick, 0.1);
    // 设置腮红系数
    this.queenEngine.setQueenBeautyParams(kQueenBeautyParams.Blush, 0.1);
    // 设置口红色相系数
    this.queenEngine.setQueenBeautyParams(kQueenBeautyParams.LipstickColorParam, 0.1);
    // 设置口红饱和度系数
    this.queenEngine.setQueenBeautyParams(kQueenBeautyParams.LipstickGlossParam, 0.3);
    // 设置口红明度系数
    this.queenEngine.setQueenBeautyParams(kQueenBeautyParams.LipstickBrightnessParam, 0.3);
    // 设置亮眼系数
    this.queenEngine.setQueenBeautyParams(kQueenBeautyParams.BrightenEye, 0.9);
    // 设置红润系数
    this.queenEngine.setQueenBeautyParams(kQueenBeautyParams.SkinRed, 0.2);
    // 设置去皱纹系数
    this.queenEngine.setQueenBeautyParams(kQueenBeautyParams.Wrinkles, 0.9);
    // 设置去暗沉系数
    this.queenEngine.setQueenBeautyParams(kQueenBeautyParams.BrightenFace, 0.3);
  }

   //美型
   testFaceShape =()=> {
    this.queenEnabled = true;
    // 打开美型功能开关
    this.queenEngine.setQueenBeautyType(kQueenBeautyType.FaceShape, true);
    // 设置大眼系数
    this.queenEngine.setFaceShape(kQueenBeautyFaceShapeType.BigEye, 0.9);
    // 设置发际线系数
    this.queenEngine.setFaceShape(kQueenBeautyFaceShapeType.HairLine, 1.0);
    // 设置嘴角上扬(微笑)系数
    this.queenEngine.setFaceShape(kQueenBeautyFaceShapeType.Smile, 0.5);
  }

  testFaceMakeup=()=>{
    this.applyFaceMakeup();
  }

  async applyFaceMakeup(){
    this.queenEnabled = true;
    this.queenEngine.setQueenBeautyType(kQueenBeautyType.Makeup, true);
    // 设置美妆口红效果的透明度，目前female参数的值统一传YES/true，男性妆容还在优化中    
    const mouthMakeupPackageUrl = "queen_res/makeup/mouth_yaochun/shiliuhong.1.2.3.bin";
    await this.queenEngine.setMakeupWithPackage(kQueenBeautyMakeupType.Mouth, mouthMakeupPackageUrl, "1.2.3.png", kQueenBeautyBlend.LabMix);
    this.queenEngine.setMakeupAlphaWithType(kQueenBeautyMakeupType.Mouth, true, 1.0);

    // 设置美妆眉毛效果的透明度，目前female参数的值统一传YES/true，男性妆容还在优化中    
    const eyeBrowMakeupPackageUrl = "queen_res/makeup/eyebrow/biaozhunmei.2.3.bin";
    await this.queenEngine.setMakeupWithPackage(kQueenBeautyMakeupType.EyeBrow, eyeBrowMakeupPackageUrl, "biaozhunmei.2.3.png", kQueenBeautyBlend.Multiply);
    this.queenEngine.setMakeupAlphaWithType(kQueenBeautyMakeupType.EyeBrow, true, 0.5);

    //设置美妆睫毛效果的透明度，目前female参数的值统一传YES/true，男性妆容还在优化中    
    const eyeashMakeupUrl = "queen_res/makeup/eyelash/chenjing.2.3.png";
    await this.queenEngine.setMakeupWithUrl(kQueenBeautyMakeupType.Eyelash, eyeashMakeupUrl, kQueenBeautyBlend.Multiply);
    this.queenEngine.setMakeupAlphaWithType(kQueenBeautyMakeupType.Eyelash, true, 0.6);
    
    // 设置美妆腮红效果的透明度，目前female参数的值统一传YES/true，男性妆容还在优化中
    const blushMakeupUrl = "queen_res/makeup/blush/blush_wugu.2.3.png";
    await this.queenEngine.setMakeupWithUrl(kQueenBeautyMakeupType.Blush, blushMakeupUrl, kQueenBeautyBlend.LabMix);
    this.queenEngine.setMakeupAlphaWithType(kQueenBeautyMakeupType.Blush, true, 0.6);
  }

  /**
   * 开始美颜
   */
  applyEffect = ()=>{
    this.queenEffect();
  }

  /**
   * 增加头像贴纸
   */
  async addSticker(){
    this.queenEnabled = true;
    const sticker1 =  "queen_res/sticker/9.bin";
    await this.queenEngine.addMaterialWithUrl(sticker1);

    const sticker2 =  "queen_res/sticker/10.bin";
    await this.queenEngine.addMaterialWithUrl(sticker2);
  }

  /**
   * 设置滤镜效果
   */
  applyFilterEffect = () =>{
    const self = this;
    this.queenEnabled = true;
    const filterUrl = "queen_res/lookups/A3.png";
    // 资源配置
    this.queenEngine.setLutImageUrl(filterUrl).then(function(){
      // 打开滤镜功能开关
      self.queenEngine.setQueenBeautyType(kQueenBeautyType.LUT, true);
      // 设置滤镜强度
      self.queenEngine.setQueenBeautyParams(kQueenBeautyParams.LUT, 0.5);
    });
  }

  /**
   * 头像贴纸
   */
  applyStickerEffect = ()=>{
    this.queenEnabled = true;
    this.addSticker();
  }

  /**
   * 背景虚化
   */
  bokehBackground = () =>{
    this.queenEnabled = true;
    this.queenEngine.setSegmentBackgroundUrl("");
    this.queenEngine.enableBokehBackground(true);
  }

  /**
   * 背景抠图
   */
  cutoutBackground = () =>{
    this.queenEnabled = true;
    let backgroundPath = "queen_res/background/b2.png";
    this.queenEngine.enableBokehBackground(false);
    this.queenEngine.setSegmentBackgroundUrl(backgroundPath).then(()=>{
    });
  }

  /**
   * 美颜效果重置
   */
  resetEffect = () =>{
    this.queenEngine.setQueenBeautyType(kQueenBeautyType.FaceShape, false);
    this.queenEngine.setQueenBeautyType(kQueenBeautyType.Makeup, false);

    this.queenEngine.enableBokehBackground(false);
    this.queenEngine.setSegmentBackgroundUrl("").then(()=>{
    });
   
    const sticker1 =  "queen_res/sticker/9.bin";
    this.queenEngine.removeMaterialWithUrl(sticker1);

    const sticker2 =  "queen_res/sticker/10.bin";
    this.queenEngine.removeMaterialWithUrl(sticker2);

    this.queenEngine.setLutImageUrl("").then(()=>{});
  }

  renderEffect(){
    if(this.queenEnabled === false){
      return;
    }
    const self = this;
    const sourceVideo = document.getElementById("source");
    if(sourceVideo?.srcObject){
        let startTime = performance.now();
        let outTexture = this.queenEngine.renderMediaObjectToTexture(sourceVideo, sourceVideo.clientWidth, sourceVideo.clientHeight);
        tracker.queenRenderReport({ts: performance.now() - startTime});
        self.drawImageTexture(outTexture, sourceVideo.clientWidth, sourceVideo.clientHeight);
    }    
  }

  drawImageTexture(texture: any, width: number, height: number) {  
    const gl = document.getElementById("queenCanvas").getContext("webgl2");
    if(gl === null){
      return;
    }
    if(this.progObj === null){
      let vertexShaderSrc =
      "attribute vec2 aVertex;" +
      "attribute vec2 aUV;" +
      "varying vec2 vTex;" +
      "uniform vec2 pos;" +
      "void main(void) {" +
      "  gl_Position = vec4(aVertex + pos, 0.0, 1.0);" +
      "  vTex = aUV;" +
      "}";
  
      let fragmentShaderSrc =
      "precision highp float;" +
      "varying vec2 vTex;" +
      "uniform sampler2D sampler0;" +
      "void main(void){" +
      "  gl_FragColor = texture2D(sampler0, vTex);" +
      "}";
      const vertShaderObj = gl.createShader(gl.VERTEX_SHADER);
      const fragShaderObj = gl.createShader(gl.FRAGMENT_SHADER);
      gl.shaderSource(vertShaderObj, vertexShaderSrc);
      gl.shaderSource(fragShaderObj, fragmentShaderSrc);
      gl.compileShader(vertShaderObj);
      gl.compileShader(fragShaderObj);
    
      this.progObj = gl.createProgram();
      gl.attachShader(this.progObj, vertShaderObj);
      gl.attachShader(this.progObj, fragShaderObj);
    
      gl.linkProgram(this.progObj);
    }
    gl.useProgram(this.progObj);
    gl.viewport(0, 0, width, height);
    let vertexBuff = gl.createBuffer();
    gl.bindBuffer(gl.ARRAY_BUFFER, vertexBuff); 
    gl.bufferData(gl.ARRAY_BUFFER, new Float32Array([-1, -1,   -1,  1,   1, 1,  1, -1]), gl.STATIC_DRAW);//正常
  
    let texBuff = gl.createBuffer();
    gl.bindBuffer(gl.ARRAY_BUFFER, texBuff);
    gl.bufferData(gl.ARRAY_BUFFER, new Float32Array([0, 1, 0, 0, 1, 0, 1, 1]), gl.STATIC_DRAW);
  
    let vloc = gl.getAttribLocation(this.progObj, "aVertex");
    let tloc = gl.getAttribLocation(this.progObj, "aUV");
  
    gl.enableVertexAttribArray(vloc);
    gl.bindBuffer(gl.ARRAY_BUFFER, vertexBuff);
    gl.vertexAttribPointer(vloc, 2, gl.FLOAT, false, 0, 0);
  
    gl.enableVertexAttribArray(tloc);
    gl.bindBuffer(gl.ARRAY_BUFFER, texBuff);
    gl.activeTexture(gl.TEXTURE0);
    gl.bindTexture(gl.TEXTURE_2D, texture);
    gl.vertexAttribPointer(tloc, 2, gl.FLOAT, false, 0, 0);

  
    gl.drawArrays(gl.TRIANGLE_FAN, 0, 4);
    gl.disableVertexAttribArray(vloc);
    gl.disableVertexAttribArray(tloc);
    gl.bindTexture(gl.TEXTURE_2D, null);
  }

  openCamera =(constraints: MediaStreamConstraints)=> {
    const self = this;
    navigator.mediaDevices.getUserMedia(constraints)
    .then(mediaStream => {
      const sourceVideo = document.getElementById("source");
      if(sourceVideo){
        sourceVideo.srcObject = mediaStream;
        sourceVideo.play();
        sourceVideo.addEventListener('play', function () { 
          self.queenInitialize();
        });  
      }
    }); 
  }   

  componentDidMount(){
    tracker.actionReport(EMsgid.PAGELOAD);
    let constraints = { audio: false, video: { mandatory: { maxWidth: 1280, maxHeight: 960 }}};
    this.openCamera(constraints);        
  }

  componentWillUnmount(){
    this.queenEnabled = false;
    const videoElem = document.querySelector('video');
    if(videoElem?.srcObject){
      const stream = videoElem.srcObject;
      const tracks = stream.getTracks();
      tracks.forEach(function(track) {
        track.stop();
      });
      videoElem.srcObject = null;
    }   
  }

  render() {
    return (
    <>
    <PageContainer>
      <div className=''>
        渲染到纹理，<a href='https://queen.aliyuncs.com' target='blank'>查看完整Demo</a>
      </div>      
      <div className={styles.action}>
      <Button type="default" onClick={this.applyEffect} >美颜</Button>
      <Button type="default" onClick={this.testFaceShape} >美型</Button>
      <Button type="default" onClick={this.testFaceMakeup} >美妆</Button>
      <Button type="default" onClick={this.applyFilterEffect} >滤镜</Button>
      <Button type="default" onClick={this.bokehBackground} >背景虚化</Button>
      <Button type="default" onClick={this.cutoutBackground} >背景抠图</Button>
      <Button type="default" onClick={this.applyStickerEffect} >头像贴纸</Button>
      <Button type="default" onClick={this.resetEffect} >重置</Button>
      </div>
      <div className={styles.container}>
        <video controls={false} id="source" width="680" height="510"/>
        <canvas id="queenCanvas" width="680" height="510" />
      </div>
      <div id="testDiv"></div>
    </PageContainer>
    </>
  );
};
}
export default TexturePage;
