text: import * as echarts from 'echarts/lib/echarts';
  import graphicGL from '../../util/graphicGL';
  import retrieve from '../../util/retrieve';
  import format from '../../util/format';
  import BarsGeometry from '../../util/geometry/Bars3DGeometry';
  import LabelsBuilder from '../../component/common/LabelsBuilder';
  import glmatrix from 'claygl/src/dep/glmatrix';
  import { getItemVisualColor, getItemVisualOpacity } from '../../util/visual';
  var vec3 = glmatrix.vec3;
  export default echarts.ChartView.extend({
    type: 'bar3D',
    __ecgl__: true,
    init: function (ecModel, api) {
      this.groupGL = new graphicGL.Node();
      this._api = api;
      this._labelsBuilder = new LabelsBuilder(256, 256, api);
      var self = this;
  
      this._labelsBuilder.getLabelPosition = function (dataIndex, position, distance) {
        if (self._data) {
          var layout = self._data.getItemLayout(dataIndex);
  
          var start = layout[0];
          var dir = layout[1];
          var height = layout[2][1];
          return vec3.scaleAndAdd([], start, dir, distance + height);
        } else {
          return [0, 0];
        }
      }; // Give a large render order.
  
  
      this._labelsBuilder.getMesh().renderOrder = 100;
    },
    render: function (seriesModel, ecModel, api) {
      // Swap barMesh
      var tmp = this._prevBarMesh;
      this._prevBarMesh = this._barMesh;
      this._barMesh = tmp;
  
      if (!this._barMesh) {
        this._barMesh = new graphicGL.Mesh({
          geometry: new BarsGeometry(),
          shadowDepthMaterial: new graphicGL.Material({
            shader: new graphicGL.Shader(graphicGL.Shader.source('ecgl.sm.depth.vertex'), graphicGL.Shader.source('ecgl.sm.depth.fragment'))
          }),
          // Only cartesian3D enable culling
          // FIXME Performance
          culling: seriesModel.coordinateSystem.type === 'cartesian3D',
          // Render after axes
          renderOrder: 10,
          // Render normal in normal pass
          renderNormal: true
        });
      }
  
      this.groupGL.remove(this._prevBarMesh);
      this.groupGL.add(this._barMesh);
      this.groupGL.add(this._labelsBuilder.getMesh());
      var coordSys = seriesModel.coordinateSystem;
  
      this._doRender(seriesModel, api);
  
      if (coordSys && coordSys.viewGL) {
        coordSys.viewGL.add(this.groupGL);
        var methodName = coordSys.viewGL.isLinearSpace() ? 'define' : 'undefine';
  
        this._barMesh.material[methodName]('fragment', 'SRGB_DECODE');
      }
  
      this._data = seriesModel.getData();
  
      this._labelsBuilder.updateData(this._data);
  
      this._labelsBuilder.updateLabels();
  
      this._updateAnimation(seriesModel);
    },
    _updateAnimation: function (seriesModel) {
      graphicGL.updateVertexAnimation([['prevPosition', 'position'], ['prevNormal', 'normal']], this._prevBarMesh, this._barMesh, seriesModel);
    },
    _doRender: function (seriesModel, api) {
      var data = seriesModel.getData();
      var shading = seriesModel.get('shading');
      var enableNormal = shading !== 'color';
      var self = this;
      var barMesh = this._barMesh;
      var shadingPrefix = 'ecgl.' + shading;
  
      if (!barMesh.material || barMesh.material.shader.name !== shadingPrefix) {
        barMesh.material = graphicGL.createMaterial(shadingPrefix, ['VERTEX_COLOR']);
      }
  
      graphicGL.setMaterialFromModel(shading, barMesh.material, seriesModel, api);
      barMesh.geometry.enableNormal = enableNormal;
      barMesh.geometry.resetOffset(); // Bevel settings
  
      var bevelSize = seriesModel.get('bevelSize');
      var bevelSegments = seriesModel.get('bevelSmoothness');
      barMesh.geometry.bevelSegments = bevelSegments;
      barMesh.geometry.bevelSize = bevelSize;
      var colorArr = [];
      var vertexColors = new Float32Array(data.count() * 4);
      var colorOffset = 0;
      var barCount = 0;
      var hasTransparent = false;
      data.each(function (idx) {
        if (!data.hasValue(idx)) {
          return;
        }
  
        var color = getItemVisualColor(data, idx);
        var opacity = getItemVisualOpacity(data, idx);
  
        if (opacity == null) {
          opacity = 1;
        }
  
        graphicGL.parseColor(color, colorArr);
        colorArr[3] *= opacity;
        vertexColors[colorOffset++] = colorArr[0];
        vertexColors[colorOffset++] = colorArr[1];
        vertexColors[colorOffset++] = colorArr[2];
        vertexColors[colorOffset++] = colorArr[3];
  
        if (colorArr[3] > 0) {
          barCount++;
  
          if (colorArr[3] < 0.99) {
            hasTransparent = true;
          }
        }
      });
      barMesh.geometry.setBarCount(barCount);
      var orient = data.getLayout('orient'); // Map of dataIndex and barIndex.
  
      var barIndexOfData = this._barIndexOfData = new Int32Array(data.count());
      var barCount = 0;
      data.each(function (idx) {
        if (!data.hasValue(idx)) {
          barIndexOfData[idx] = -1;
          return;
        }
  
        var layout = data.getItemLayout(idx);
        var start = layout[0];
        var dir = layout[1];
        var size = layout[2];
        var idx4 = idx * 4;
        colorArr[0] = vertexColors[idx4++];
        colorArr[1] = vertexColors[idx4++];
        colorArr[2] = vertexColors[idx4++];
        colorArr[3] = vertexColors[idx4++];
  
        if (colorArr[3] > 0) {
          self._barMesh.geometry.addBar(start, dir, orient, size, colorArr, idx);
  
          barIndexOfData[idx] = barCount++;
        }
      });
      barMesh.geometry.dirty();
      barMesh.geometry.updateBoundingBox();
      var material = barMesh.material;
      material.transparent = hasTransparent;
      material.depthMask = !hasTransparent;
      barMesh.geometry.sortTriangles = hasTransparent;
  
      this._initHandler(seriesModel, api);
    },
    _initHandler: function (seriesModel, api) {
      var data = seriesModel.getData();
      var barMesh = this._barMesh;
      var isCartesian3D = seriesModel.coordinateSystem.type === 'cartesian3D';
      barMesh.seriesIndex = seriesModel.seriesIndex;
      var lastDataIndex = -1;
      barMesh.off('mousemove');
      barMesh.off('mouseout');
      barMesh.on('mousemove', function (e) {
        var dataIndex = barMesh.geometry.getDataIndexOfVertex(e.triangle[0]);
  
        if (dataIndex !== lastDataIndex) {
          this._downplay(lastDataIndex);
  
          this._highlight(dataIndex);
  
          this._labelsBuilder.updateLabels([dataIndex]);
  
          if (isCartesian3D) {
            api.dispatchAction({
              type: 'grid3DShowAxisPointer',
              value: [data.get('x', dataIndex), data.get('y', dataIndex), data.get('z', dataIndex, true)]
            });
          }
        }
  
        lastDataIndex = dataIndex;
        barMesh.dataIndex = dataIndex;
      }, this);
      barMesh.on('mouseout', function (e) {
        this._downplay(lastDataIndex);
  
        this._labelsBuilder.updateLabels();
  
        lastDataIndex = -1;
        barMesh.dataIndex = -1;
  
        if (isCartesian3D) {
          api.dispatchAction({
            type: 'grid3DHideAxisPointer'
          });
        }
      }, this);
    },
    _highlight: function (dataIndex) {
      var data = this._data;
  
      if (!data) {
        return;
      }
  
      var barIndex = this._barIndexOfData[dataIndex];
  
      if (barIndex < 0) {
        return;
      }
  
      var itemModel = data.getItemModel(dataIndex);
      var emphasisItemStyleModel = itemModel.getModel('emphasis.itemStyle');
      var emphasisColor = emphasisItemStyleModel.get('color');
      var emphasisOpacity = emphasisItemStyleModel.get('opacity');
  
      if (emphasisColor == null) {
        var color = getItemVisualColor(data, dataIndex);
        emphasisColor = echarts.color.lift(color, -0.4);
      }
  
      if (emphasisOpacity == null) {
        emphasisOpacity = getItemVisualOpacity(data, dataIndex);
      }
  
      var colorArr = graphicGL.parseColor(emphasisColor);
      colorArr[3] *= emphasisOpacity;
  
      this._barMesh.geometry.setColor(barIndex, colorArr);
  
      this._api.getZr().refresh();
    },
    _downplay: function (dataIndex) {
      var data = this._data;
  
      if (!data) {
        return;
      }
  
      var barIndex = this._barIndexOfData[dataIndex];
  
      if (barIndex < 0) {
        return;
      }
  
      var color = getItemVisualColor(data, dataIndex);
      var opacity = getItemVisualOpacity(data, dataIndex);
      var colorArr = graphicGL.parseColor(color);
      colorArr[3] *= opacity;
  
      this._barMesh.geometry.setColor(barIndex, colorArr);
  
      this._api.getZr().refresh();
    },
    highlight: function (seriesModel, ecModel, api, payload) {
      this._toggleStatus('highlight', seriesModel, ecModel, api, payload);
    },
    downplay: function (seriesModel, ecModel, api, payload) {
      this._toggleStatus('downplay', seriesModel, ecModel, api, payload);
    },
    _toggleStatus: function (status, seriesModel, ecModel, api, payload) {
      var data = seriesModel.getData();
      var dataIndex = retrieve.queryDataIndex(data, payload);
      var self = this;
  
      if (dataIndex != null) {
        echarts.util.each(format.normalizeToArray(dataIndex), function (dataIdx) {
          status === 'highlight' ? this._highlight(dataIdx) : this._downplay(dataIdx);
        }, this);
      } else {
        data.each(function (dataIdx) {
          status === 'highlight' ? self._highlight(dataIdx) : self._downplay(dataIdx);
        });
      }
    },
    remove: function () {
      this.groupGL.removeAll();
    },
    dispose: function () {
      this.groupGL.removeAll();
    }
  });