diff --git a/frontend/src/tools/drawing/SeatingTemplateTool.ts b/frontend/src/tools/drawing/SeatingTemplateTool.ts new file mode 100644 index 0000000..70ef2ad --- /dev/null +++ b/frontend/src/tools/drawing/SeatingTemplateTool.ts @@ -0,0 +1,339 @@ +import { Tool } from '../Tool'; +import { YjsDocument } from '../../crdt/YjsDocument'; + +type SeatingTemplate = 'bankett' | 'gala' | 'stehempfang' | 'parlament' | 'klasse'; + +class SeatingTemplateTool extends Tool { + private template: SeatingTemplate = 'bankett'; + private tableSpacing: number = 150; // Spacing between tables + private chairSpacing: number = 60; // Spacing between chairs + + constructor(yjsDoc: YjsDocument, template: SeatingTemplate = 'bankett') { + super(yjsDoc); + this.name = 'SeatingTemplateTool'; + this.template = template; + } + + onMouseDown(event: MouseEvent): void { + // This tool creates templates at the click position + const x = event.clientX; + const y = event.clientY; + + switch (this.template) { + case 'bankett': + this.createBankettTemplate(x, y); + break; + case 'gala': + this.createGalaTemplate(x, y); + break; + case 'stehempfang': + this.createStehempfangTemplate(x, y); + break; + case 'parlament': + this.createParlamentTemplate(x, y); + break; + case 'klasse': + this.createKlasseTemplate(x, y); + break; + } + } + + onMouseMove(event: MouseEvent): void { + // Preview template at cursor position + } + + onMouseUp(event: MouseEvent): void { + // Handle mouse up if needed + } + + onKeyUp(event: KeyboardEvent): void { + // Handle key up events + if (event.key === 'Escape') { + this.reset(); + } + } + + reset(): void { + // Reset any state if needed + } + + // Create Bankett template (long tables with chairs on both sides) + private createBankettTemplate(x: number, y: number): void { + const tableWidth = 240; + const tableHeight = 100; + const chairWidth = 45; + const chairHeight = 45; + const tablesCount = 3; + + for (let i = 0; i < tablesCount; i++) { + const tableX = x + i * (tableWidth + this.tableSpacing); + const tableY = y; + + // Create table + this.yjsDoc.createElement({ + id: Date.now().toString() + '_table_' + i, + type: 'rectangular_table', + layerId: 'default', + x: tableX, + y: tableY, + width: tableWidth, + height: tableHeight, + properties: {} + }); + + // Create chairs on both sides + const chairsPerSide = 4; + for (let j = 0; j < chairsPerSide; j++) { + const positionRatio = (j + 1) / (chairsPerSide + 1); + + // Top side chairs + this.yjsDoc.createElement({ + id: Date.now().toString() + '_chair_top_' + i + '_' + j, + type: 'chair', + layerId: 'default', + x: tableX + positionRatio * tableWidth - chairWidth / 2, + y: tableY - this.chairSpacing - chairHeight, + width: chairWidth, + height: chairHeight, + properties: {} + }); + + // Bottom side chairs + this.yjsDoc.createElement({ + id: Date.now().toString() + '_chair_bottom_' + i + '_' + j, + type: 'chair', + layerId: 'default', + x: tableX + positionRatio * tableWidth - chairWidth / 2, + y: tableY + tableHeight + this.chairSpacing, + width: chairWidth, + height: chairHeight, + properties: {} + }); + } + } + } + + // Create Gala template (round tables with chairs around) + private createGalaTemplate(x: number, y: number): void { + const tableRadius = 50; + const tablesPerRow = 3; + const tablesRows = 2; + + for (let i = 0; i < tablesRows; i++) { + for (let j = 0; j < tablesPerRow; j++) { + const tableX = x + j * (tableRadius * 2 + this.tableSpacing); + const tableY = y + i * (tableRadius * 2 + this.tableSpacing); + + // Create round table + this.yjsDoc.createElement({ + id: Date.now().toString() + '_table_' + i + '_' + j, + type: 'round_table', + layerId: 'default', + x: tableX - tableRadius, + y: tableY - tableRadius, + width: tableRadius * 2, + height: tableRadius * 2, + properties: { + radius: tableRadius, + centerX: tableX, + centerY: tableY + } + }); + + // Create chairs around table + const chairsAround = 8; + for (let k = 0; k < chairsAround; k++) { + const angle = (2 * Math.PI * k) / chairsAround; + const chairX = tableX + (tableRadius + this.chairSpacing) * Math.cos(angle) - 22.5; + const chairY = tableY + (tableRadius + this.chairSpacing) * Math.sin(angle) - 22.5; + + this.yjsDoc.createElement({ + id: Date.now().toString() + '_chair_' + i + '_' + j + '_' + k, + type: 'chair', + layerId: 'default', + x: chairX, + y: chairY, + width: 45, + height: 45, + properties: {} + }); + } + } + } + } + + // Create Stehempfang template (no chairs, just tables for drinks/food) + private createStehempfangTemplate(x: number, y: number): void { + const tableWidth = 120; + const tableHeight = 60; + const tablesPerRow = 4; + const tablesRows = 2; + + for (let i = 0; i < tablesRows; i++) { + for (let j = 0; j < tablesPerRow; j++) { + const tableX = x + j * (tableWidth + this.tableSpacing); + const tableY = y + i * (tableHeight + this.tableSpacing); + + // Create table + this.yjsDoc.createElement({ + id: Date.now().toString() + '_table_' + i + '_' + j, + type: 'rectangular_table', + layerId: 'default', + x: tableX, + y: tableY, + width: tableWidth, + height: tableHeight, + properties: {} + }); + } + } + } + + // Create Parlament template (U-shape with chairs) + private createParlamentTemplate(x: number, y: number): void { + const tableWidth = 200; + const tableHeight = 60; + const chairWidth = 45; + const chairHeight = 45; + + // Create main table (president's table) + this.yjsDoc.createElement({ + id: Date.now().toString() + '_main_table', + type: 'rectangular_table', + layerId: 'default', + x: x + tableWidth / 2, + y: y, + width: tableWidth, + height: tableHeight, + properties: {} + }); + + // Create side tables (delegates' tables) + const sideTablesCount = 4; + for (let i = 0; i < sideTablesCount; i++) { + // Left side table + this.yjsDoc.createElement({ + id: Date.now().toString() + '_left_table_' + i, + type: 'rectangular_table', + layerId: 'default', + x: x, + y: y + (i + 1) * (tableHeight + this.tableSpacing), + width: tableWidth / 2, + height: tableHeight, + properties: {} + }); + + // Right side table + this.yjsDoc.createElement({ + id: Date.now().toString() + '_right_table_' + i, + type: 'rectangular_table', + layerId: 'default', + x: x + tableWidth + tableWidth / 2, + y: y + (i + 1) * (tableHeight + this.tableSpacing), + width: tableWidth / 2, + height: tableHeight, + properties: {} + }); + + // Create chairs for side tables + // Left side chairs + this.yjsDoc.createElement({ + id: Date.now().toString() + '_left_chair_' + i, + type: 'chair', + layerId: 'default', + x: x - this.chairSpacing - chairWidth, + y: y + (i + 1) * (tableHeight + this.tableSpacing) + tableHeight / 2 - chairHeight / 2, + width: chairWidth, + height: chairHeight, + properties: {} + }); + + // Right side chairs + this.yjsDoc.createElement({ + id: Date.now().toString() + '_right_chair_' + i, + type: 'chair', + layerId: 'default', + x: x + tableWidth + tableWidth / 2 + tableWidth / 2 + this.chairSpacing, + y: y + (i + 1) * (tableHeight + this.tableSpacing) + tableHeight / 2 - chairHeight / 2, + width: chairWidth, + height: chairHeight, + properties: {} + }); + } + } + + // Create Klasse template (U-shape classroom layout) + private createKlasseTemplate(x: number, y: number): void { + const tableWidth = 120; + const tableHeight = 60; + const chairWidth = 45; + const chairHeight = 45; + + // Create teacher's table + this.yjsDoc.createElement({ + id: Date.now().toString() + '_teacher_table', + type: 'rectangular_table', + layerId: 'default', + x: x + tableWidth, + y: y, + width: tableWidth, + height: tableHeight, + properties: {} + }); + + // Create student tables in U-shape + const rows = 4; + const cols = 5; + + for (let i = 0; i < rows; i++) { + for (let j = 0; j < cols; j++) { + // Skip center tables to create U-shape + if (i > 0 && i < rows - 1 && j > 0 && j < cols - 1) continue; + + const tableX = x + j * (tableWidth + this.tableSpacing); + const tableY = y + (i + 1) * (tableHeight + this.tableSpacing); + + // Create table + this.yjsDoc.createElement({ + id: Date.now().toString() + '_student_table_' + i + '_' + j, + type: 'rectangular_table', + layerId: 'default', + x: tableX, + y: tableY, + width: tableWidth, + height: tableHeight, + properties: {} + }); + + // Create chair behind each table + this.yjsDoc.createElement({ + id: Date.now().toString() + '_student_chair_' + i + '_' + j, + type: 'chair', + layerId: 'default', + x: tableX + tableWidth / 2 - chairWidth / 2, + y: tableY + tableHeight + this.chairSpacing, + width: chairWidth, + height: chairHeight, + properties: {} + }); + } + } + } + + // Set template + setTemplate(template: SeatingTemplate): void { + this.template = template; + } + + // Set table spacing + setTableSpacing(spacing: number): void { + this.tableSpacing = spacing; + } + + // Set chair spacing + setChairSpacing(spacing: number): void { + this.chairSpacing = spacing; + } +} + +export { SeatingTemplateTool }; \ No newline at end of file