import * as Three from 'three';
import React from 'react';

const WIDTH=90;
const DEPTH=40;
const HEIGHT=30;


const black = new Three.MeshLambertMaterial({color:0x000000});
black.side = Three.DoubleSide;

// const objectMaxLOD = makeObjectMaxLOD();
// const objectMinLOD = makeObjectMinLOD();


function makeObjectMaxLOD(element) {

  let grey = null;  
  let darkGrey = null;  

  if(element.get("selected")){
    grey = new Three.MeshLambertMaterial({color: "green", opacity: 0.8});
    darkGrey = new Three.MeshLambertMaterial({color: "green", opacity: 0.8});
  }else if(element.getIn(["properties", "associate", "thing"])!="-"){
      grey = new Three.MeshLambertMaterial( {color: element.getIn(["properties", "associate", "hoverColor"])} );
      darkGrey = new Three.MeshLambertMaterial( {color: element.getIn(["properties", "associate", "hoverColor"])} );
    
  }else{

    grey = new Three.MeshLambertMaterial( {color: 0xaaaaaa} );  
    darkGrey = new Three.MeshLambertMaterial( {color: 0x808287} );  

  }


  grey.side = Three.DoubleSide;
  darkGrey.side = Three.DoubleSide;

  let air_conditioner = new Three.Mesh();
  let roundedRectShape = new Three.Shape();
  let x=0;
  let y=0;
  let width=.15;
  let height=.6;
  let radius=0.15;

  roundedRectShape.moveTo( x, y );
  roundedRectShape.lineTo( x + width, y);
  roundedRectShape.lineTo( x + width + radius, y + radius);
  roundedRectShape.quadraticCurveTo( x + width + radius, y + height, x + width/2, y + height );
  roundedRectShape.lineTo( x + width/2, y+height );
  roundedRectShape.lineTo( x, y + height) ;


  let extrudeSettings = {
    steps: 2,
    depth: 1,
    bevelEnabled: false,
    bevelThickness: 1,
    bevelSize: 1,
    bevelSegments: 1
  };

  let bodyGeometry = new Three.ExtrudeGeometry( roundedRectShape, extrudeSettings );
  let body = new Three.Mesh( bodyGeometry, grey );

  body.position.set(-.11,1.2,0);
  body.rotation.z+=Math.PI;
  air_conditioner.add(body);

  let j=1.18;

  for (let i = -.30; i > -.36; i-=.005) {

    let gridHorizontalGeometry = new Three.BoxGeometry(.001, .025, .705);
    let gridHorizontal = new Three.Mesh(gridHorizontalGeometry, darkGrey);
    gridHorizontal.position.set(i,j,.5);
    gridHorizontal.rotation.z+=Math.PI/4;
    air_conditioner.add(gridHorizontal);
    j-=.005
  }

  for (let k = .15; k < .87; k+=.05) {
    let gridVerticalGeometry = new Three.BoxGeometry(.079, .025, .005);
    let gridVertical = new Three.Mesh(gridVerticalGeometry, darkGrey);
    gridVertical.position.set(-.324,1.148,k);
    gridVertical.rotation.z+=Math.PI/4;
    air_conditioner.add(gridVertical);
  }


  let roundedRectShape2 = new Three.Shape();

  let x2=0;
  let y2=0;
  let width2=.2;
  let height2=.4;
  let radius2=0.15;

  roundedRectShape2.moveTo( x2, y2 );
  roundedRectShape2.lineTo( x2 + width2, y2);
  roundedRectShape2.quadraticCurveTo( x2 + width2 + radius2, y2 + height2, x2 + width2/2, y2 + height2 );
  roundedRectShape2.lineTo( x2 + width2/2, y2+height2 );
  roundedRectShape2.quadraticCurveTo( x2 + width2 + radius2, y2 + height2/4, x2 , y2 );


  let extrudeSettings2 = {
    steps: 2,
    depth: 1,
    bevelEnabled: false,
    bevelThickness: 1,
    bevelSize: 1,
    bevelSegments: 1
  };

  let frontCoverGeometry = new Three.ExtrudeGeometry( roundedRectShape2, extrudeSettings2 );
  let frontCover = new Three.Mesh( frontCoverGeometry, grey) ;

  frontCover.position.set(-.2,1.1,0);
  frontCover.rotation.z+=Math.PI;
  air_conditioner.add(frontCover);

  let roundedRectShape3 = new Three.Shape();

  let x3=0;
  let y3=0;
  let width3=.1;
  let height3=.1;
  let radius3=0.15;

  roundedRectShape3.moveTo( x3, y3 );
  roundedRectShape3.quadraticCurveTo( x3 - width3/2 + radius3/2, y3 - height3, x3 + width3, y3);
  roundedRectShape3.lineTo( x3 + width3, y3);
  roundedRectShape3.quadraticCurveTo( x3 + width3/2 + radius3/2, y3 + 2 * height3, x3 + width3/2, y3 + height3 );
  roundedRectShape3.lineTo( x3 + width3/2, y3 + height3 );
  roundedRectShape3.quadraticCurveTo( x3 + width3/4, y3 + height3/6, x3 , y3 );

  let extrudeSettings3 = {
    steps: 2,
    depth: .1,
    bevelEnabled: false,
    bevelThickness: 1,
    bevelSize: 1,
    bevelSegments: 1
  };

  let flapSupportGeometry = new Three.ExtrudeGeometry( roundedRectShape3, extrudeSettings3 );
  let flapLeft = new Three.Mesh( flapSupportGeometry, darkGrey ) ;

  flapLeft.position.set(-.27,.62,0.1);
  flapLeft.rotation.y+=Math.PI;
  flapLeft.rotation.z-=Math.PI/9;
  air_conditioner.add(flapLeft);

  let flapRight = new Three.Mesh( flapSupportGeometry, darkGrey ) ;

  flapRight.position.set(-.27,.62,1);
  flapRight.rotation.y+=Math.PI;
  flapRight.rotation.z-=Math.PI/9;
  air_conditioner.add(flapRight);

  let points2 = [];

  points2.push( new Three.Vector3(.5, 0));
  points2.push( new Three.Vector3(.5, 0));
  points2.push( new Three.Vector3(.5, .8));
  points2.push( new Three.Vector3(.5, .8));

  let flapGeometry = new Three.LatheGeometry( points2, 200, Math.PI/2, Math.PI/16 );
  let flap1 = new Three.Mesh( flapGeometry, darkGrey );

  flap1.position.set(-.4,.18,.9);
  flap1.rotation.z+=Math.PI/2;
  flap1.rotation.y+=-Math.PI/2;

  air_conditioner.add(flap1);

  let flap2 = new Three.Mesh( flapGeometry, darkGrey );

  flap2.position.set(-.4,.15,.9);
  flap2.rotation.z+=Math.PI/2;
  flap2.rotation.y+=-Math.PI/2;

  air_conditioner.add(flap2);

  return air_conditioner
}

function makeObjectMinLOD(element) {

  let grey = null;  
  let darkGrey = null;  

  if(element.get("selected")){
    grey = new Three.MeshLambertMaterial({color: "green", opacity: 0.8});
    darkGrey = new Three.MeshLambertMaterial({color: "green", opacity: 0.8});
  }else if(element.getIn(["properties", "associate", "thing"])!="-"){
      grey = new Three.MeshLambertMaterial( {color: element.getIn(["properties", "associate", "hoverColor"])} );
      darkGrey = new Three.MeshLambertMaterial( {color: element.getIn(["properties", "associate", "hoverColor"])} );
    
  }else{

    grey = new Three.MeshLambertMaterial( {color: 0xaaaaaa} );  
    darkGrey = new Three.MeshLambertMaterial( {color: 0x808287} );  

  }

  grey.side = Three.DoubleSide;
  darkGrey.side = Three.DoubleSide;

  let air_conditioner = new Three.Mesh();

  let roundedRectShape = new Three.Shape();

  let x=0;
  let y=0;
  let width=.15;
  let height=.6;
  let radius=0.15;

  roundedRectShape.moveTo( x, y );
  roundedRectShape.lineTo( x + width, y);
  roundedRectShape.lineTo( x + width + radius, y + radius);
  roundedRectShape.quadraticCurveTo( x + width + radius, y + height, x + width/2, y + height );
  roundedRectShape.lineTo( x + width/2, y+height );
  roundedRectShape.lineTo( x, y + height) ;


  let extrudeSettings = {
    steps: 2,
    depth: 1,
    bevelEnabled: false,
    bevelThickness: 1,
    bevelSize: 1,
    bevelSegments: 1
  };

  let bodyGeometry = new Three.ExtrudeGeometry( roundedRectShape, extrudeSettings );
  let body = new Three.Mesh( bodyGeometry, grey );

  body.position.set(-.11,1.2,0);
  body.rotation.z+=Math.PI;
  air_conditioner.add(body);

  let roundedRectShape2 = new Three.Shape();

  let x2=0;
  let y2=0;
  let width2=.2;
  let height2=.4;
  let radius2=0.15;

  roundedRectShape2.moveTo( x2, y2 );
  roundedRectShape2.lineTo( x2 + width2, y2);
  roundedRectShape2.quadraticCurveTo( x2 + width2 + radius2, y2 + height2, x2 + width2/2, y2 + height2 );
  roundedRectShape2.lineTo( x2 + width2/2, y2+height2 );
  roundedRectShape2.quadraticCurveTo( x2 + width2 + radius2, y2 + height2/4, x2 , y2 );

  let extrudeSettings2 = {
    steps: 2,
    depth: 1,
    bevelEnabled: false,
    bevelThickness: 1,
    bevelSize: 1,
    bevelSegments: 1
  };

  let frontCoverGeometry = new Three.ExtrudeGeometry( roundedRectShape2, extrudeSettings2 );

  let frontCover = new Three.Mesh( frontCoverGeometry, grey) ;

  frontCover.position.set(-.2,1.1,0);
  frontCover.rotation.z+=Math.PI;
  air_conditioner.add(frontCover);

  return air_conditioner
}

export default {
  name: 'conditioner',
  prototype: 'items',

  info: {
    tag: ['furnishings', 'metal'],
    title: 'air conditioner',
    description: 'air conditioner',
    image: require('./air_conditioner.png')
  },
  properties: {
    altitude: {
      label: 'quota',
      type: 'length-measure',
      defaultValue: {
        length: 220,
        unit: 'cm'
      }
    },

    
    associate: {
      label: "Associate",
      type: "associate",
      defaultValue:{
        category: "-",
        thing: "-",
        thingName: "",
        popUp: "model",
        hoverColor: "#ffffff"
      }
    }
  },

  render2D: function (element, layer, scene) {

    let angle = element.rotation + 90;
    let textRotation = 0;
    if (Math.sin(angle * Math.PI / 180) < 0) {
      textRotation = 180;
    }

    return (
      <g transform={`translate(${-WIDTH / 2},${-DEPTH / 2})`}>
        <rect key='1' x='0' y='0' width={WIDTH} height={DEPTH}
              style={{stroke: element.selected ? '#0096fd' : '#000', strokeWidth: '2px', fill: '#84e1ce'}}/>
        <text key='2' x='0' y='0'
              transform={`translate(${WIDTH / 2}, ${DEPTH / 2}) scale(1,-1) rotate(${textRotation})`}
              style={{textAnchor: 'middle', fontSize: '11px'}}>
          {element.name}
        </text>

        {(element.properties.get("associate"))&&<text key='3' x='0' y='10'
              transform={`translate(${WIDTH / 2}, ${DEPTH / 2}) scale(1,-1) rotate(${textRotation})`}
              style={{textAnchor: 'middle', fontSize: '11px', fill: "red"}}>
          {element.properties.get("associate").get("thingName")}
        </text>}
      </g>
    )
  },

  render3D: function (element, layer, scene) {

    let newAltitude = element.properties.get('altitude').get('length');

    /*************** lod max *******************/

    let air_conditionerMaxLOD = new Three.Object3D();
    let objectMaxLOD = makeObjectMaxLOD(element);
    let objectMinLOD = makeObjectMinLOD(element);
    air_conditionerMaxLOD.add(objectMaxLOD.clone());

    let value = new Three.Box3().setFromObject(air_conditionerMaxLOD);

    let deltaX = Math.abs(value.max.x - value.min.x);
    let deltaY = Math.abs(value.max.y - value.min.y);
    let deltaZ = Math.abs(value.max.z - value.min.z);

    air_conditionerMaxLOD.position.x+= WIDTH/2.2;
    air_conditionerMaxLOD.position.z+= DEPTH/1.2;
    air_conditionerMaxLOD.position.y+= newAltitude;
    air_conditionerMaxLOD.rotation.y+= -Math.PI/2;
    air_conditionerMaxLOD.scale.set(WIDTH / deltaZ, HEIGHT / deltaY, DEPTH / deltaX/1.4);


    /*************** lod min *******************/

    let air_conditionerMinLOD = new Three.Object3D();
    air_conditionerMinLOD.add(objectMinLOD.clone());
    air_conditionerMinLOD.position.x+= WIDTH/2.2;
    air_conditionerMinLOD.position.z+= DEPTH/1.2;
    air_conditionerMinLOD.position.y+= newAltitude;
    air_conditionerMinLOD.rotation.y+= -Math.PI/2;
    air_conditionerMinLOD.scale.set(WIDTH / deltaZ, HEIGHT / deltaY, DEPTH / deltaX/1.4);

    /**** all level of detail ***/

    let lod = new Three.LOD();

    lod.addLevel(air_conditionerMaxLOD, 200);
    lod.addLevel(air_conditionerMinLOD, 900);
    lod.updateMatrix();
    lod.matrixAutoUpdate = false;

    // if (element.selected) {
    //   let bbox = new Three.BoxHelper(lod, "green");
    //   bbox.material.linewidth = 5;
    //   bbox.renderOrder = 1000;
    //   bbox.material.depthTest = false;
    //   lod.add(bbox);
    // }

    return Promise.resolve(lod);
  }

};

