/*
* 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 * as zrUtil from 'zrender/src/core/util';
import ComponentModel from '../../model/Component';
import type Parallel from './Parallel';
import {
    DimensionName, ComponentOption, BoxLayoutOptionMixin, ComponentOnCalendarOptionMixin,
    ComponentOnMatrixOptionMixin
} from '../../util/types';
import ParallelAxisModel, { ParallelAxisOption } from './AxisModel';
import GlobalModel from '../../model/Global';
import ParallelSeriesModel from '../../chart/parallel/ParallelSeries';
import SeriesModel from '../../model/Series';


export const COORD_SYS_TYPE_PARALLEL = 'parallel';
export const COMPONENT_TYPE_PARALLEL = COORD_SYS_TYPE_PARALLEL;

export type ParallelLayoutDirection = 'horizontal' | 'vertical';

export interface ParallelCoordinateSystemOption extends
    ComponentOption,
    ComponentOnCalendarOptionMixin,
    ComponentOnMatrixOptionMixin,
    BoxLayoutOptionMixin {

    mainType?: 'parallel';

    layout?: ParallelLayoutDirection;

    axisExpandable?: boolean;
    axisExpandCenter?: number;
    axisExpandCount?: number;
    axisExpandWidth?: number; // TODO '10%' ?
    axisExpandTriggerOn?: 'click' | 'mousemove';

    // Not ready to expose to users yet.
    axisExpandRate?: number;
    // Not ready to expose to users yet.
    axisExpandDebounce?: number;
    // Not ready to expose to users yet.
    // [out, in, jumpTarget]. In percentage. If use [null, 0.05], null means full.
    // Do not doc to user until necessary.
    axisExpandSlideTriggerArea?: [number, number, number];
    // Not ready to expose to users yet.
    axisExpandWindow?: number[];

    parallelAxisDefault?: ParallelAxisOption
}

class ParallelModel extends ComponentModel<ParallelCoordinateSystemOption> {

    static type = COMPONENT_TYPE_PARALLEL;
    readonly type = ParallelModel.type;

    static dependencies = ['parallelAxis'];

    coordinateSystem: Parallel;

    /**
     * Each item like: 'dim0', 'dim1', 'dim2', ...
     */
    dimensions: DimensionName[];

    /**
     * Corresponding to dimensions.
     */
    parallelAxisIndex: number[];

    static layoutMode = 'box' as const;

    static defaultOption: ParallelCoordinateSystemOption = {
        // zlevel: 0,
        z: 0,
        left: 80,
        top: 60,
        right: 80,
        bottom: 60,
        // width: {totalWidth} - left - right,
        // height: {totalHeight} - top - bottom,

        layout: 'horizontal',      // 'horizontal' or 'vertical'

        // FIXME
        // naming?
        axisExpandable: false,
        axisExpandCenter: null,
        axisExpandCount: 0,
        axisExpandWidth: 50,      // FIXME '10%' ?
        axisExpandRate: 17,
        axisExpandDebounce: 50,
        // [out, in, jumpTarget]. In percentage. If use [null, 0.05], null means full.
        // Do not doc to user until necessary.
        axisExpandSlideTriggerArea: [-0.15, 0.05, 0.4],
        axisExpandTriggerOn: 'click', // 'mousemove' or 'click'

        parallelAxisDefault: null
    };

    init() {
        super.init.apply(this, arguments as any);
        this.mergeOption({});
    }

    mergeOption(newOption: ParallelCoordinateSystemOption) {
        const thisOption = this.option;

        newOption && zrUtil.merge(thisOption, newOption, true);

        this._initDimensions();
    }

    /**
     * Whether series or axis is in this coordinate system.
     */
    contains(model: SeriesModel | ParallelAxisModel, ecModel: GlobalModel): boolean {
        const parallelIndex = (model as ParallelSeriesModel).get('parallelIndex');
        return parallelIndex != null
            && ecModel.getComponent('parallel', parallelIndex) === this;
    }

    setAxisExpand(opt: {
        axisExpandable?: boolean,
        axisExpandCenter?: number,
        axisExpandCount?: number,
        axisExpandWidth?: number,
        axisExpandWindow?: number[]
    }): void {
        zrUtil.each(
            [
                'axisExpandable',
                'axisExpandCenter',
                'axisExpandCount',
                'axisExpandWidth',
                'axisExpandWindow'
            ] as const,
            function (name) {
                if (opt.hasOwnProperty(name)) {
                    // @ts-ignore FIXME: why "never" inferred in this.option[name]?
                    this.option[name] = opt[name];
                }
            },
            this
        );
    }

    private _initDimensions(): void {
        const dimensions = this.dimensions = [] as DimensionName[];
        const parallelAxisIndex = this.parallelAxisIndex = [] as number[];

        const axisModels = zrUtil.filter(
            this.ecModel.queryComponents({ mainType: 'parallelAxis' }),
            function (axisModel: ParallelAxisModel) {
                // Can not use this.contains here, because
                // initialization has not been completed yet.
                return (axisModel.get('parallelIndex') || 0) === this.componentIndex;
            },
            this
        );

        zrUtil.each(axisModels, function (axisModel: ParallelAxisModel) {
            dimensions.push('dim' + axisModel.get('dim'));
            parallelAxisIndex.push(axisModel.componentIndex);
        });
    }

}

export default ParallelModel;
