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

import { StageHandler, SeriesOption, SeriesSamplingOptionMixin } from '../util/types';
import { Dictionary } from 'zrender/src/core/types';
import SeriesModel from '../model/Series';
import { isFunction, isString } from 'zrender/src/core/util';


type Sampler = (frame: ArrayLike<number>) => number;
const samplers: Dictionary<Sampler> = {
    average: function (frame) {
        let sum = 0;
        let count = 0;
        for (let i = 0; i < frame.length; i++) {
            if (!isNaN(frame[i])) {
                sum += frame[i];
                count++;
            }
        }
        // Return NaN if count is 0
        return count === 0 ? NaN : sum / count;
    },
    sum: function (frame) {
        let sum = 0;
        for (let i = 0; i < frame.length; i++) {
            // Ignore NaN
            sum += frame[i] || 0;
        }
        return sum;
    },
    max: function (frame) {
        let max = -Infinity;
        for (let i = 0; i < frame.length; i++) {
            frame[i] > max && (max = frame[i]);
        }
        // NaN will cause illegal axis extent.
        return isFinite(max) ? max : NaN;
    },
    min: function (frame) {
        let min = Infinity;
        for (let i = 0; i < frame.length; i++) {
            frame[i] < min && (min = frame[i]);
        }
        // NaN will cause illegal axis extent.
        return isFinite(min) ? min : NaN;
    },
    // TODO
    // Median
    nearest: function (frame) {
        return frame[0];
    }
};

const indexSampler = function (frame: ArrayLike<number>) {
    return Math.round(frame.length / 2);
};

export default function dataSample(seriesType: string): StageHandler {
    return {

        seriesType: seriesType,

        // FIXME:TS never used, so comment it
        // modifyOutputEnd: true,

        reset: function (seriesModel: SeriesModel<SeriesOption & SeriesSamplingOptionMixin>, ecModel, api) {
            const data = seriesModel.getData();
            const sampling = seriesModel.get('sampling');
            const coordSys = seriesModel.coordinateSystem;
            const count = data.count();
            // Only cartesian2d support down sampling. Disable it when there is few data.
            if (count > 10 && coordSys.type === 'cartesian2d' && sampling) {
                const baseAxis = coordSys.getBaseAxis();
                const valueAxis = coordSys.getOtherAxis(baseAxis);
                const extent = baseAxis.getExtent();
                const dpr = api.getDevicePixelRatio();
                // Coordinste system has been resized
                const size = Math.abs(extent[1] - extent[0]) * (dpr || 1);
                const rate = Math.round(count / size);

                if (isFinite(rate) && rate > 1) {
                    if (sampling === 'lttb') {
                        seriesModel.setData(data.lttbDownSample(data.mapDimension(valueAxis.dim), 1 / rate));
                    }
                    let sampler;
                    if (isString(sampling)) {
                        sampler = samplers[sampling];
                    }
                    else if (isFunction(sampling)) {
                        sampler = sampling;
                    }
                    if (sampler) {
                        // Only support sample the first dim mapped from value axis.
                        seriesModel.setData(data.downSample(
                            data.mapDimension(valueAxis.dim), 1 / rate, sampler, indexSampler
                        ));
                    }
                }
            }
        }
    };
}