#!/usr/bin/env python3
"""
网页预览版手部检测系统
通过Flask提供网页界面，解决树莓派图形界面问题
"""

import cv2
import threading
import time
from flask import Flask, render_template_string, Response
from picamera2 import Picamera2
import sys
import os

# 导入手部检测模块
sys.path.append(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
from src.hand_detection_3d import load_mediapipe_model, process_frame_3d

app = Flask(__name__)

class WebPreviewCamera:
    def __init__(self):
        self.picam2 = None
        self.hands_model = load_mediapipe_model(max_num_hands=1)
        self.prev_hand_data = None
        self.latest_control_signal = None
        
    def start_camera(self):
        """启动摄像头"""
        self.picam2 = Picamera2()
        video_config = self.picam2.create_video_configuration(main={"size": (640, 480)})
        self.picam2.configure(video_config)
        self.picam2.start()
        
    def get_frame(self):
        """获取处理后的帧"""
        if not self.picam2:
            return None
            
        # 获取原始帧
        frame = self.picam2.capture_array()
        frame = cv2.cvtColor(frame, cv2.COLOR_RGB2BGR)
        
        # 进行手部检测
        control_signal, self.prev_hand_data = process_frame_3d(
            frame, self.hands_model, self.prev_hand_data
        )
        self.latest_control_signal = control_signal
        
        # 在帧上添加控制信号信息
        if control_signal:
            y_offset = 30
            cv2.putText(frame, f"X: {control_signal['x_angle']:.1f}°", 
                       (10, y_offset), cv2.FONT_HERSHEY_SIMPLEX, 0.6, (0, 255, 0), 2)
            cv2.putText(frame, f"Y: {control_signal['y_angle']:.1f}°", 
                       (10, y_offset + 25), cv2.FONT_HERSHEY_SIMPLEX, 0.6, (0, 255, 0), 2)
            cv2.putText(frame, f"Z: {control_signal['z_angle']:.1f}°", 
                       (10, y_offset + 50), cv2.FONT_HERSHEY_SIMPLEX, 0.6, (0, 255, 0), 2)
            cv2.putText(frame, f"Grip: {'ON' if control_signal['grip'] else 'OFF'}", 
                       (10, y_offset + 75), cv2.FONT_HERSHEY_SIMPLEX, 0.6, 
                       (0, 0, 255) if control_signal['grip'] else (0, 255, 0), 2)
        
        return frame
        
    def generate_frames(self):
        """生成视频流"""
        while True:
            frame = self.get_frame()
            if frame is None:
                continue
                
            # 编码为JPEG
            ret, buffer = cv2.imencode('.jpg', frame)
            frame_bytes = buffer.tobytes()
            
            yield (b'--frame\r\n'
                   b'Content-Type: image/jpeg\r\n\r\n' + frame_bytes + b'\r\n')
            
            time.sleep(0.033)  # ~30 FPS

# 全局摄像头实例
camera = WebPreviewCamera()

@app.route('/')
def index():
    """主页面"""
    return render_template_string('''
    <!DOCTYPE html>
    <html>
    <head>
        <title>🍓 树莓派手部检测预览</title>
        <style>
            body { 
                font-family: Arial, sans-serif; 
                text-align: center; 
                background-color: #f0f0f0;
                margin: 0;
                padding: 20px;
            }
            .container {
                max-width: 800px;
                margin: 0 auto;
                background: white;
                padding: 20px;
                border-radius: 10px;
                box-shadow: 0 4px 6px rgba(0,0,0,0.1);
            }
            h1 { color: #333; }
            .video-container {
                margin: 20px 0;
                border: 2px solid #ddd;
                border-radius: 10px;
                overflow: hidden;
            }
            img { 
                width: 100%; 
                height: auto; 
                display: block;
            }
            .info {
                background: #e7f3ff;
                padding: 15px;
                border-radius: 5px;
                margin: 20px 0;
            }
            .controls {
                margin: 20px 0;
            }
            button {
                background: #007bff;
                color: white;
                border: none;
                padding: 10px 20px;
                border-radius: 5px;
                cursor: pointer;
                margin: 0 10px;
            }
            button:hover {
                background: #0056b3;
            }
        </style>
    </head>
    <body>
        <div class="container">
            <h1>🍓 树莓派3D手部检测系统</h1>
            
            <div class="info">
                <p><strong>操作说明:</strong></p>
                <p>• 将手部放在摄像头前</p>
                <p>• 移动手部查看三轴角度变化</p>
                <p>• 拇指和食指捏合触发抓取检测</p>
                <p>• 实时显示控制信号</p>
            </div>
            
            <div class="video-container">
                <img src="{{ url_for('video_feed') }}" alt="手部检测预览">
            </div>
            
            <div class="controls">
                <button onclick="location.reload()">🔄 刷新页面</button>
                <button onclick="window.close()">❌ 关闭窗口</button>
            </div>
            
            <div class="info">
                <p><strong>访问地址:</strong> http://树莓派IP:5000</p>
                <p><strong>提示:</strong> 可以在手机、电脑等任意设备上打开此页面查看预览</p>
            </div>
        </div>
        
        <script>
            // 自动刷新控制信号信息
            setInterval(() => {
                // 这里可以添加AJAX获取最新控制信号的代码
            }, 1000);
        </script>
    </body>
    </html>
    ''')

@app.route('/video_feed')
def video_feed():
    """视频流路由"""
    return Response(camera.generate_frames(),
                   mimetype='multipart/x-mixed-replace; boundary=frame')

def start_web_preview():
    """启动网页预览服务"""
    print("🍓 启动树莓派网页预览系统...")
    print("📷 初始化摄像头...")
    
    try:
        camera.start_camera()
        print("✅ 摄像头启动成功")
        print("🌐 启动网页服务器...")
        print("📱 请在浏览器中访问: http://localhost:5000")
        print("📱 或在其他设备访问: http://树莓派IP:5000")
        print("🛑 按 Ctrl+C 停止服务")
        
        # 启动Flask应用
        app.run(host='0.0.0.0', port=5000, debug=False, threaded=True)
        
    except KeyboardInterrupt:
        print("\n🛑 用户停止服务")
    except Exception as e:
        print(f"❌ 错误: {e}")
    finally:
        if camera.picam2:
            camera.picam2.stop()
            camera.picam2.close()
        print("✅ 网页预览系统已停止")

if __name__ == "__main__":
    start_web_preview() 