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

/**
 * Linear continuous scale
 * http://en.wikipedia.org/wiki/Level_of_measurement
 */

// FIXME only one data

import Scale from './Scale';
import OrdinalMeta from '../data/OrdinalMeta';
import SeriesData from '../data/SeriesData';
import * as scaleHelper from './helper';
import {
    OrdinalRawValue,
    OrdinalNumber,
    DimensionLoose,
    OrdinalSortInfo,
    OrdinalScaleTick,
    ScaleTick
} from '../util/types';
import { CategoryAxisBaseOption } from '../coord/axisCommonTypes';
import { isArray, map, isObject, isString } from 'zrender/src/core/util';

type OrdinalScaleSetting = {
    ordinalMeta?: OrdinalMeta | CategoryAxisBaseOption['data'];
    extent?: [number, number];
};

class OrdinalScale extends Scale<OrdinalScaleSetting> {

    static type = 'ordinal';
    readonly type = 'ordinal';

    private _ordinalMeta: OrdinalMeta;

    /**
     * For example:
     * Given original ordinal data:
     * ```js
     * option = {
     *     xAxis: {
     *         // Their raw ordinal numbers are:
     *         //      0    1    2    3    4    5
     *         data: ['a', 'b', 'c', 'd', 'e', 'f']
     *     },
     *     yAxis: {}
     *     series: {
     *         type: 'bar',
     *         data: [
     *             ['d', 110], // ordinalNumber: 3
     *             ['c', 660], // ordinalNumber: 2
     *             ['f', 220], // ordinalNumber: 5
     *             ['e', 550]  // ordinalNumber: 4
     *         ],
     *         realtimeSort: true
     *     }
     * };
     * ```
     * After realtime sorted (order by yValue desc):
     * ```js
     * _ordinalNumbersByTick: [
     *     2, // tick: 0, yValue: 660
     *     5, // tick: 1, yValue: 220
     *     3, // tick: 2, yValue: 110
     *     4, // tick: 3, yValue: 550
     *     0, // tick: 4, yValue: -
     *     1, // tick: 5, yValue: -
     * ],
     * _ticksByOrdinalNumber: [
     *     4, // ordinalNumber: 0, yValue: -
     *     5, // ordinalNumber: 1, yValue: -
     *     0, // ordinalNumber: 2, yValue: 660
     *     2, // ordinalNumber: 3, yValue: 110
     *     3, // ordinalNumber: 4, yValue: 550
     *     1, // ordinalNumber: 5, yValue: 220
     * ]
     * ```
     * The index of this array is from `0` to `ordinalMeta.categories.length`.
     *
     * @see `Ordinal['getRawOrdinalNumber']`
     * @see `OrdinalSortInfo`
     */
    private _ordinalNumbersByTick: OrdinalNumber[];

    /**
     * This is the inverted map of `_ordinalNumbersByTick`.
     * The index of this array is from `0` to `ordinalMeta.categories.length`.
     *
     * @see `Ordinal['_ordinalNumbersByTick']`
     * @see `Ordinal['_getTickNumber']`
     * @see `OrdinalSortInfo`
     */
    private _ticksByOrdinalNumber: number[];


    constructor(setting?: OrdinalScaleSetting) {
        super(setting);

        let ordinalMeta = this.getSetting('ordinalMeta');
        // Caution: Should not use instanceof, consider ec-extensions using
        // import approach to get OrdinalMeta class.
        if (!ordinalMeta) {
            ordinalMeta = new OrdinalMeta({});
        }
        if (isArray(ordinalMeta)) {
            ordinalMeta = new OrdinalMeta({
                categories: map(ordinalMeta, item => (isObject(item) ? item.value : item))
            });
        }
        this._ordinalMeta = ordinalMeta as OrdinalMeta;
        this._extent = this.getSetting('extent') || [0, ordinalMeta.categories.length - 1];
    }

    parse(val: OrdinalRawValue | OrdinalNumber): OrdinalNumber {
        // Caution: Math.round(null) will return `0` rather than `NaN`
        if (val == null) {
            return NaN;
        }
        return isString(val)
            ? this._ordinalMeta.getOrdinal(val)
            // val might be float.
            : Math.round(val);
    }

    contain(rank: OrdinalRawValue | OrdinalNumber): boolean {
        rank = this.parse(rank);
        return scaleHelper.contain(rank, this._extent)
            && this._ordinalMeta.categories[rank] != null;
    }

    /**
     * Normalize given rank or name to linear [0, 1]
     * @param val raw ordinal number.
     * @return normalized value in [0, 1].
     */
    normalize(val: OrdinalRawValue | OrdinalNumber): number {
        val = this._getTickNumber(this.parse(val));
        return scaleHelper.normalize(val, this._extent);
    }

    /**
     * @param val normalized value in [0, 1].
     * @return raw ordinal number.
     */
    scale(val: number): OrdinalNumber {
        val = Math.round(scaleHelper.scale(val, this._extent));
        return this.getRawOrdinalNumber(val);
    }

    getTicks(): OrdinalScaleTick[] {
        const ticks = [];
        const extent = this._extent;
        let rank = extent[0];

        while (rank <= extent[1]) {
            ticks.push({
                value: rank
            });
            rank++;
        }

        return ticks;
    }

    getMinorTicks(splitNumber: number): number[][] {
        // Not support.
        return;
    }

    /**
     * @see `Ordinal['_ordinalNumbersByTick']`
     */
    setSortInfo(info: OrdinalSortInfo): void {
        if (info == null) {
            this._ordinalNumbersByTick = this._ticksByOrdinalNumber = null;
            return;
        }

        const infoOrdinalNumbers = info.ordinalNumbers;
        const ordinalsByTick = this._ordinalNumbersByTick = [] as OrdinalNumber[];
        const ticksByOrdinal = this._ticksByOrdinalNumber = [] as number[];

        // Unnecessary support negative tick in `realtimeSort`.
        let tickNum = 0;
        const allCategoryLen = this._ordinalMeta.categories.length;
        for (const len = Math.min(allCategoryLen, infoOrdinalNumbers.length); tickNum < len; ++tickNum) {
            const ordinalNumber = infoOrdinalNumbers[tickNum];
            ordinalsByTick[tickNum] = ordinalNumber;
            ticksByOrdinal[ordinalNumber] = tickNum;
        }
        // Handle that `series.data` only covers part of the `axis.category.data`.
        let unusedOrdinal = 0;
        for (; tickNum < allCategoryLen; ++tickNum) {
            while (ticksByOrdinal[unusedOrdinal] != null) {
                unusedOrdinal++;
            };
            ordinalsByTick.push(unusedOrdinal);
            ticksByOrdinal[unusedOrdinal] = tickNum;
        }
    }

    private _getTickNumber(ordinal: OrdinalNumber): number {
        const ticksByOrdinalNumber = this._ticksByOrdinalNumber;
        // also support ordinal out of range of `ordinalMeta.categories.length`,
        // where ordinal numbers are used as tick value directly.
        return (ticksByOrdinalNumber && ordinal >= 0 && ordinal < ticksByOrdinalNumber.length)
            ? ticksByOrdinalNumber[ordinal]
            : ordinal;
    }

    /**
     * @usage
     * ```js
     * const ordinalNumber = ordinalScale.getRawOrdinalNumber(tickVal);
     *
     * // case0
     * const rawOrdinalValue = axisModel.getCategories()[ordinalNumber];
     * // case1
     * const rawOrdinalValue = this._ordinalMeta.categories[ordinalNumber];
     * // case2
     * const coord = axis.dataToCoord(ordinalNumber);
     * ```
     *
     * @param {OrdinalNumber} tickNumber index of display
     */
    getRawOrdinalNumber(tickNumber: number): OrdinalNumber {
        const ordinalNumbersByTick = this._ordinalNumbersByTick;
        // tickNumber may be out of range, e.g., when axis max is larger than `ordinalMeta.categories.length`.,
        // where ordinal numbers are used as tick value directly.
        return (ordinalNumbersByTick && tickNumber >= 0 && tickNumber < ordinalNumbersByTick.length)
            ? ordinalNumbersByTick[tickNumber]
            : tickNumber;
    }

    /**
     * Get item on tick
     */
    getLabel(tick: ScaleTick): string {
        if (!this.isBlank()) {
            const ordinalNumber = this.getRawOrdinalNumber(tick.value);
            const cateogry = this._ordinalMeta.categories[ordinalNumber];
            // Note that if no data, ordinalMeta.categories is an empty array.
            // Return empty if it's not exist.
            return cateogry == null ? '' : cateogry + '';
        }
    }

    count(): number {
        return this._extent[1] - this._extent[0] + 1;
    }

    unionExtentFromData(data: SeriesData, dim: DimensionLoose) {
        this.unionExtent(data.getApproximateExtent(dim));
    }

    /**
     * @override
     * If value is in extent range
     */
    isInExtentRange(value: OrdinalNumber): boolean {
        value = this._getTickNumber(value);
        return this._extent[0] <= value && this._extent[1] >= value;
    }

    getOrdinalMeta(): OrdinalMeta {
        return this._ordinalMeta;
    }

    calcNiceTicks() {}

    calcNiceExtent() {}

}

Scale.registerClass(OrdinalScale);

export default OrdinalScale;
