File size: 7,658 Bytes
a812b4e
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
document.addEventListener('DOMContentLoaded', () => {
    /* --- Clock --- */
    function updateClock() {
        const now = new Date();
        const timeString = now.toLocaleTimeString('en-US', { hour12: false });
        const clockEl = document.getElementById('clock');
        if(clockEl) clockEl.textContent = timeString;
    }
    setInterval(updateClock, 1000);
    updateClock();

    /* --- Operation Control Logic --- */
    let simState = 'IDLE'; // IDLE, RUNNING, PAUSED
    let simTime = 0;
    let simInterval = null;
    let progress = 0;

    const statusText = document.getElementById('sim-status-text');
    const timerText = document.getElementById('sim-timer');
    const progressBar = document.getElementById('sim-progress');
    const btnAdvance = document.getElementById('btn-advance');
    const btnPause = document.getElementById('btn-pause');
    const btnReset = document.getElementById('btn-reset');

    function formatTime(seconds) {
        const h = Math.floor(seconds / 3600).toString().padStart(2, '0');
        const m = Math.floor((seconds % 3600) / 60).toString().padStart(2, '0');
        const s = (seconds % 60).toString().padStart(2, '0');
        return `${h}:${m}:${s}`;
    }

    function updateUI() {
        statusText.textContent = simState;
        
        // Color coding based on state
        statusText.classList.remove('text-neon-green', 'text-neon-orange', 'text-gray-500');
        if (simState === 'RUNNING') {
            statusText.classList.add('text-neon-green');
            statusText.classList.add('animate-pulse');
        } else if (simState === 'PAUSED') {
            statusText.classList.add('text-neon-orange');
            statusText.classList.remove('animate-pulse');
        } else {
            statusText.classList.add('text-gray-500');
            statusText.classList.remove('animate-pulse');
        }

        timerText.textContent = formatTime(simTime);
        progressBar.style.width = `${progress}%`;
    }

    btnAdvance.addEventListener('click', () => {
        if (simState === 'RUNNING') return; // Already running
        
        simState = 'RUNNING';
        statusText.classList.add('animate-pulse');
        
        simInterval = setInterval(() => {
            simTime++;
            progress = (simTime % 60) / 60 * 100; // Loop progress for demo
            updateUI();
            if (simTime % 60 === 0 && simTime > 0) {
                addAiMessage("Simulation milestone reached. Analyzing vector performance...", false);
            }
        }, 1000);
        
        updateUI();
        addAiMessage("Simulation sequence initiated. Engines firing.", false);
    });

    btnPause.addEventListener('click', () => {
        if (simState !== 'RUNNING') return;
        
        simState = 'PAUSED';
        clearInterval(simInterval);
        updateUI();
        addAiMessage("Simulation paused. Awaiting command.", false);
    });

    btnReset.addEventListener('click', () => {
        simState = 'IDLE';
        clearInterval(simInterval);
        simTime = 0;
        progress = 0;
        updateUI();
        addAiMessage("Simulation reset. All parameters normalized.", false);
    });

    /* --- AI Companion & NLP --- */
    const chatHistory = document.getElementById('chat-history');
    const aiInput = document.getElementById('ai-input');
    const voiceBtn = document.getElementById('voice-btn');
    const nlpStatus = document.getElementById('nlp-status');
    const cmdChips = document.querySelectorAll('.cmd-chip');

    function addAiMessage(text, isUser = false) {
        const div = document.createElement('div');
        div.className = `flex items-start gap-3 ${isUser ? 'flex-row-reverse' : ''}`;
        
        const iconColor = isUser ? 'bg-neon-green/20 text-neon-green' : 'bg-gradient-to-br from-gray-700 to-gray-900 text-neon-gold';
        const icon = isUser ? '<i data-feather="user" class="w-4 h-4"></i>' : '<i data-feather="aperture" class="w-4 h-4"></i>';
        const bubbleColor = isUser ? 'bg-neon-green/10 border-neon-green/30' : 'bg-void-700 border-gray-700';
        
        div.innerHTML = `
            <div class="w-8 h-8 rounded flex items-center justify-center border border-gray-600 shrink-0 ${iconColor}">
                ${icon}
            </div>
            <div class="p-3 rounded-lg text-sm text-gray-200 border shadow-sm max-w-[80%] ${isUser ? 'rounded-tr-none' : 'rounded-tl-none'} ${bubbleColor}">
                <p>${text}</p>
            </div>
        `;
        
        chatHistory.appendChild(div);
        chatHistory.scrollTop = chatHistory.scrollHeight;
        feather.replace();
    }

    function handleCommand(text) {
        const lower = text.toLowerCase();
        let response = "";

        if (lower.includes("pause") || lower.includes("stop")) {
            if (simState === 'RUNNING') btnPause.click();
            response = "Acknowledged. Pausing operations.";
        } else if (lower.includes("start") || lower.includes("advance") || lower.includes("resume")) {
            if (simState !== 'RUNNING') btnAdvance.click();
            response = "Acknowledged. Advancing simulation.";
        } else if (lower.includes("reset")) {
            btnReset.click();
            response = "System resetting to initial state.";
        } else if (lower.includes("status") || lower.includes("report")) {
            response = `Current Status: ${simState}. Runtime: ${formatTime(simTime)}. Progress: ${Math.floor(progress)}%.`;
        } else if (lower.includes("hello") || lower.includes("hi")) {
            response = "Greetings, Commander. Systems nominal.";
        } else {
            response = `I received: "${text}". Please clarify the tactical directive.`;
        }

        addAiMessage(text, true);
        setTimeout(() => addAiMessage(response, false), 600);
    }

    // Text Input
    aiInput.addEventListener('keypress', (e) => {
        if (e.key === 'Enter' && aiInput.value.trim()) {
            handleCommand(aiInput.value);
            aiInput.value = '';
        }
    });

    // Chip Inputs
    cmdChips.forEach(chip => {
        chip.addEventListener('click', () => {
            handleCommand(chip.textContent);
        });
    });

    // NLP / Web Speech API
    if ('webkitSpeechRecognition' in window || 'SpeechRecognition' in window) {
        const SpeechRecognition = window.SpeechRecognition || window.webkitSpeechRecognition;
        const recognition = new SpeechRecognition();
        
        recognition.continuous = false;
        recognition.lang = 'en-US';
        recognition.interimResults = false;

        recognition.onstart = () => {
            nlpStatus.textContent = "LISTENING...";
            nlpStatus.classList.remove('text-gray-400', 'border-gray-600');
            nlpStatus.classList.add('text-neon-red', 'border-neon-red', 'animate-pulse');
            voiceBtn.classList.add('text-neon-red');
        };

        recognition.onend = () => {
            nlpStatus.textContent = "VOICE OFF";
            nlpStatus.classList.add('text-gray-400', 'border-gray-600');
            nlpStatus.classList.remove('text-neon-red', 'border-neon-red', 'animate-pulse');
            voiceBtn.classList.remove('text-neon-red');
        };

        recognition.onresult = (event) => {
            const transcript = event.results[0][0].transcript;
            handleCommand(transcript);
        };

        voiceBtn.addEventListener('click', () => {
            recognition.start();
        });
    } else {
        voiceBtn.style.display = 'none';
        console.log("Web Speech API not supported in this browser.");
    }
});