'use strict';

var util = require('../../../../../../zrender@6.0.0/node_modules/zrender/lib/core/util.js');
var model = require('../../util/model.js');
var Source = require('../Source.js');
var types = require('../../util/types.js');
var log = require('../../util/log.js');

/*
* 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.
*/


/**
 * AUTO-GENERATED FILE. DO NOT MODIFY.
 */

/*
* 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.
*/
var _a, _b, _c, _d;
var providerMethods;
var mountMethods;
/**
 * If normal array used, mutable chunk size is supported.
 * If typed array used, chunk size must be fixed.
 */
var DefaultDataProvider = /** @class */function () {
  function DefaultDataProvider(sourceParam, dimSize) {
    // let source: Source;
    var source = !Source.isSourceInstance(sourceParam) ? Source.createSourceFromSeriesDataOption(sourceParam) : sourceParam;
    // declare source is Source;
    this._source = source;
    var data = this._data = source.data;
    var sourceFormat = source.sourceFormat;
    var seriesLayoutBy = source.seriesLayoutBy;
    // Typed array. TODO IE10+?
    if (sourceFormat === types.SOURCE_FORMAT_TYPED_ARRAY) {
      if (process.env.NODE_ENV !== 'production') {
        if (dimSize == null) {
          throw new Error('Typed array data must specify dimension size');
        }
      }
      this._offset = 0;
      this._dimSize = dimSize;
      this._data = data;
    }
    if (process.env.NODE_ENV !== 'production') {
      var validator = rawSourceDataValidatorMap[getMethodMapKey(sourceFormat, seriesLayoutBy)];
      validator && validator(data, source.dimensionsDefine);
    }
    mountMethods(this, data, source);
  }
  DefaultDataProvider.prototype.getSource = function () {
    return this._source;
  };
  DefaultDataProvider.prototype.count = function () {
    return 0;
  };
  DefaultDataProvider.prototype.getItem = function (idx, out) {
    return;
  };
  DefaultDataProvider.prototype.appendData = function (newData) {};
  DefaultDataProvider.prototype.clean = function () {};
  DefaultDataProvider.protoInitialize = function () {
    // PENDING: To avoid potential incompat (e.g., prototype
    // is visited somewhere), still init them on prototype.
    var proto = DefaultDataProvider.prototype;
    proto.pure = false;
    proto.persistent = true;
  }();
  DefaultDataProvider.internalField = function () {
    var _a;
    mountMethods = function (provider, data, source) {
      var sourceFormat = source.sourceFormat;
      var seriesLayoutBy = source.seriesLayoutBy;
      var startIndex = source.startIndex;
      var dimsDef = source.dimensionsDefine;
      var methods = providerMethods[getMethodMapKey(sourceFormat, seriesLayoutBy)];
      if (process.env.NODE_ENV !== 'production') {
        util.assert(methods, 'Invalide sourceFormat: ' + sourceFormat);
      }
      util.extend(provider, methods);
      if (sourceFormat === types.SOURCE_FORMAT_TYPED_ARRAY) {
        provider.getItem = getItemForTypedArray;
        provider.count = countForTypedArray;
        provider.fillStorage = fillStorageForTypedArray;
      } else {
        var rawItemGetter = getRawSourceItemGetter(sourceFormat, seriesLayoutBy);
        provider.getItem = util.bind(rawItemGetter, null, data, startIndex, dimsDef);
        var rawCounter = getRawSourceDataCounter(sourceFormat, seriesLayoutBy);
        provider.count = util.bind(rawCounter, null, data, startIndex, dimsDef);
      }
    };
    var getItemForTypedArray = function (idx, out) {
      idx = idx - this._offset;
      out = out || [];
      var data = this._data;
      var dimSize = this._dimSize;
      var offset = dimSize * idx;
      for (var i = 0; i < dimSize; i++) {
        out[i] = data[offset + i];
      }
      return out;
    };
    var fillStorageForTypedArray = function (start, end, storage, extent) {
      var data = this._data;
      var dimSize = this._dimSize;
      for (var dim = 0; dim < dimSize; dim++) {
        var dimExtent = extent[dim];
        var min = dimExtent[0] == null ? Infinity : dimExtent[0];
        var max = dimExtent[1] == null ? -Infinity : dimExtent[1];
        var count = end - start;
        var arr = storage[dim];
        for (var i = 0; i < count; i++) {
          // appendData with TypedArray will always do replace in provider.
          var val = data[i * dimSize + dim];
          arr[start + i] = val;
          val < min && (min = val);
          val > max && (max = val);
        }
        dimExtent[0] = min;
        dimExtent[1] = max;
      }
    };
    var countForTypedArray = function () {
      return this._data ? this._data.length / this._dimSize : 0;
    };
    providerMethods = (_a = {}, _a[types.SOURCE_FORMAT_ARRAY_ROWS + '_' + types.SERIES_LAYOUT_BY_COLUMN] = {
      pure: true,
      appendData: appendDataSimply
    }, _a[types.SOURCE_FORMAT_ARRAY_ROWS + '_' + types.SERIES_LAYOUT_BY_ROW] = {
      pure: true,
      appendData: function () {
        throw new Error('Do not support appendData when set seriesLayoutBy: "row".');
      }
    }, _a[types.SOURCE_FORMAT_OBJECT_ROWS] = {
      pure: true,
      appendData: appendDataSimply
    }, _a[types.SOURCE_FORMAT_KEYED_COLUMNS] = {
      pure: true,
      appendData: function (newData) {
        var data = this._data;
        util.each(newData, function (newCol, key) {
          var oldCol = data[key] || (data[key] = []);
          for (var i = 0; i < (newCol || []).length; i++) {
            oldCol.push(newCol[i]);
          }
        });
      }
    }, _a[types.SOURCE_FORMAT_ORIGINAL] = {
      appendData: appendDataSimply
    }, _a[types.SOURCE_FORMAT_TYPED_ARRAY] = {
      persistent: false,
      pure: true,
      appendData: function (newData) {
        if (process.env.NODE_ENV !== 'production') {
          util.assert(util.isTypedArray(newData), 'Added data must be TypedArray if data in initialization is TypedArray');
        }
        this._data = newData;
      },
      // Clean self if data is already used.
      clean: function () {
        // PENDING
        this._offset += this.count();
        this._data = null;
      }
    }, _a);
    function appendDataSimply(newData) {
      for (var i = 0; i < newData.length; i++) {
        this._data.push(newData[i]);
      }
    }
  }();
  return DefaultDataProvider;
}();
var validateSimply = function (rawData) {
  if (!util.isArray(rawData)) {
    log.error('series.data or dataset.source must be an array.');
  }
};
/**
 * Only run in dev mode - hint users for debug.
 */
var rawSourceDataValidatorMap = (_a = {}, _a[types.SOURCE_FORMAT_ARRAY_ROWS + '_' + types.SERIES_LAYOUT_BY_COLUMN] = validateSimply, _a[types.SOURCE_FORMAT_ARRAY_ROWS + '_' + types.SERIES_LAYOUT_BY_ROW] = validateSimply, _a[types.SOURCE_FORMAT_OBJECT_ROWS] = validateSimply, _a[types.SOURCE_FORMAT_KEYED_COLUMNS] = function (rawData, dimsDef) {
  for (var i = 0; i < dimsDef.length; i++) {
    var dimName = dimsDef[i].name;
    if (dimName == null) {
      log.error('dimension name must not be null/undefined.');
    }
  }
}, _a[types.SOURCE_FORMAT_ORIGINAL] = validateSimply, _a);
var getItemSimply = function (rawData, startIndex, dimsDef, idx) {
  return rawData[idx];
};
var rawSourceItemGetterMap = (_b = {}, _b[types.SOURCE_FORMAT_ARRAY_ROWS + '_' + types.SERIES_LAYOUT_BY_COLUMN] = function (rawData, startIndex, dimsDef, idx) {
  return rawData[idx + startIndex];
}, _b[types.SOURCE_FORMAT_ARRAY_ROWS + '_' + types.SERIES_LAYOUT_BY_ROW] = function (rawData, startIndex, dimsDef, idx, out) {
  idx += startIndex;
  var item = out || [];
  var data = rawData;
  for (var i = 0; i < data.length; i++) {
    var row = data[i];
    item[i] = row ? row[idx] : null;
  }
  return item;
}, _b[types.SOURCE_FORMAT_OBJECT_ROWS] = getItemSimply, _b[types.SOURCE_FORMAT_KEYED_COLUMNS] = function (rawData, startIndex, dimsDef, idx, out) {
  var item = out || [];
  for (var i = 0; i < dimsDef.length; i++) {
    var dimName = dimsDef[i].name;
    var col = dimName != null ? rawData[dimName] : null;
    item[i] = col ? col[idx] : null;
  }
  return item;
}, _b[types.SOURCE_FORMAT_ORIGINAL] = getItemSimply, _b);
function getRawSourceItemGetter(sourceFormat, seriesLayoutBy) {
  var method = rawSourceItemGetterMap[getMethodMapKey(sourceFormat, seriesLayoutBy)];
  if (process.env.NODE_ENV !== 'production') {
    util.assert(method, 'Do not support get item on "' + sourceFormat + '", "' + seriesLayoutBy + '".');
  }
  return method;
}
var countSimply = function (rawData, startIndex, dimsDef) {
  return rawData.length;
};
var rawSourceDataCounterMap = (_c = {}, _c[types.SOURCE_FORMAT_ARRAY_ROWS + '_' + types.SERIES_LAYOUT_BY_COLUMN] = function (rawData, startIndex, dimsDef) {
  return Math.max(0, rawData.length - startIndex);
}, _c[types.SOURCE_FORMAT_ARRAY_ROWS + '_' + types.SERIES_LAYOUT_BY_ROW] = function (rawData, startIndex, dimsDef) {
  var row = rawData[0];
  return row ? Math.max(0, row.length - startIndex) : 0;
}, _c[types.SOURCE_FORMAT_OBJECT_ROWS] = countSimply, _c[types.SOURCE_FORMAT_KEYED_COLUMNS] = function (rawData, startIndex, dimsDef) {
  var dimName = dimsDef[0].name;
  var col = dimName != null ? rawData[dimName] : null;
  return col ? col.length : 0;
}, _c[types.SOURCE_FORMAT_ORIGINAL] = countSimply, _c);
function getRawSourceDataCounter(sourceFormat, seriesLayoutBy) {
  var method = rawSourceDataCounterMap[getMethodMapKey(sourceFormat, seriesLayoutBy)];
  if (process.env.NODE_ENV !== 'production') {
    util.assert(method, 'Do not support count on "' + sourceFormat + '", "' + seriesLayoutBy + '".');
  }
  return method;
}
var getRawValueSimply = function (dataItem, dimIndex, property) {
  return dataItem[dimIndex];
};
var rawSourceValueGetterMap = (_d = {}, _d[types.SOURCE_FORMAT_ARRAY_ROWS] = getRawValueSimply, _d[types.SOURCE_FORMAT_OBJECT_ROWS] = function (dataItem, dimIndex, property) {
  return dataItem[property];
}, _d[types.SOURCE_FORMAT_KEYED_COLUMNS] = getRawValueSimply, _d[types.SOURCE_FORMAT_ORIGINAL] = function (dataItem, dimIndex, property) {
  // FIXME: In some case (markpoint in geo (geo-map.html)),
  // dataItem is {coord: [...]}
  var value = model.getDataItemValue(dataItem);
  return !(value instanceof Array) ? value : value[dimIndex];
}, _d[types.SOURCE_FORMAT_TYPED_ARRAY] = getRawValueSimply, _d);
function getRawSourceValueGetter(sourceFormat) {
  var method = rawSourceValueGetterMap[sourceFormat];
  if (process.env.NODE_ENV !== 'production') {
    util.assert(method, 'Do not support get value on "' + sourceFormat + '".');
  }
  return method;
}
function getMethodMapKey(sourceFormat, seriesLayoutBy) {
  return sourceFormat === types.SOURCE_FORMAT_ARRAY_ROWS ? sourceFormat + '_' + seriesLayoutBy : sourceFormat;
}
// ??? FIXME can these logic be more neat: getRawValue, getRawDataItem,
// Consider persistent.
// Caution: why use raw value to display on label or tooltip?
// A reason is to avoid format. For example time value we do not know
// how to format is expected. More over, if stack is used, calculated
// value may be 0.91000000001, which have brings trouble to display.
// TODO: consider how to treat null/undefined/NaN when display?
function retrieveRawValue(data, dataIndex,
// If dimIndex is null/undefined, return OptionDataItem.
// Otherwise, return OptionDataValue.
dim) {
  if (!data) {
    return;
  }
  // Consider data may be not persistent.
  var dataItem = data.getRawDataItem(dataIndex);
  if (dataItem == null) {
    return;
  }
  var store = data.getStore();
  var sourceFormat = store.getSource().sourceFormat;
  if (dim != null) {
    var dimIndex = data.getDimensionIndex(dim);
    var property = store.getDimensionProperty(dimIndex);
    return getRawSourceValueGetter(sourceFormat)(dataItem, dimIndex, property);
  } else {
    var result = dataItem;
    if (sourceFormat === types.SOURCE_FORMAT_ORIGINAL) {
      result = model.getDataItemValue(dataItem);
    }
    return result;
  }
}
/**
 * Compatible with some cases (in pie, map) like:
 * data: [{name: 'xx', value: 5, selected: true}, ...]
 * where only sourceFormat is 'original' and 'objectRows' supported.
 *
 * // TODO
 * Supported detail options in data item when using 'arrayRows'.
 *
 * @param data
 * @param dataIndex
 * @param attr like 'selected'
 */
function retrieveRawAttr(data, dataIndex, attr) {
  if (!data) {
    return;
  }
  var sourceFormat = data.getStore().getSource().sourceFormat;
  if (sourceFormat !== types.SOURCE_FORMAT_ORIGINAL && sourceFormat !== types.SOURCE_FORMAT_OBJECT_ROWS) {
    return;
  }
  var dataItem = data.getRawDataItem(dataIndex);
  if (sourceFormat === types.SOURCE_FORMAT_ORIGINAL && !util.isObject(dataItem)) {
    dataItem = null;
  }
  if (dataItem) {
    return dataItem[attr];
  }
}

exports.DefaultDataProvider = DefaultDataProvider;
exports.getRawSourceDataCounter = getRawSourceDataCounter;
exports.getRawSourceItemGetter = getRawSourceItemGetter;
exports.getRawSourceValueGetter = getRawSourceValueGetter;
exports.retrieveRawAttr = retrieveRawAttr;
exports.retrieveRawValue = retrieveRawValue;
