'use strict';
import H from '../../parts/Globals.js';
import '../../parts/Utilities.js';

var Annotation = H.Annotation,
    MockPoint = Annotation.MockPoint,
    ControlPoint = Annotation.ControlPoint;

/**
 * @class
 * @extends Annotation
 * @memberOf Annotation
 */
function CrookedLine() {
    Annotation.apply(this, arguments);
}

H.extendAnnotation(CrookedLine, null, /** @lends Annotation.CrookedLine# */ {
    /**
     * Overrides default setter to get axes from typeOptions.
     */
    setClipAxes: function () {
        this.clipXAxis = this.chart.xAxis[this.options.typeOptions.xAxis];
        this.clipYAxis = this.chart.yAxis[this.options.typeOptions.yAxis];
    },
    getPointsOptions: function () {
        var typeOptions = this.options.typeOptions;

        return typeOptions.points.map(function (pointOptions) {
            pointOptions.xAxis = typeOptions.xAxis;
            pointOptions.yAxis = typeOptions.yAxis;

            return pointOptions;
        });
    },

    getControlPointsOptions: function () {
        return this.getPointsOptions();
    },

    addControlPoints: function () {
        this.getControlPointsOptions().forEach(
            function (pointOptions, i) {
                var controlPoint = new ControlPoint(
                    this.chart,
                    this,
                    H.merge(
                        this.options.controlPointOptions,
                        pointOptions.controlPoint
                    ),
                    i
                );

                this.controlPoints.push(controlPoint);

                pointOptions.controlPoint = controlPoint.options;
            },
            this
        );
    },

    addShapes: function () {
        var typeOptions = this.options.typeOptions,
            shape = this.initShape(
                H.merge(typeOptions.line, {
                    type: 'path',
                    points: this.points.map(function (point, i) {
                        return function (target) {
                            return target.annotation.points[i];
                        };
                    })
                }),
                false
            );

        typeOptions.line = shape.options;
    }
},
    /**
     * A crooked line annotation.
     *
     * @excluding labels, shapes
     * @sample highcharts/annotations-advanced/crooked-line/
     *         Crooked line
     * @product highstock
     * @optionparent annotations.crookedLine
     */
    {
        /**
         * Additional options for an annotation with the type.
         */
        typeOptions: {
            /**
             * This number defines which xAxis the point is connected to.
             * It refers to either the axis id or the index of the axis
             * in the xAxis array.
             */
            xAxis: 0,
            /**
             * This number defines which yAxis the point is connected to.
             * It refers to either the axis id or the index of the axis
             * in the xAxis array.
             */
            yAxis: 0,

            /**
             * @type {Array<Object>}
             * @apioption annotations.crookedLine.typeOptions.points
             */

            /**
             * The x position of the point.
             * @type {number}
             * @apioption annotations.crookedLine.typeOptions.points.x
             */

            /**
             * The y position of the point.
             * @type {number}
             * @apioption annotations.crookedLine.typeOptions.points.y
             */

            /**
             * @type {number}
             * @excluding positioner, events
             * @apioption annotations.crookedLine.typeOptions.points.controlPoint
             */

            /**
             * Line options.
             *
             * @type {Object}
             * @excluding height, point, points, r, type, width
             */
            line: {
                fill: 'none'
            }
        },

        /**
         * @excluding positioner, events
         */
        controlPointOptions: {
            positioner: function (target) {
                var graphic = this.graphic,
                    xy = MockPoint.pointToPixels(target.points[this.index]);

                return {
                    x: xy.x - graphic.width / 2,
                    y: xy.y - graphic.height / 2
                };
            },

            events: {
                drag: function (e, target) {
                    if (
                        target.chart.isInsidePlot(
                            e.chartX - target.chart.plotLeft,
                            e.chartY - target.chart.plotTop
                        )
                    ) {
                        var translation = this.mouseMoveToTranslation(e);

                        target.translatePoint(
                            translation.x,
                            translation.y,
                            this.index
                        );

                        target.redraw(false);
                    }
                }
            }
        }
    }
);

Annotation.types.crookedLine = CrookedLine;

export default CrookedLine;
