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

// Symbol factory

import * as zrUtil from 'zrender/src/core/util';
import * as graphic from './graphic';
import BoundingRect from 'zrender/src/core/BoundingRect';
import {calculateTextPosition} from 'zrender/src/contain/text';
import { Dictionary } from 'zrender/src/core/types';
import { ZRColor } from './types';

type ECSymbol = graphic.Path & {
    __isEmptyBrush?: boolean
    setColor: (color: ZRColor, innerColor?: string) => void
    getColor: () => ZRColor
};
type SymbolCtor = { new(): ECSymbol };
type SymbolShapeMaker = (x: number, y: number, w: number, h: number, shape: Dictionary<any>) => void;

/**
 * Triangle shape
 * @inner
 */
const Triangle = graphic.Path.extend({
    type: 'triangle',
    shape: {
        cx: 0,
        cy: 0,
        width: 0,
        height: 0
    },
    buildPath: function (path, shape) {
        const cx = shape.cx;
        const cy = shape.cy;
        const width = shape.width / 2;
        const height = shape.height / 2;
        path.moveTo(cx, cy - height);
        path.lineTo(cx + width, cy + height);
        path.lineTo(cx - width, cy + height);
        path.closePath();
    }
});

/**
 * Diamond shape
 * @inner
 */
const Diamond = graphic.Path.extend({
    type: 'diamond',
    shape: {
        cx: 0,
        cy: 0,
        width: 0,
        height: 0
    },
    buildPath: function (path, shape) {
        const cx = shape.cx;
        const cy = shape.cy;
        const width = shape.width / 2;
        const height = shape.height / 2;
        path.moveTo(cx, cy - height);
        path.lineTo(cx + width, cy);
        path.lineTo(cx, cy + height);
        path.lineTo(cx - width, cy);
        path.closePath();
    }
});

/**
 * Pin shape
 * @inner
 */
const Pin = graphic.Path.extend({
    type: 'pin',
    shape: {
        // x, y on the cusp
        x: 0,
        y: 0,
        width: 0,
        height: 0
    },

    buildPath: function (path, shape) {
        const x = shape.x;
        const y = shape.y;
        const w = shape.width / 5 * 3;
        // Height must be larger than width
        const h = Math.max(w, shape.height);
        const r = w / 2;

        // Dist on y with tangent point and circle center
        const dy = r * r / (h - r);
        const cy = y - h + r + dy;
        const angle = Math.asin(dy / r);
        // Dist on x with tangent point and circle center
        const dx = Math.cos(angle) * r;

        const tanX = Math.sin(angle);
        const tanY = Math.cos(angle);

        const cpLen = r * 0.6;
        const cpLen2 = r * 0.7;

        path.moveTo(x - dx, cy + dy);

        path.arc(
            x, cy, r,
            Math.PI - angle,
            Math.PI * 2 + angle
        );
        path.bezierCurveTo(
            x + dx - tanX * cpLen, cy + dy + tanY * cpLen,
            x, y - cpLen2,
            x, y
        );
        path.bezierCurveTo(
            x, y - cpLen2,
            x - dx + tanX * cpLen, cy + dy + tanY * cpLen,
            x - dx, cy + dy
        );
        path.closePath();
    }
});

/**
 * Arrow shape
 * @inner
 */
const Arrow = graphic.Path.extend({

    type: 'arrow',

    shape: {
        x: 0,
        y: 0,
        width: 0,
        height: 0
    },

    buildPath: function (ctx, shape) {
        const height = shape.height;
        const width = shape.width;
        const x = shape.x;
        const y = shape.y;
        const dx = width / 3 * 2;
        ctx.moveTo(x, y);
        ctx.lineTo(x + dx, y + height);
        ctx.lineTo(x, y + height / 4 * 3);
        ctx.lineTo(x - dx, y + height);
        ctx.lineTo(x, y);
        ctx.closePath();
    }
});

/**
 * Map of path contructors
 */
// TODO Use function to build symbol path.
const symbolCtors: Dictionary<SymbolCtor> = {
    // Use small height rect to simulate line.
    // Avoid using stroke.
    line: graphic.Rect as unknown as SymbolCtor,

    rect: graphic.Rect as unknown as SymbolCtor,

    roundRect: graphic.Rect as unknown as SymbolCtor,

    square: graphic.Rect as unknown as SymbolCtor,

    circle: graphic.Circle as unknown as SymbolCtor,

    diamond: Diamond as unknown as SymbolCtor,

    pin: Pin as unknown as SymbolCtor,

    arrow: Arrow as unknown as SymbolCtor,

    triangle: Triangle as unknown as SymbolCtor
};


// NOTICE Only use fill. No line!
const symbolShapeMakers: Dictionary<SymbolShapeMaker> = {

    line: function (x, y, w, h, shape: graphic.Rect['shape']) {
        const thickness = 2;
        // A thin line
        shape.x = x;
        shape.y = y + h / 2 - thickness / 2;
        shape.width = w;
        shape.height = thickness;
    },

    rect: function (x, y, w, h, shape: graphic.Rect['shape']) {
        shape.x = x;
        shape.y = y;
        shape.width = w;
        shape.height = h;
    },

    roundRect: function (x, y, w, h, shape: graphic.Rect['shape']) {
        shape.x = x;
        shape.y = y;
        shape.width = w;
        shape.height = h;
        shape.r = Math.min(w, h) / 4;
    },

    square: function (x, y, w, h, shape: graphic.Rect['shape']) {
        const size = Math.min(w, h);
        shape.x = x;
        shape.y = y;
        shape.width = size;
        shape.height = size;
    },

    circle: function (x, y, w, h, shape: graphic.Circle['shape']) {
        // Put circle in the center of square
        shape.cx = x + w / 2;
        shape.cy = y + h / 2;
        shape.r = Math.min(w, h) / 2;
    },

    diamond: function (x, y, w, h, shape: InstanceType<typeof Diamond>['shape']) {
        shape.cx = x + w / 2;
        shape.cy = y + h / 2;
        shape.width = w;
        shape.height = h;
    },

    pin: function (x, y, w, h, shape: InstanceType<typeof Pin>['shape']) {
        shape.x = x + w / 2;
        shape.y = y + h / 2;
        shape.width = w;
        shape.height = h;
    },

    arrow: function (x, y, w, h, shape: InstanceType<typeof Arrow>['shape']) {
        shape.x = x + w / 2;
        shape.y = y + h / 2;
        shape.width = w;
        shape.height = h;
    },

    triangle: function (x, y, w, h, shape: InstanceType<typeof Triangle>['shape']) {
        shape.cx = x + w / 2;
        shape.cy = y + h / 2;
        shape.width = w;
        shape.height = h;
    }
};

export const symbolBuildProxies: Dictionary<ECSymbol> = {};
zrUtil.each(symbolCtors, function (Ctor, name) {
    symbolBuildProxies[name] = new Ctor();
});

const SymbolClz = graphic.Path.extend({

    type: 'symbol',

    shape: {
        symbolType: '',
        x: 0,
        y: 0,
        width: 0,
        height: 0
    },

    calculateTextPosition(out, config, rect) {
        const res = calculateTextPosition(out, config, rect);
        const shape = this.shape;
        if (shape && shape.symbolType === 'pin' && config.position === 'inside') {
            res.y = rect.y + rect.height * 0.4;
        }
        return res;
    },

    buildPath: function (ctx, shape, inBundle) {
        let symbolType = shape.symbolType;
        if (symbolType !== 'none') {
            let proxySymbol = symbolBuildProxies[symbolType];
            if (!proxySymbol) {
                // Default rect
                symbolType = 'rect';
                proxySymbol = symbolBuildProxies[symbolType];
            }
            symbolShapeMakers[symbolType](
                shape.x, shape.y, shape.width, shape.height, proxySymbol.shape
            );
            proxySymbol.buildPath(ctx, proxySymbol.shape, inBundle);
        }
    }
});

// Provide setColor helper method to avoid determine if set the fill or stroke outside
function symbolPathSetColor(this: ECSymbol, color: ZRColor, innerColor?: string) {
    if (this.type !== 'image') {
        const symbolStyle = this.style;
        if (this.__isEmptyBrush) {
            symbolStyle.stroke = color;
            symbolStyle.fill = innerColor || '#fff';
            // TODO Same width with lineStyle in LineView.
            symbolStyle.lineWidth = 2;
        }
        else {
            symbolStyle.fill = color;
        }
        this.markRedraw();
    }
}

/**
 * Create a symbol element with given symbol configuration: shape, x, y, width, height, color
 */
export function createSymbol(
    symbolType: string,
    x: number,
    y: number,
    w: number,
    h: number,
    color?: ZRColor,
    // whether to keep the ratio of w/h,
    keepAspect?: boolean
) {
    // TODO Support image object, DynamicImage.

    const isEmpty = symbolType.indexOf('empty') === 0;
    if (isEmpty) {
        symbolType = symbolType.substr(5, 1).toLowerCase() + symbolType.substr(6);
    }
    let symbolPath: ECSymbol | graphic.Image;

    if (symbolType.indexOf('image://') === 0) {
        symbolPath = graphic.makeImage(
            symbolType.slice(8),
            new BoundingRect(x, y, w, h),
            keepAspect ? 'center' : 'cover'
        );
    }
    else if (symbolType.indexOf('path://') === 0) {
        symbolPath = graphic.makePath(
            symbolType.slice(7),
            {},
            new BoundingRect(x, y, w, h),
            keepAspect ? 'center' : 'cover'
        ) as unknown as ECSymbol;
    }
    else {
        symbolPath = new SymbolClz({
            shape: {
                symbolType: symbolType,
                x: x,
                y: y,
                width: w,
                height: h
            }
        }) as unknown as ECSymbol;
    }

    (symbolPath as ECSymbol).__isEmptyBrush = isEmpty;

    // TODO Should deprecate setColor
    (symbolPath as ECSymbol).setColor = symbolPathSetColor;

    if (color) {
        (symbolPath as ECSymbol).setColor(color);
    }

    return symbolPath as ECSymbol;
}
