/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements.  See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership.  The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License.  You may obtain a copy of the License at
*
*   http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied.  See the License for the
* specific language governing permissions and limitations
* under the License.
*/

/* global Float32Array */
// TODO Batch by color
import * as graphic from '../../util/graphic';
import { createSymbol } from '../../util/symbol';
import IncrementalDisplayable from 'zrender/src/graphic/IncrementalDisplayable';
var BOOST_SIZE_THRESHOLD = 4;
var LargeSymbolPath = graphic.extendShape({
  shape: {
    points: null
  },
  symbolProxy: null,
  buildPath: function (path, shape) {
    var points = shape.points;
    var size = shape.size;
    var symbolProxy = this.symbolProxy;
    var symbolProxyShape = symbolProxy.shape;
    var ctx = path.getContext ? path.getContext() : path;
    var canBoost = ctx && size[0] < BOOST_SIZE_THRESHOLD; // Do draw in afterBrush.

    if (canBoost) {
      return;
    }

    for (var i = 0; i < points.length;) {
      var x = points[i++];
      var y = points[i++];

      if (isNaN(x) || isNaN(y)) {
        continue;
      }

      symbolProxyShape.x = x - size[0] / 2;
      symbolProxyShape.y = y - size[1] / 2;
      symbolProxyShape.width = size[0];
      symbolProxyShape.height = size[1];
      symbolProxy.buildPath(path, symbolProxyShape, true);
    }
  },
  afterBrush: function (ctx) {
    var shape = this.shape;
    var points = shape.points;
    var size = shape.size;
    var canBoost = size[0] < BOOST_SIZE_THRESHOLD;

    if (!canBoost) {
      return;
    }

    this.setTransform(ctx); // PENDING If style or other canvas status changed?

    for (var i = 0; i < points.length;) {
      var x = points[i++];
      var y = points[i++];

      if (isNaN(x) || isNaN(y)) {
        continue;
      } // fillRect is faster than building a rect path and draw.
      // And it support light globalCompositeOperation.


      ctx.fillRect(x - size[0] / 2, y - size[1] / 2, size[0], size[1]);
    }

    this.restoreTransform(ctx);
  },
  findDataIndex: function (x, y) {
    // TODO ???
    // Consider transform
    var shape = this.shape;
    var points = shape.points;
    var size = shape.size;
    var w = Math.max(size[0], 4);
    var h = Math.max(size[1], 4); // Not consider transform
    // Treat each element as a rect
    // top down traverse

    for (var idx = points.length / 2 - 1; idx >= 0; idx--) {
      var i = idx * 2;
      var x0 = points[i] - w / 2;
      var y0 = points[i + 1] - h / 2;

      if (x >= x0 && y >= y0 && x <= x0 + w && y <= y0 + h) {
        return idx;
      }
    }

    return -1;
  }
});

function LargeSymbolDraw() {
  this.group = new graphic.Group();
}

var largeSymbolProto = LargeSymbolDraw.prototype;

largeSymbolProto.isPersistent = function () {
  return !this._incremental;
};
/**
 * Update symbols draw by new data
 * @param {module:echarts/data/List} data
 */


largeSymbolProto.updateData = function (data) {
  this.group.removeAll();
  var symbolEl = new LargeSymbolPath({
    rectHover: true,
    cursor: 'default'
  });
  symbolEl.setShape({
    points: data.getLayout('symbolPoints')
  });

  this._setCommon(symbolEl, data);

  this.group.add(symbolEl);
  this._incremental = null;
};

largeSymbolProto.updateLayout = function (data) {
  if (this._incremental) {
    return;
  }

  var points = data.getLayout('symbolPoints');
  this.group.eachChild(function (child) {
    if (child.startIndex != null) {
      var len = (child.endIndex - child.startIndex) * 2;
      var byteOffset = child.startIndex * 4 * 2;
      points = new Float32Array(points.buffer, byteOffset, len);
    }

    child.setShape('points', points);
  });
};

largeSymbolProto.incrementalPrepareUpdate = function (data) {
  this.group.removeAll();

  this._clearIncremental(); // Only use incremental displayables when data amount is larger than 2 million.
  // PENDING Incremental data?


  if (data.count() > 2e6) {
    if (!this._incremental) {
      this._incremental = new IncrementalDisplayable({
        silent: true
      });
    }

    this.group.add(this._incremental);
  } else {
    this._incremental = null;
  }
};

largeSymbolProto.incrementalUpdate = function (taskParams, data) {
  var symbolEl;

  if (this._incremental) {
    symbolEl = new LargeSymbolPath();

    this._incremental.addDisplayable(symbolEl, true);
  } else {
    symbolEl = new LargeSymbolPath({
      rectHover: true,
      cursor: 'default',
      startIndex: taskParams.start,
      endIndex: taskParams.end
    });
    symbolEl.incremental = true;
    this.group.add(symbolEl);
  }

  symbolEl.setShape({
    points: data.getLayout('symbolPoints')
  });

  this._setCommon(symbolEl, data, !!this._incremental);
};

largeSymbolProto._setCommon = function (symbolEl, data, isIncremental) {
  var hostModel = data.hostModel; // TODO
  // if (data.hasItemVisual.symbolSize) {
  //     // TODO typed array?
  //     symbolEl.setShape('sizes', data.mapArray(
  //         function (idx) {
  //             var size = data.getItemVisual(idx, 'symbolSize');
  //             return (size instanceof Array) ? size : [size, size];
  //         }
  //     ));
  // }
  // else {

  var size = data.getVisual('symbolSize');
  symbolEl.setShape('size', size instanceof Array ? size : [size, size]); // }
  // Create symbolProxy to build path for each data

  symbolEl.symbolProxy = createSymbol(data.getVisual('symbol'), 0, 0, 0, 0); // Use symbolProxy setColor method

  symbolEl.setColor = symbolEl.symbolProxy.setColor;
  var extrudeShadow = symbolEl.shape.size[0] < BOOST_SIZE_THRESHOLD;
  symbolEl.useStyle( // Draw shadow when doing fillRect is extremely slow.
  hostModel.getModel('itemStyle').getItemStyle(extrudeShadow ? ['color', 'shadowBlur', 'shadowColor'] : ['color']));
  var visualColor = data.getVisual('color');

  if (visualColor) {
    symbolEl.setColor(visualColor);
  }

  if (!isIncremental) {
    // Enable tooltip
    // PENDING May have performance issue when path is extremely large
    symbolEl.seriesIndex = hostModel.seriesIndex;
    symbolEl.on('mousemove', function (e) {
      symbolEl.dataIndex = null;
      var dataIndex = symbolEl.findDataIndex(e.offsetX, e.offsetY);

      if (dataIndex >= 0) {
        // Provide dataIndex for tooltip
        symbolEl.dataIndex = dataIndex + (symbolEl.startIndex || 0);
      }
    });
  }
};

largeSymbolProto.remove = function () {
  this._clearIncremental();

  this._incremental = null;
  this.group.removeAll();
};

largeSymbolProto._clearIncremental = function () {
  var incremental = this._incremental;

  if (incremental) {
    incremental.clearDisplaybles();
  }
};

export default LargeSymbolDraw;