/**
 * PointChart class extends the Chart class to represent data with points
 */
class PointChart extends Chart {
    /**
     * Constructor for the PointChart class
     * @param {HTMLElement} canvas - The canvas element to draw the chart on
     * @param {Array} data - The data array containing values for the chart
     * @param {Object} settings - The settings object for configuring the chart
     * @param {ZoomManager} zoom - The zoom manager for the chart.
     */
    constructor(canvas, data, settings, zoom) {
        // Call the constructor of the parent class (Chart)
        super(canvas, data, settings, zoom)
    }

    /**
     * Calculates the position of a point on the chart.
     * 
     * @param {number} i - The index of the point.
     * @param {number} value - The value of the point.
     * @returns {Object} The position of the point {x, y}.
     */
    getPointPos(i, value) {
        return {
            x: Math.round(this.zoomBounds.left + this.zoomBounds.width / (this.dataLen - 1) * i),
            y: Math.round(this.zoomBounds.xAxis - value / this.extreme * this.scale)// * this.zoom.scaleY)
        }
    }

    /**
     * Draws the data points on the chart
     * @param {Array} values - The array of values to be plotted
     * @param {string} name - The name or label associated with the values
     * @param {string} color - The color to use for drawing the points
     */
    drawPoints(values, name, color) {
        // Set the fill and stroke styles for the points
        this.ctx.fillStyle = color

        // Set border values if enabled
        if (this.settings.pointBorderSize > 0) {
            this.ctx.lineWidth = this.settings.pointBorderSize
            this.ctx.strokeStyle = this.settings.pointBorderColor
        }

        // Iterate over the values to plot each data point
        for (let i = 0; i < this.dataLen; i++) {

            // Skip empty points
            if (values[i] === null || values[i] === undefined)
                continue

            // Calculate the x and y coordinates for the data point
            let pos = this.getPointPos(i, values[i])

            // Create a new Circle object for the data point
            let shape = new Circle(this.ctx, values[i], name, pos.x, pos.y, this.settings.pointSize)

            // Don't draw objects outside of screen (zoom or panning)
            if (this.isInBounds(shape.getCenter())) {
                shape.draw(this.ctx)

                // Draw a border if enabled
                if (this.settings.pointBorderSize > 0)
                    this.ctx.stroke()
            }

            // Add the shape
            this.objects.push(shape)
        }
    }

    /**
     * Draws the entire PointChart
     * @param {Boolean} async - Says if the chart should be drawn synchronously or asynchronously
     */
    draw(async = true) {
        // Clear the canvas and draw the axis
        this.clear()
        this.drawAxis()

        // Draw the data points
        let fn = () => this.data.forEach((categ, colId) => { this.drawPoints(categ.values, colId, categ.color) })
        if (this.settings.displayPoints)
            async ? setTimeout(() => fn(), 0) : fn()
    }
}
