import React from 'react';
import PropTypes from 'prop-types';

import IDUtil from '../../../../util/IDUtil';

import { timeToString } from './_timeHelpers';

// Render a time axis in a canvas, by the given properties
class Axis extends React.PureComponent {
    constructor(props) {
        super(props);

        // refs
        this.canvasRef = React.createRef();
    }

    componentDidUpdate() {
        this.renderTime();
    }

    // get the optimal time step for rendering, so that we have always a nice number of steps in the view
    getTimeStep(start, end, width) {
        // get time step
        const stepsInScreen = Math.max(1, Math.round(width / 300));
        const duration = end - start;
        //const validSteps = [0.1, 0.5, 1, 5, 10, 60, 300, 900, 1800, 3600]; //sec
        const validSteps = [1, 10, 60, 600, 1800, 3600]; //sec
        const realStep = Math.max(0.1, Math.round(duration / stepsInScreen));
        let smallStep = 0.1;
        let step = realStep;
        let diff = Infinity;
        validSteps.forEach((s, index) => {
            const d = Math.abs(s - realStep);
            if (d < diff) {
                diff = d;
                step = s;
                if (index > 0) {
                    smallStep = validSteps[index - 1];
                }
            }
        });
        return { step, smallStep };
    }

    // render the time to a canvas
    renderTime() {
        // get time step
        const { start, end, width, height, pixelsPerSecond } = this.props;
        const stepSize = this.getTimeStep(start, end, width);
        const canvas = this.canvasRef.current;

        const ctx = canvas.getContext('2d');

        // clear
        ctx.fillStyle = 'black';
        ctx.fillRect(0, 0, width, height);

        // set stroke style
        ctx.strokeStyle = 'white';

        // Draw small step lines
        ctx.lineWidth = 1;
        this.drawBars(
            ctx,
            stepSize.smallStep,
            start,
            end - start,
            height,
            height / 5,
            pixelsPerSecond,
            false
        );

        // Draw Step lines and labels
        ctx.fillStyle = 'white';
        ctx.font = '13px sans';
        ctx.lineWidth = 2;
        this.drawBars(
            ctx,
            stepSize.step,
            start,
            end - start,
            height,
            height / 2,
            pixelsPerSecond,
            true
        );
    }

    // draw bars with given properties to the given context
    drawBars(
        ctx,
        stepSize,
        start,
        duration,
        height,
        size,
        pixelsPerSecond,
        drawLabels
    ) {
        const labels = [];

        // draw bars
        ctx.beginPath();
        for (
            let i = 0, x = 0, t = 0, steps = Math.ceil(duration / stepSize) + 1;
            i < steps;
            i++
        ) {
            t = -(start % stepSize) + i * stepSize;
            x = t * pixelsPerSecond;
            ctx.moveTo(x, height - size);
            ctx.lineTo(x, height);
            ctx.stroke();

            // store data for labels
            if (drawLabels) {
                labels.push({ x, time: Math.round((start + t) * 10) / 10 });
            }
        }
        ctx.closePath();

        // draw the labels
        if (drawLabels) {
            for (
                let i = 0, steps = Math.ceil(duration / stepSize) + 1;
                i < steps;
                i++
            ) {
                ctx.fillText(
                    timeToString(labels[i].time, stepSize < 1),
                    labels[i].x - 1,
                    15
                );
            }
        }
    }

    render() {
        const { width, height } = this.props;
        return (
            <div
                className={IDUtil.cssClassName('tl-axis')}
                ref={this.ref}
                style={{ height }}
            >
                <canvas
                    ref={this.canvasRef}
                    width={width}
                    height={height}
                    style={{ width: '100%', height: '100%' }}
                ></canvas>
            </div>
        );
    }
}

Axis.propTypes = {
    start: PropTypes.number.isRequired,
    end: PropTypes.number.isRequired,
    position: PropTypes.number.isRequired,
    width: PropTypes.number.isRequired,
    height: PropTypes.number.isRequired
};

export default Axis;
