import React from 'react';
interface ToolbarProps {
onToolClick: (tool: string) => void;
}
// Inline SVG icons for toolbar items
const Icons = {
contactNO: (
<svg width="18" height="14" viewBox="0 0 18 14">
<line x1="3" y1="1" x2="3" y2="13" stroke="currentColor" strokeWidth="1.8" strokeLinecap="round"/>
<line x1="15" y1="1" x2="15" y2="13" stroke="currentColor" strokeWidth="1.8" strokeLinecap="round"/>
<line x1="3" y1="13" x2="15" y2="1" stroke="currentColor" strokeWidth="1.3" strokeLinecap="round"/>
</svg>
),
contactNC: (
<svg width="18" height="14" viewBox="0 0 18 14">
<line x1="3" y1="1" x2="3" y2="13" stroke="currentColor" strokeWidth="1.8" strokeLinecap="round"/>
<line x1="15" y1="1" x2="15" y2="13" stroke="currentColor" strokeWidth="1.8" strokeLinecap="round"/>
<line x1="3" y1="1" x2="15" y2="13" stroke="currentColor" strokeWidth="1.3" strokeLinecap="round"/>
</svg>
),
oneshot: (
<svg width="18" height="14" viewBox="0 0 18 14">
<line x1="3" y1="1" x2="3" y2="13" stroke="currentColor" strokeWidth="1.8" strokeLinecap="round"/>
<line x1="15" y1="1" x2="15" y2="13" stroke="currentColor" strokeWidth="1.8" strokeLinecap="round"/>
<text x="9" y="10" textAnchor="middle" fontSize="9" fill="currentColor" fontWeight="bold">↑</text>
</svg>
),
coil: (
<svg width="18" height="14" viewBox="0 0 18 14">
<circle cx="9" cy="7" r="6" fill="none" stroke="currentColor" strokeWidth="1.8"/>
</svg>
),
timer: (
<svg width="18" height="14" viewBox="0 0 18 14">
<rect x="2" y="1" width="14" height="12" rx="1.5" fill="none" stroke="currentColor" strokeWidth="1.5"/>
<line x1="9" y1="3" x2="9" y2="7" stroke="currentColor" strokeWidth="1.2"/>
<line x1="9" y1="7" x2="12" y2="9" stroke="currentColor" strokeWidth="1.2"/>
</svg>
),
counter: (
<svg width="18" height="14" viewBox="0 0 18 14">
<rect x="2" y="1" width="14" height="12" rx="1.5" fill="none" stroke="currentColor" strokeWidth="1.5"/>
<text x="9" y="10" textAnchor="middle" fontSize="8" fill="currentColor" fontWeight="bold">#</text>
</svg>
),
gate: (
<svg width="18" height="14" viewBox="0 0 18 14">
<polygon points="9,1 16,5 16,9 9,13 2,9 2,5" fill="none" stroke="currentColor" strokeWidth="1.5"/>
</svg>
),
branch: (
<svg width="18" height="14" viewBox="0 0 18 14">
<line x1="2" y1="7" x2="9" y2="7" stroke="currentColor" strokeWidth="1.5"/>
<line x1="9" y1="7" x2="16" y2="2" stroke="currentColor" strokeWidth="1.5"/>
<line x1="9" y1="7" x2="16" y2="12" stroke="currentColor" strokeWidth="1.5"/>
</svg>
),
math: (
<svg width="18" height="14" viewBox="0 0 18 14">
<rect x="2" y="1" width="14" height="12" rx="1.5" fill="none" stroke="currentColor" strokeWidth="1.5"/>
<text x="9" y="10.5" textAnchor="middle" fontSize="8" fill="currentColor" fontWeight="bold">Σ</text>
</svg>
),
move: (
<svg width="18" height="14" viewBox="0 0 18 14">
<rect x="1" y="2" width="16" height="10" rx="2" fill="none" stroke="currentColor" strokeWidth="1.5"/>
<text x="9" y="10" textAnchor="middle" fontSize="7" fill="currentColor" fontWeight="bold">→</text>
</svg>
),
compare: (
<svg width="18" height="14" viewBox="0 0 18 14">
<rect x="1" y="2" width="16" height="10" rx="2" fill="none" stroke="currentColor" strokeWidth="1.5"/>
<text x="9" y="10" textAnchor="middle" fontSize="8" fill="currentColor" fontWeight="bold">=</text>
</svg>
),
noop: (
<svg width="18" height="14" viewBox="0 0 18 14">
<rect x="2" y="4" width="14" height="6" rx="1" fill="none" stroke="currentColor" strokeWidth="1" strokeDasharray="2,2"/>
</svg>
),
};
export const Toolbar: React.FC<ToolbarProps> = ({ onToolClick }) => {
const tools = [
// ── Inputs ──
{ id: 'contact-no', label: 'NO Contact', icon: Icons.contactNO, category: 'Inputs' },
{ id: 'contact-nc', label: 'NC Contact', icon: Icons.contactNC, category: 'Inputs' },
{ id: 'oneshot-rising', label: 'One-Shot Rising', icon: Icons.oneshot, category: 'Inputs' },
{ id: 'oneshot-falling', label: 'One-Shot Falling', icon: Icons.oneshot, category: 'Inputs' },
// ── Outputs ──
{ id: 'coil-output', label: 'Output Coil', icon: Icons.coil, category: 'Outputs' },
{ id: 'coil-set', label: 'Set Coil', icon: Icons.coil, category: 'Outputs' },
{ id: 'coil-reset', label: 'Reset Coil', icon: Icons.coil, category: 'Outputs' },
{ id: 'coil-toggle', label: 'Toggle Coil', icon: Icons.coil, category: 'Outputs' },
{ id: 'coil-latch', label: 'Latch Coil', icon: Icons.coil, category: 'Outputs' },
{ id: 'coil-unlatch', label: 'Unlatch Coil', icon: Icons.coil, category: 'Outputs' },
// ── Timers ──
{ id: 'timer-ton', label: 'TON Timer', icon: Icons.timer, category: 'Timers' },
{ id: 'timer-tof', label: 'TOF Timer', icon: Icons.timer, category: 'Timers' },
{ id: 'timer-tp', label: 'TP Timer', icon: Icons.timer, category: 'Timers' },
{ id: 'timer-rto', label: 'RTO Timer', icon: Icons.timer, category: 'Timers' },
// ── Counters ──
{ id: 'counter-ctu', label: 'CTU Counter', icon: Icons.counter, category: 'Counters' },
{ id: 'counter-ctd', label: 'CTD Counter', icon: Icons.counter, category: 'Counters' },
{ id: 'counter-ctud', label: 'CTUD Counter', icon: Icons.counter, category: 'Counters' },
// ── Logic ──
{ id: 'gate-and', label: 'AND Gate', icon: Icons.gate, category: 'Logic' },
{ id: 'gate-or', label: 'OR Gate', icon: Icons.gate, category: 'Logic' },
{ id: 'gate-xor', label: 'XOR Gate', icon: Icons.gate, category: 'Logic' },
{ id: 'gate-not', label: 'NOT Gate', icon: Icons.gate, category: 'Logic' },
{ id: 'gate-nand', label: 'NAND Gate', icon: Icons.gate, category: 'Logic' },
{ id: 'gate-nor', label: 'NOR Gate', icon: Icons.gate, category: 'Logic' },
// ── Control ──
{ id: 'branch-and', label: 'Branch AND', icon: Icons.branch, category: 'Control' },
{ id: 'branch-or', label: 'Branch OR', icon: Icons.branch, category: 'Control' },
{ id: 'noop', label: 'NoOp', icon: Icons.noop, category: 'Control' },
// ── Data ──
{ id: 'math-add', label: 'Math ADD', icon: Icons.math, category: 'Data' },
{ id: 'math-sub', label: 'Math SUB', icon: Icons.math, category: 'Data' },
{ id: 'math-mul', label: 'Math MUL', icon: Icons.math, category: 'Data' },
{ id: 'math-div', label: 'Math DIV', icon: Icons.math, category: 'Data' },
{ id: 'move', label: 'Move', icon: Icons.move, category: 'Data' },
{ id: 'scale', label: 'Scale', icon: Icons.move, category: 'Data' },
{ id: 'compare', label: 'Compare', icon: Icons.compare, category: 'Data' },
];
const handleDragStart = (e: React.DragEvent, tool: string) => {
e.dataTransfer.setData('text/plain', tool);
e.dataTransfer.effectAllowed = 'copy';
};
// Group tools by category
const categories = [...new Set(tools.map(t => t.category))];
return (
<aside className="toolbar">
{categories.map(category => (
<div key={category}>
<h3>{category}</h3>
<div className="tool-group">
{tools.filter(t => t.category === category).map((tool) => (
<div
key={tool.id}
className="tool-item"
draggable
onDragStart={(e) => handleDragStart(e, tool.id)}
onClick={() => onToolClick(tool.id)}
>
<span className="tool-icon">{tool.icon}</span>
<span className="tool-label">{tool.label}</span>
</div>
))}
</div>
</div>
))}
</aside>
);
};