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

// TODO Axis scale

import * as zrUtil from 'zrender/src/core/util';
import Polar, { polarDimensions } from './Polar';
import {parsePercent} from '../../util/number';
import {
    createScaleByModel,
    niceScaleExtent,
    getDataDimensionsOnAxis
} from '../../coord/axisHelper';

import PolarModel from './PolarModel';
import ExtensionAPI from '../../core/ExtensionAPI';
import GlobalModel from '../../model/Global';
import OrdinalScale from '../../scale/Ordinal';
import RadiusAxis from './RadiusAxis';
import AngleAxis from './AngleAxis';
import { PolarAxisModel, AngleAxisModel, RadiusAxisModel } from './AxisModel';
import SeriesModel from '../../model/Series';
import { SeriesOption } from '../../util/types';
import { SINGLE_REFERRING } from '../../util/model';

/**
 * Resize method bound to the polar
 */
function resizePolar(polar: Polar, polarModel: PolarModel, api: ExtensionAPI) {
    const center = polarModel.get('center');
    const width = api.getWidth();
    const height = api.getHeight();

    polar.cx = parsePercent(center[0], width);
    polar.cy = parsePercent(center[1], height);

    const radiusAxis = polar.getRadiusAxis();
    const size = Math.min(width, height) / 2;

    let radius = polarModel.get('radius');
    if (radius == null) {
        radius = [0, '100%'];
    }
    else if (!zrUtil.isArray(radius)) {
        // r0 = 0
        radius = [0, radius];
    }
    const parsedRadius = [
        parsePercent(radius[0], size),
        parsePercent(radius[1], size)
    ];

    radiusAxis.inverse
        ? radiusAxis.setExtent(parsedRadius[1], parsedRadius[0])
        : radiusAxis.setExtent(parsedRadius[0], parsedRadius[1]);
}

/**
 * Update polar
 */
function updatePolarScale(this: Polar, ecModel: GlobalModel, api: ExtensionAPI) {
    const polar = this;
    const angleAxis = polar.getAngleAxis();
    const radiusAxis = polar.getRadiusAxis();
    // Reset scale
    angleAxis.scale.setExtent(Infinity, -Infinity);
    radiusAxis.scale.setExtent(Infinity, -Infinity);

    ecModel.eachSeries(function (seriesModel) {
        if (seriesModel.coordinateSystem === polar) {
            const data = seriesModel.getData();
            zrUtil.each(getDataDimensionsOnAxis(data, 'radius'), function (dim) {
                radiusAxis.scale.unionExtentFromData(data, dim);
            });
            zrUtil.each(getDataDimensionsOnAxis(data, 'angle'), function (dim) {
                angleAxis.scale.unionExtentFromData(data, dim);
            });
        }
    });

    niceScaleExtent(angleAxis.scale, angleAxis.model);
    niceScaleExtent(radiusAxis.scale, radiusAxis.model);

    // Fix extent of category angle axis
    if (angleAxis.type === 'category' && !angleAxis.onBand) {
        const extent = angleAxis.getExtent();
        const diff = 360 / (angleAxis.scale as OrdinalScale).count();
        angleAxis.inverse ? (extent[1] += diff) : (extent[1] -= diff);
        angleAxis.setExtent(extent[0], extent[1]);
    }
}

function isAngleAxisModel(axisModel: AngleAxisModel | PolarAxisModel): axisModel is AngleAxisModel {
    return axisModel.mainType === 'angleAxis';
}
/**
 * Set common axis properties
 */
function setAxis(axis: RadiusAxis | AngleAxis, axisModel: PolarAxisModel) {
    axis.type = axisModel.get('type');
    axis.scale = createScaleByModel(axisModel);
    axis.onBand = axisModel.get('boundaryGap') && axis.type === 'category';
    axis.inverse = axisModel.get('inverse');

    if (isAngleAxisModel(axisModel)) {
        axis.inverse = axis.inverse !== axisModel.get('clockwise');
        const startAngle = axisModel.get('startAngle');
        axis.setExtent(startAngle, startAngle + (axis.inverse ? -360 : 360));
    }

    // Inject axis instance
    axisModel.axis = axis;
    axis.model = axisModel as AngleAxisModel | RadiusAxisModel;
}


const polarCreator = {

    dimensions: polarDimensions,

    create: function (ecModel: GlobalModel, api: ExtensionAPI) {
        const polarList: Polar[] = [];
        ecModel.eachComponent('polar', function (polarModel: PolarModel, idx: number) {
            const polar = new Polar(idx + '');
            // Inject resize and update method
            polar.update = updatePolarScale;

            const radiusAxis = polar.getRadiusAxis();
            const angleAxis = polar.getAngleAxis();

            const radiusAxisModel = polarModel.findAxisModel('radiusAxis');
            const angleAxisModel = polarModel.findAxisModel('angleAxis');

            setAxis(radiusAxis, radiusAxisModel);
            setAxis(angleAxis, angleAxisModel);

            resizePolar(polar, polarModel, api);

            polarList.push(polar);

            polarModel.coordinateSystem = polar;
            polar.model = polarModel;
        });
        // Inject coordinateSystem to series
        ecModel.eachSeries(function (seriesModel: SeriesModel<SeriesOption & {
            polarIndex?: number
            polarId?: string
        }>) {
            if (seriesModel.get('coordinateSystem') === 'polar') {
                const polarModel = seriesModel.getReferringComponents(
                    'polar', SINGLE_REFERRING
                ).models[0] as PolarModel;

                if (__DEV__) {
                    if (!polarModel) {
                        throw new Error(
                            'Polar "' + zrUtil.retrieve<number | string>(
                                seriesModel.get('polarIndex'),
                                seriesModel.get('polarId'),
                                0
                            ) + '" not found'
                        );
                    }
                }
                seriesModel.coordinateSystem = polarModel.coordinateSystem;
            }
        });

        return polarList;
    }
};

export default polarCreator;