/**
 * Drawing Tools for Lightweight Charts
 * Implements professional trading chart drawing primitives
 */

export class DrawingManager {
    constructor(dashboard, container) {
        this.dashboard = dashboard;
        this.chart = dashboard.chart;
        this.series = dashboard.candleSeries;
        this.container = container;
        this.drawings = [];
        this.activeTool = null;
        this.currentDrawing = null;
        this.selectedDrawing = null;
        this.dragMode = null; 
        this.isMouseDown = false;
        
        // Dragging offsets
        this.dragStartPos = null;
        this.startP1 = null;
        this.startP2 = null;
        this.startPrice = null;
        this.startTime = null;
        
        this.init();
    }

    init() {
        const container = this.container;
        
        container.addEventListener('mousedown', (e) => this.handleMouseDown(e));
        window.addEventListener('mousemove', (e) => this.handleMouseMove(e));
        window.addEventListener('mouseup', (e) => this.handleMouseUp(e));
        
        window.addEventListener('keydown', (e) => {
            if ((e.key === 'Delete' || e.key === 'Backspace') && this.selectedDrawing) {
                this.drawings = this.drawings.filter(d => d !== this.selectedDrawing);
                this.selectedDrawing = null;
                this.update();
            }
        });
        
        this.drawingPrimitive = {
            attached: (param) => {
                this.requestUpdate = param.requestUpdate;
            },
            detached: () => {
                this.requestUpdate = undefined;
            },
            updateAllViews: () => {},
            paneViews: () => [{
                renderer: () => ({
                    draw: (target) => this.render(target)
                })
            }],
            priceAxisViews: () => this.getPriceAxisViews(),
            timeAxisViews: () => this.getTimeAxisViews()
        };
        
        this.series.attachPrimitive(this.drawingPrimitive);
    }

    getPriceAxisViews() {
        const views = [];
        const drawingsToShow = [];
        if (this.currentDrawing && this.currentDrawing.type === 'measure') drawingsToShow.push(this.currentDrawing);
        if (this.selectedDrawing && this.selectedDrawing.type === 'measure') drawingsToShow.push(this.selectedDrawing);

        drawingsToShow.forEach(d => {
            const isUp = d.p2.price >= d.p1.price;
            const color = isUp ? '#26a69a' : '#ef5350';
            [d.p1.price, d.p2.price].forEach(price => {
                views.push({
                    coordinate: () => this.series.priceToCoordinate(price),
                    text: () => price.toFixed(2),
                    textColor: () => '#ffffff',
                    backColor: () => color,
                    visible: () => true,
                });
            });
        });
        return views;
    }

    getTimeAxisViews() {
        const views = [];
        const drawingsToShow = [];
        if (this.currentDrawing && this.currentDrawing.type === 'measure') drawingsToShow.push(this.currentDrawing);
        if (this.selectedDrawing && this.selectedDrawing.type === 'measure') drawingsToShow.push(this.selectedDrawing);

        drawingsToShow.forEach(d => {
            const isUp = d.p2.price >= d.p1.price;
            const color = isUp ? '#26a69a' : '#ef5350';
            [d.p1.time, d.p2.time].forEach(time => {
                views.push({
                    coordinate: () => this.chart.timeScale().timeToCoordinate(time),
                    text: () => {
                        const date = new Date(time * 1000);
                        const day = date.getDate().toString().padStart(2, '0');
                        const months = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'];
                        const month = months[date.getMonth()];
                        const year = date.getFullYear().toString().slice(-2);
                        const hours = date.getHours().toString().padStart(2, '0');
                        const mins = date.getMinutes().toString().padStart(2, '0');
                        return `${day} ${month} '${year}  ${hours}:${mins}`;
                    },
                    textColor: () => '#ffffff',
                    backColor: () => color,
                    visible: () => true,
                });
            });
        });
        return views;
    }

    updateChartInteractions() {
        const isInteracting = this.activeTool !== null || this.currentDrawing !== null || (this.selectedDrawing !== null && this.isMouseDown);
        
        this.chart.applyOptions({
            handleScroll: {
                mouseWheel: !isInteracting,
                pressedMouseMove: !isInteracting,
                horzTouchDrag: !isInteracting,
                vertTouchDrag: !isInteracting,
            },
            handleScale: {
                axisPressedMouseMove: !isInteracting,
                mouseWheel: !isInteracting,
                pinch: !isInteracting,
            }
        });
    }

    setTool(tool) {
        this.activeTool = tool;
        
        if (tool === 'cursor') {
            this.activeTool = null;
            document.body.style.cursor = 'default';
        } else if (tool === 'clear') {
            this.drawings = [];
            this.selectedDrawing = null;
            this.activeTool = null;
            this.update();
        } else {
            document.body.style.cursor = 'crosshair';
            this.selectedDrawing = null;
        }
        
        this.updateChartInteractions();
        this.update();
    }

    getMousePos(e) {
        const rect = this.container.getBoundingClientRect();
        const x = e.clientX - rect.left;
        const y = e.clientY - rect.top;
        const time = this.chart.timeScale().coordinateToTime(x);
        const price = this.series.coordinateToPrice(y);
        return { x, y, time, price };
    }

    handleMouseDown(e) {
        const pos = this.getMousePos(e);
        this.isMouseDown = true;
        this.dragStartPos = pos;

        // Shift + Click shortcut for Measurement Tool
        if (e.shiftKey && !this.activeTool) {
            this.setTool('measure');
            this.currentDrawing = { 
                type: 'measure', 
                p1: { time: pos.time, price: pos.price }, 
                p2: { time: pos.time, price: pos.price }, 
                color: '#26a69a' 
            };
            this.update();
            return;
        }

        // Click-Move-Click logic for Measurement Tool
        if (this.activeTool === 'measure') {
            if (this.currentDrawing) {
                // 2nd Click: Finish
                this.drawings.push(this.currentDrawing);
                this.currentDrawing = null;
                this.setTool(null);
                this.isMouseDown = false;
                this.update();
                return;
            } else {
                // 1st Click: Start
                this.currentDrawing = { 
                    type: 'measure', 
                    p1: { time: pos.time, price: pos.price }, 
                    p2: { time: pos.time, price: pos.price }, 
                    color: '#26a69a' 
                };
                this.update();
                return;
            }
        }

        if (!this.activeTool) {
            const hit = this.findHit(pos.x, pos.y);
            if (hit) {
                this.selectedDrawing = hit.drawing;
                this.dragMode = hit.part;
                
                const d = this.selectedDrawing;
                if (d.p1) this.startP1 = { ...d.p1 };
                if (d.p2) this.startP2 = { ...d.p2 };
                if (d.price !== undefined) this.startPrice = d.price;
                if (d.time !== undefined) this.startTime = d.time;
                
                this.updateChartInteractions();
                this.update();
                return;
            } else {
                this.selectedDrawing = null;
                this.dragMode = null;
            }
        }

        if (!this.activeTool || pos.time === null || pos.price === null) {
            this.update();
            return;
        }
        
        const color = '#2962ff';
        const p1 = { time: pos.time, price: pos.price };
        const p2 = { time: pos.time, price: pos.price };

        if (this.activeTool === 'trend_line' || this.activeTool === 'ray' || this.activeTool === 'rectangle') {
            this.currentDrawing = { type: this.activeTool, p1, p2, color };
        } else if (this.activeTool === 'horizontal_line') {
            this.drawings.push({ type: 'horizontal_line', price: pos.price, color });
            this.setTool(null);
        } else if (this.activeTool === 'vertical_line') {
            this.drawings.push({ type: 'vertical_line', time: pos.time, color });
            this.setTool(null);
        } else if (this.activeTool === 'fib_retracement') {
            this.currentDrawing = { type: 'fib_retracement', p1, p2, color: '#fb8c00' };
        } else if (this.activeTool === 'arrow_up' || this.activeTool === 'arrow_down') {
            this.drawings.push({
                type: 'arrow', time: pos.time, price: pos.price,
                direction: this.activeTool === 'arrow_up' ? 'up' : 'down',
                color: this.activeTool === 'arrow_up' ? '#26a69a' : '#ef5350'
            });
            this.setTool(null);
        } else if (this.activeTool === 'text') {
            const text = prompt('Enter text:');
            if (text) this.drawings.push({ type: 'text', time: pos.time, price: pos.price, text, color: '#ffffff' });
            this.setTool(null);
        }
        this.update();
    }

    handleMouseMove(e) {
        const pos = this.getMousePos(e);
        if (!this.isMouseDown && !this.activeTool) {
            const hit = this.findHit(pos.x, pos.y);
            this.container.style.cursor = hit ? 'pointer' : 'default';
        }

        if (this.currentDrawing && this.currentDrawing.type === 'measure') {
            if (pos.time !== null) {
                this.currentDrawing.p2 = { time: pos.time, price: pos.price };
                this.update();
            }
            return;
        }

        if (!this.isMouseDown) return;

        if (this.selectedDrawing && this.dragMode) {
            if (pos.time === null || pos.price === null) return;
            const d = this.selectedDrawing;
            if (this.dragMode === 'p1') {
                d.p1 = { time: pos.time, price: pos.price };
            } else if (this.dragMode === 'p2') {
                d.p2 = { time: pos.time, price: pos.price };
            } else if (this.dragMode === 'all') {
                const timeDiff = pos.time - this.dragStartPos.time;
                const priceDiff = pos.price - this.dragStartPos.price;
                if (d.p1 && d.p2) {
                    d.p1.time = this.startP1.time + timeDiff;
                    d.p1.price = this.startP1.price + priceDiff;
                    d.p2.time = this.startP2.time + timeDiff;
                    d.p2.price = this.startP2.price + priceDiff;
                } else if (d.time !== undefined && d.price !== undefined) {
                    d.time = this.startTime + timeDiff;
                    d.price = this.startPrice + priceDiff;
                } else if (d.price !== undefined) {
                    d.price = this.startPrice + priceDiff;
                } else if (d.time !== undefined) {
                    d.time = this.startTime + timeDiff;
                }
            } else if (this.dragMode === 'price') {
                d.price = pos.price;
            } else if (this.dragMode === 'time') {
                d.time = pos.time;
            }
            this.update();
            return;
        }

        if (this.currentDrawing && pos.time !== null) {
            this.currentDrawing.p2 = { time: pos.time, price: pos.price };
            this.update();
        }
    }

    handleMouseUp() {
        if (this.currentDrawing && this.currentDrawing.type === 'measure') {
            this.isMouseDown = false;
            this.updateChartInteractions();
            this.update();
            return; 
        }

        if (this.currentDrawing) {
            this.drawings.push(this.currentDrawing);
            this.currentDrawing = null;
            this.setTool(null);
        }
        this.dragMode = null;
        this.isMouseDown = false;
        this.updateChartInteractions();
        this.update();
    }

    findHit(x, y) {
        const threshold = 10;
        for (let i = this.drawings.length - 1; i >= 0; i--) {
            const d = this.drawings[i];
            if (d.p1 && d.p2) {
                const x1 = this.chart.timeScale().timeToCoordinate(d.p1.time);
                const y1 = this.series.priceToCoordinate(d.p1.price);
                const x2 = this.chart.timeScale().timeToCoordinate(d.p2.time);
                const y2 = this.series.priceToCoordinate(d.p2.price);
                if (x1 === null || y1 === null || x2 === null || y2 === null) continue;
                if (Math.hypot(x - x1, y - y1) < threshold) return { drawing: d, part: 'p1' };
                if (Math.hypot(x - x2, y - y2) < threshold) return { drawing: d, part: 'p2' };
                
                if (d.type === 'rectangle' || d.type === 'measure') {
                    if (x >= Math.min(x1, x2) && x <= Math.max(x1, x2) && y >= Math.min(y1, y2) && y <= Math.max(y1, y2)) return { drawing: d, part: 'all' };
                } else {
                    const dist = this.distToSegment({ x, y }, { x: x1, y: y1 }, { x: x2, y: y2 });
                    if (dist < threshold) return { drawing: d, part: 'all' };
                }
            } else if (d.price !== undefined && d.type === 'horizontal_line') {
                const dy = this.series.priceToCoordinate(d.price);
                if (Math.abs(y - dy) < threshold) return { drawing: d, part: 'price' };
            } else if (d.time !== undefined && d.type === 'vertical_line') {
                const dx = this.chart.timeScale().timeToCoordinate(d.time);
                if (Math.abs(x - dx) < threshold) return { drawing: d, part: 'time' };
            } else if (d.time !== undefined && d.price !== undefined) {
                const dx = this.chart.timeScale().timeToCoordinate(d.time);
                const dy = this.series.priceToCoordinate(d.price);
                if (Math.hypot(x - dx, y - dy) < threshold) return { drawing: d, part: 'all' };
            }
        }
        return null;
    }

    distToSegment(p, v, w) {
        const l2 = Math.pow(v.x - w.x, 2) + Math.pow(v.y - w.y, 2);
        if (l2 === 0) return Math.hypot(p.x - v.x, p.y - v.y);
        let t = ((p.x - v.x) * (w.x - v.x) + (p.y - v.y) * (w.y - v.y)) / l2;
        t = Math.max(0, Math.min(1, t));
        return Math.hypot(p.x - (v.x + t * (w.x - v.x)), p.y - (v.y + t * (w.y - v.y)));
    }

    update() {
        if (this.requestUpdate) this.requestUpdate();
    }

    render(target) {
        target.useMediaCoordinateSpace((scope) => {
            const ctx = scope.context;
            const chart = this.chart;
            const series = this.series;
            const allDrawings = [...this.drawings];
            if (this.currentDrawing) allDrawings.push(this.currentDrawing);
            
            allDrawings.forEach(d => {
                const isSelected = d === this.selectedDrawing;
                ctx.save();
                ctx.strokeStyle = d.color;
                ctx.lineWidth = isSelected ? 3 : 2;
                if (isSelected) { ctx.shadowBlur = 5; ctx.shadowColor = d.color; }
                
                if (d.type === 'trend_line' || d.type === 'ray') {
                    const x1 = chart.timeScale().timeToCoordinate(d.p1.time);
                    const y1 = series.priceToCoordinate(d.p1.price);
                    const x2 = chart.timeScale().timeToCoordinate(d.p2.time);
                    const y2 = series.priceToCoordinate(d.p2.price);
                    if (x1 !== null && y1 !== null && x2 !== null && y2 !== null) {
                        ctx.beginPath();
                        ctx.moveTo(x1, y1);
                        if (d.type === 'ray') {
                            const angle = Math.atan2(y2 - y1, x2 - x1);
                            ctx.lineTo(x1 + Math.cos(angle) * 10000, y1 + Math.sin(angle) * 10000);
                        } else {
                            ctx.lineTo(x2, y2);
                        }
                        ctx.stroke();
                        if (isSelected) {
                            ctx.fillStyle = '#ffffff';
                            ctx.beginPath(); ctx.arc(x1, y1, 5, 0, Math.PI * 2); ctx.fill(); ctx.stroke();
                            ctx.beginPath(); ctx.arc(x2, y2, 5, 0, Math.PI * 2); ctx.fill(); ctx.stroke();
                        }
                    }
                } else if (d.type === 'rectangle') {
                    const x1 = chart.timeScale().timeToCoordinate(d.p1.time);
                    const y1 = series.priceToCoordinate(d.p1.price);
                    const x2 = chart.timeScale().timeToCoordinate(d.p2.time);
                    const y2 = series.priceToCoordinate(d.p2.price);
                    if (x1 !== null && y1 !== null && x2 !== null && y2 !== null) {
                        ctx.fillStyle = d.color + '22';
                        ctx.fillRect(Math.min(x1, x2), Math.min(y1, y2), Math.abs(x2 - x1), Math.abs(y2 - y1));
                        ctx.strokeRect(Math.min(x1, x2), Math.min(y1, y2), Math.abs(x2 - x1), Math.abs(y2 - y1));
                        if (isSelected) {
                            ctx.fillStyle = '#ffffff';
                            ctx.beginPath(); ctx.arc(x1, y1, 5, 0, Math.PI * 2); ctx.fill(); ctx.stroke();
                            ctx.beginPath(); ctx.arc(x2, y2, 5, 0, Math.PI * 2); ctx.fill(); ctx.stroke();
                        }
                    }
                } else if (d.type === 'horizontal_line') {
                    const y = series.priceToCoordinate(d.price);
                    if (y !== null) {
                        ctx.beginPath(); ctx.moveTo(0, y); ctx.lineTo(scope.mediaSize.width, y); ctx.stroke();
                    }
                } else if (d.type === 'vertical_line') {
                    const x = chart.timeScale().timeToCoordinate(d.time);
                    if (x !== null) {
                        ctx.beginPath(); ctx.moveTo(x, 0); ctx.lineTo(x, scope.mediaSize.height); ctx.stroke();
                    }
                } else if (d.type === 'fib_retracement') {
                    const x1 = chart.timeScale().timeToCoordinate(d.p1.time);
                    const y1 = series.priceToCoordinate(d.p1.price);
                    const x2 = chart.timeScale().timeToCoordinate(d.p2.time);
                    const y2 = series.priceToCoordinate(d.p2.price);
                    if (x1 !== null && y1 !== null && x2 !== null && y2 !== null) {
                        const levels = [0, 0.236, 0.382, 0.5, 0.618, 0.786, 1];
                        const range = d.p2.price - d.p1.price;
                        ctx.setLineDash([5, 5]); ctx.lineWidth = 1;
                        levels.forEach(level => {
                            const price = d.p1.price + (range * level);
                            const y = series.priceToCoordinate(price);
                            if (y !== null) {
                                ctx.beginPath(); ctx.moveTo(Math.min(x1, x2), y); ctx.lineTo(Math.max(x1, x2), y); ctx.stroke();
                                ctx.fillStyle = d.color; ctx.font = '10px Inter';
                                ctx.fillText(`${(level * 100).toFixed(1)}% (${price.toFixed(2)})`, Math.max(x1, x2) + 5, y + 3);
                            }
                        });
                        ctx.setLineDash([]); ctx.strokeStyle = d.color + '44';
                        ctx.beginPath(); ctx.moveTo(x1, y1); ctx.lineTo(x2, y2); ctx.stroke();
                        if (isSelected) {
                            ctx.fillStyle = '#ffffff'; ctx.strokeStyle = d.color; ctx.lineWidth = 2;
                            ctx.beginPath(); ctx.arc(x1, y1, 5, 0, Math.PI * 2); ctx.fill(); ctx.stroke();
                            ctx.beginPath(); ctx.arc(x2, y2, 5, 0, Math.PI * 2); ctx.fill(); ctx.stroke();
                        }
                    }
                } else if (d.type === 'arrow') {
                    const x = chart.timeScale().timeToCoordinate(d.time);
                    const y = series.priceToCoordinate(d.price);
                    if (x !== null && y !== null) {
                        ctx.fillStyle = d.color; ctx.beginPath();
                        const size = isSelected ? 15 : 10;
                        if (d.direction === 'up') {
                            ctx.moveTo(x, y);
                            ctx.lineTo(x - size/2, y + size);
                            ctx.lineTo(x + size/2, y + size);
                        } else {
                            ctx.moveTo(x, y);
                            ctx.lineTo(x - size/2, y - size);
                            ctx.lineTo(x + size/2, y - size);
                        }
                        ctx.fill();
                        if (isSelected) { ctx.strokeStyle = '#ffffff'; ctx.lineWidth = 1; ctx.stroke(); }
                    }
                } else if (d.type === 'text') {
                    const x = chart.timeScale().timeToCoordinate(d.time);
                    const y = series.priceToCoordinate(d.price);
                    if (x !== null && y !== null) {
                        ctx.fillStyle = d.color;
                        ctx.font = isSelected ? 'bold 14px Inter' : '12px Inter';
                        ctx.fillText(d.text, x, y);
                        if (isSelected) {
                            const metrics = ctx.measureText(d.text);
                            ctx.strokeStyle = d.color;
                            ctx.strokeRect(x - 2, y - 12, metrics.width + 4, 16);
                        }
                    }
                } else if (d.type === 'measure') {
                    const x1 = chart.timeScale().timeToCoordinate(d.p1.time);
                    const y1 = series.priceToCoordinate(d.p1.price);
                    const x2 = chart.timeScale().timeToCoordinate(d.p2.time);
                    const y2 = series.priceToCoordinate(d.p2.price);
                    
                    if (x1 !== null && y1 !== null && x2 !== null && y2 !== null) {
                        const priceDiff = d.p2.price - d.p1.price;
                        const percentChange = (priceDiff / d.p1.price) * 100;
                        const isUp = priceDiff >= 0;
                        const color = isUp ? '#26a69a' : '#ef5350';
                        
                        // 1. Draw Measurement Area
                        ctx.fillStyle = color + '33';
                        ctx.fillRect(Math.min(x1, x2), Math.min(y1, y2), Math.abs(x2 - x1), Math.abs(y2 - y1));
                        
                        // 2. Draw Crosshairs & Arrows
                        ctx.strokeStyle = color;
                        ctx.lineWidth = 1;
                        
                        // Horizontal line
                        ctx.beginPath();
                        ctx.moveTo(Math.min(x1, x2), (y1 + y2) / 2);
                        ctx.lineTo(Math.max(x1, x2), (y1 + y2) / 2);
                        ctx.stroke();
                        
                        // Vertical line
                        ctx.beginPath();
                        ctx.moveTo((x1 + x2) / 2, Math.min(y1, y2));
                        ctx.lineTo((x1 + x2) / 2, Math.max(y1, y2));
                        ctx.stroke();
                        
                        // Draw Arrows at ends of crosshairs
                        const drawArrow = (x, y, angle) => {
                            ctx.save();
                            ctx.translate(x, y);
                            ctx.rotate(angle);
                            ctx.beginPath();
                            ctx.moveTo(-6, -4);
                            ctx.lineTo(0, 0);
                            ctx.lineTo(-6, 4);
                            ctx.stroke();
                            ctx.restore();
                        };
                        
                        // Time arrow (horizontal)
                        if (x2 > x1) drawArrow(x2, (y1 + y2) / 2, 0);
                        else drawArrow(x2, (y1 + y2) / 2, Math.PI);
                        
                        // Price arrow (vertical)
                        if (y2 < y1) drawArrow((x1 + x2) / 2, y2, -Math.PI/2);
                        else drawArrow((x1 + x2) / 2, y2, Math.PI/2);

                        // 3. Data Calculation
                        // Bar count
                        const candleData = this.dashboard.allData.get(this.dashboard.currentInterval) || [];
                        const startIdx = candleData.findIndex(c => c.time === d.p1.time);
                        const endIdx = candleData.findIndex(c => c.time === d.p2.time);
                        let barCount = 0;
                        let totalVol = 0;
                        if (startIdx !== -1 && endIdx !== -1) {
                            barCount = endIdx - startIdx;
                            const minIdx = Math.min(startIdx, endIdx);
                            const maxIdx = Math.max(startIdx, endIdx);
                            for (let i = minIdx; i <= maxIdx; i++) {
                                totalVol += candleData[i].volume || 0;
                            }
                        } else {
                            // Rough estimate if not in current data
                            barCount = Math.round((d.p2.time - d.p1.time) / 60); // Assuming 1m? Better use current interval
                        }
                        
                        // Time duration
                        const diffSec = Math.abs(d.p2.time - d.p1.time);
                        const h = Math.floor(diffSec / 3600);
                        const m = Math.floor((diffSec % 3600) / 60);
                        const timeStr = `${h}h${m > 0 ? ` ${m}m` : ''}`;
                        
                        const volStr = totalVol > 1000 ? `${(totalVol/1000).toFixed(3)}K` : totalVol.toFixed(0);
                        
                        // 4. Draw Label Box
                        const labelLines = [
                            `${priceDiff.toFixed(2)} (${percentChange.toFixed(2)}%) , ${Math.round(priceDiff * 100)}`,
                            `${barCount} bars, ${timeStr}`,
                            `Vol ${volStr}`
                        ];
                        
                        ctx.font = '500 12px Inter';
                        const labelWidth = Math.max(...labelLines.map(l => ctx.measureText(l).width)) + 24;
                        const labelHeight = 65;
                        const labelX = x2 - labelWidth / 2;
                        const labelY = isUp ? y2 - labelHeight - 10 : y2 + 10;
                        
                        // Solid Box
                        ctx.fillStyle = color;
                        this.roundRect(ctx, labelX, labelY, labelWidth, labelHeight, 4);
                        ctx.fill();
                        
                        // Text
                        ctx.fillStyle = '#ffffff';
                        ctx.textAlign = 'center';
                        labelLines.forEach((line, i) => {
                            ctx.fillText(line, labelX + labelWidth/2, labelY + 20 + (i * 18));
                        });
                        
                        if (isSelected) {
                            ctx.strokeStyle = '#ffffff'; ctx.lineWidth = 2;
                            ctx.beginPath(); ctx.arc(x1, y1, 5, 0, Math.PI * 2); ctx.stroke();
                            ctx.beginPath(); ctx.arc(x2, y2, 5, 0, Math.PI * 2); ctx.stroke();
                        }
                    }
                }
                ctx.restore();
            });
        });
    }

    roundRect(ctx, x, y, width, height, radius) {
        ctx.beginPath();
        ctx.moveTo(x + radius, y);
        ctx.lineTo(x + width - radius, y);
        ctx.quadraticCurveTo(x + width, y, x + width, y + radius);
        ctx.lineTo(x + width, y + height - radius);
        ctx.quadraticCurveTo(x + width, y + height, x + width - radius, y + height);
        ctx.lineTo(x + radius, y + height);
        ctx.quadraticCurveTo(x, y + height, x, y + height - radius);
        ctx.lineTo(x, y + radius);
        ctx.quadraticCurveTo(x, y, x + radius, y);
        ctx.closePath();
    }
}
