#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
视频播放集成模块
用于在现有的Panda3D编辑器中添加视频播放功能
"""

from panda3d.core import (
    MovieTexture, CardMaker, Texture, PNMImage,
    TextureStage, NodePath, Vec3
)
import os
import math

class VideoManager:
    """视频管理器 - 集成到现有的MyWorld类中"""
    
    def __init__(self, world_instance):
        self.world = world_instance
        self.video_objects = []  # 存储所有视频对象
        self.supported_formats = ['.mp4', '.avi', '.mov', '.mkv', '.webm']
        
    def create_video_screen(self, pos=(0, 0, 0), size=(4, 3), video_path=None, name="video_screen"):
        """创建视频屏幕"""
        try:
            # 创建屏幕几何体
            cm = CardMaker(f"video_screen_{len(self.video_objects)}")
            cm.setFrame(-size[0]/2, size[0]/2, -size[1]/2, size[1]/2)
            
            video_screen = self.world.render.attachNewNode(cm.generate())
            video_screen.setPos(*pos)
            video_screen.setName(name)
            
            # 创建视频纹理
            if video_path and os.path.exists(video_path):
                # Convert Windows path to Panda3D compatible path format
                from panda3d.core import Filename
                panda_path = Filename.fromOsSpecific(video_path)
                converted_path = str(panda_path)
                
                movie_texture = MovieTexture(name)
                success = movie_texture.read(converted_path)
                
                if success:
                    video_screen.setTexture(movie_texture)
                    
                    # 添加视频对象到管理器
                    video_obj = {
                        'node': video_screen,
                        'texture': movie_texture,
                        'path': converted_path,
                        'name': name,
                        'type': 'movie',
                        'is_playing': False
                    }
                    
                    # 播放视频
                    movie_texture.play()
                    video_obj['is_playing'] = True
                    
                    self.video_objects.append(video_obj)
                    
                    # 添加到模型列表和场景树
                    self.world.models.append(video_screen)
                    self.world.updateSceneTree()
                    
                    print(f"✓ 视频屏幕创建成功: {name}")
                    return video_screen
                else:
                    print(f"✗ 无法加载视频: {converted_path}")
                    # 创建占位符纹理
                    self._create_placeholder_texture(video_screen, name)
            else:
                # 创建程序化动画纹理作为演示
                self._create_animated_texture(video_screen, name)
                
            return video_screen
            
        except Exception as e:
            print(f"创建视频屏幕失败: {str(e)}")
            return None
    
    def create_video_billboard(self, pos=(0, 0, 0), size=(2, 1.5), video_path=None, name="video_billboard"):
        """创建面向相机的视频广告牌"""
        try:
            video_screen = self.create_video_screen(pos, size, video_path, name)
            if video_screen:
                # 设置为广告牌模式（总是面向相机）
                video_screen.setBillboardAxis()
                print(f"✓ 视频广告牌创建成功: {name}")
            return video_screen
        except Exception as e:
            print(f"创建视频广告牌失败: {str(e)}")
            return None
    
    def create_spherical_video(self, pos=(0, 0, 0), radius=10, video_path=None, name="spherical_video"):
        """创建球形全景视频"""
        try:
            # 创建球体几何（使用多个面片模拟）
            sphere = self._create_sphere_geometry(radius)
            sphere.reparentTo(self.world.render)
            sphere.setPos(*pos)
            sphere.setName(name)
            
            # 反转法线以便从内部观看
            sphere.setTwoSided(True)
            sphere.setScale(-1, 1, 1)  # 反转X轴以正确显示内部
            
            # 创建视频纹理
            if video_path and os.path.exists(video_path):
                # Convert Windows path to Panda3D compatible path format
                from panda3d.core import Filename
                panda_path = Filename.fromOsSpecific(video_path)
                converted_path = str(panda_path)
                
                movie_texture = MovieTexture(name)
                success = movie_texture.read(converted_path)
                
                if success:
                    sphere.setTexture(movie_texture)
                    movie_texture.play()
                    
                    video_obj = {
                        'node': sphere,
                        'texture': movie_texture,
                        'path': converted_path,
                        'name': name,
                        'type': 'spherical',
                        'is_playing': True
                    }
                    
                    self.video_objects.append(video_obj)
            else:
                # 创建程序化全景纹理
                self._create_panoramic_texture(sphere, name)
            
            # 添加到模型列表
            self.world.models.append(sphere)
            self.world.updateSceneTree()
            
            print(f"✓ 球形全景视频创建成功: {name}")
            return sphere
            
        except Exception as e:
            print(f"创建球形全景视频失败: {str(e)}")
            return None
    
    def _create_sphere_geometry(self, radius):
        """创建球体几何"""
        # 简化版本：创建立方体作为球体替代
        cm = CardMaker("sphere_face")
        cm.setFrame(-radius, radius, -radius, radius)
        
        sphere_root = self.world.render.attachNewNode("sphere")
        
        # 创建6个面（立方体的6个面）
        faces = [
            (Vec3(0, radius, 0), Vec3(0, 0, 0)),      # 前面
            (Vec3(0, -radius, 0), Vec3(0, 180, 0)),   # 后面
            (Vec3(radius, 0, 0), Vec3(0, 90, 0)),     # 右面
            (Vec3(-radius, 0, 0), Vec3(0, -90, 0)),   # 左面
            (Vec3(0, 0, radius), Vec3(-90, 0, 0)),    # 上面
            (Vec3(0, 0, -radius), Vec3(90, 0, 0)),    # 下面
        ]
        
        for i, (pos, hpr) in enumerate(faces):
            face = sphere_root.attachNewNode(cm.generate())
            face.setPos(pos)
            face.setHpr(hpr)
        
        return sphere_root
    
    def _create_placeholder_texture(self, node, name):
        """创建占位符纹理"""
        # 创建简单的渐变纹理
        texture = Texture()
        texture.setup2dTexture(256, 256, Texture.TUnsignedByte, Texture.FRgba)
        
        img = PNMImage(256, 256, 4)
        for y in range(256):
            for x in range(256):
                # 创建棋盘格图案
                if (x // 32 + y // 32) % 2:
                    img.setXel(x, y, 0.8, 0.8, 0.8)
                else:
                    img.setXel(x, y, 0.3, 0.3, 0.3)
                img.setAlpha(x, y, 1.0)
        
        texture.load(img)
        node.setTexture(texture)
        
        # 添加到视频对象列表
        video_obj = {
            'node': node,
            'texture': texture,
            'path': None,
            'name': name,
            'type': 'placeholder',
            'is_playing': False
        }
        self.video_objects.append(video_obj)
    
    def _create_animated_texture(self, node, name):
        """创建动画纹理"""
        texture = Texture()
        texture.setup2dTexture(256, 256, Texture.TUnsignedByte, Texture.FRgba)
        
        node.setTexture(texture)
        
        # 启动动画更新任务 - 修复参数传递顺序
        task_name = f"animate_texture_{name}"
        self.world.taskMgr.add(lambda task: self._update_animated_texture(task, texture, name), task_name)
        
        # 添加到视频对象列表
        video_obj = {
            'node': node,
            'texture': texture,
            'path': None,
            'name': name,
            'type': 'animated',
            'is_playing': True,
            'task_name': task_name
        }
        self.video_objects.append(video_obj)
    
    def _create_panoramic_texture(self, node, name):
        """创建全景动画纹理"""
        texture = Texture()
        texture.setup2dTexture(512, 256, Texture.TUnsignedByte, Texture.FRgba)
        
        node.setTexture(texture)
        
        # 启动全景动画更新任务 - 修复参数传递顺序
        task_name = f"animate_panoramic_{name}"
        self.world.taskMgr.add(lambda task: self._update_panoramic_texture(task, texture, name), task_name)
        
        # 添加到视频对象列表
        video_obj = {
            'node': node,
            'texture': texture,
            'path': None,
            'name': name,
            'type': 'panoramic',
            'is_playing': True,
            'task_name': task_name
        }
        self.video_objects.append(video_obj)
    
    def _update_animated_texture(self, task, texture, name):
        """更新动画纹理"""
        try:
            time = task.time
            img = PNMImage(256, 256, 4)
            
            for y in range(256):
                for x in range(256):
                    # 创建波纹效果
                    dist_x = (x - 128) / 128.0
                    dist_y = (y - 128) / 128.0
                    distance = math.sqrt(dist_x**2 + dist_y**2)
                    
                    wave = math.sin(distance * 8 - time * 3)
                    r = (wave + 1) * 0.5
                    g = (math.sin(dist_x * 4 + time * 2) + 1) * 0.5
                    b = (math.sin(dist_y * 4 + time * 2.5) + 1) * 0.5
                    
                    img.setXel(x, y, r, g, b)
                    img.setAlpha(x, y, 1.0)
            
            texture.load(img)
            return task.cont
            
        except Exception as e:
            print(f"更新动画纹理失败: {str(e)}")
            return task.done
    
    def _update_panoramic_texture(self, task, texture, name):
        """更新全景动画纹理"""
        try:
            time = task.time
            img = PNMImage(512, 256, 4)
            
            for y in range(256):
                for x in range(512):
                    # 创建全景旋转效果
                    u = x / 512.0  # 经度 (0-1)
                    v = y / 256.0  # 纬度 (0-1)
                    
                    angle = u * 2 * math.pi + time * 0.5
                    height = (v - 0.5) * math.pi
                    
                    r = (math.sin(angle * 3) + 1) * 0.5
                    g = (math.cos(angle * 2 + height * 4) + 1) * 0.5
                    b = (math.sin(height * 6 + time) + 1) * 0.5
                    
                    img.setXel(x, y, r, g, b)
                    img.setAlpha(x, y, 1.0)
            
            texture.load(img)
            return task.cont
            
        except Exception as e:
            print(f"更新全景纹理失败: {str(e)}")
            return task.done
    
    def play_video(self, video_name):
        """播放指定视频"""
        for video_obj in self.video_objects:
            if video_obj['name'] == video_name:
                if video_obj['type'] == 'movie' and hasattr(video_obj['texture'], 'play'):
                    video_obj['texture'].play()
                    video_obj['is_playing'] = True
                    print(f"播放视频: {video_name}")
                elif video_obj['type'] in ['animated', 'panoramic']:
                    # 重新启动动画任务
                    if 'task_name' in video_obj:
                        task_name = video_obj['task_name']
                        if video_obj['type'] == 'animated':
                            self.world.taskMgr.add(
                                lambda task: self._update_animated_texture(task, video_obj['texture'], video_name), 
                                task_name
                            )
                        else:
                            self.world.taskMgr.add(
                                lambda task: self._update_panoramic_texture(task, video_obj['texture'], video_name), 
                                task_name
                            )
                        video_obj['is_playing'] = True
                        print(f"恢复动画: {video_name}")
                break
    
    def pause_video(self, video_name):
        """暂停指定视频"""
        for video_obj in self.video_objects:
            if video_obj['name'] == video_name:
                if video_obj['type'] == 'movie' and hasattr(video_obj['texture'], 'stop'):
                    video_obj['texture'].stop()
                    video_obj['is_playing'] = False
                    print(f"暂停视频: {video_name}")
                elif video_obj['type'] in ['animated', 'panoramic']:
                    # 停止动画任务
                    if 'task_name' in video_obj:
                        self.world.taskMgr.remove(video_obj['task_name'])
                        video_obj['is_playing'] = False
                        print(f"暂停动画: {video_name}")
                break
    
    def stop_video(self, video_name):
        """停止指定视频"""
        for video_obj in self.video_objects:
            if video_obj['name'] == video_name:
                if video_obj['type'] == 'movie':
                    if hasattr(video_obj['texture'], 'stop'):
                        video_obj['texture'].stop()
                    if hasattr(video_obj['texture'], 'setTime'):
                        video_obj['texture'].setTime(0)
                    video_obj['is_playing'] = False
                    print(f"停止视频: {video_name}")
                elif video_obj['type'] in ['animated', 'panoramic']:
                    # 停止动画任务
                    if 'task_name' in video_obj:
                        self.world.taskMgr.remove(video_obj['task_name'])
                        video_obj['is_playing'] = False
                        print(f"停止动画: {video_name}")
                break
    
    def set_video_speed(self, video_name, speed):
        """设置视频播放速度"""
        for video_obj in self.video_objects:
            if video_obj['name'] == video_name:
                if video_obj['type'] == 'movie' and hasattr(video_obj['texture'], 'setPlayRate'):
                    video_obj['texture'].setPlayRate(speed)
                    print(f"设置视频 {video_name} 播放速度: {speed}x")
                break
    
    def remove_video(self, video_name):
        """移除指定视频"""
        for i, video_obj in enumerate(self.video_objects):
            if video_obj['name'] == video_name:
                # 停止播放
                self.stop_video(video_name)
                
                # 从场景中移除节点
                if video_obj['node'] in self.world.models:
                    self.world.models.remove(video_obj['node'])
                video_obj['node'].removeNode()
                
                # 从列表中移除
                self.video_objects.pop(i)
                
                # 更新场景树
                self.world.updateSceneTree()
                
                print(f"移除视频: {video_name}")
                break
    
    def get_video_info(self, video_name):
        """获取视频信息"""
        for video_obj in self.video_objects:
            if video_obj['name'] == video_name:
                info = {
                    'name': video_obj['name'],
                    'type': video_obj['type'],
                    'is_playing': video_obj['is_playing'],
                    'path': video_obj.get('path', 'N/A')
                }
                
                if video_obj['type'] == 'movie' and hasattr(video_obj['texture'], 'getVideoLength'):
                    info['length'] = video_obj['texture'].getVideoLength()
                    info['current_time'] = video_obj['texture'].getTime()
                    info['play_rate'] = video_obj['texture'].getPlayRate()
                
                return info
        return None
    
    def list_videos(self):
        """列出所有视频"""
        videos = []
        for video_obj in self.video_objects:
            videos.append({
                'name': video_obj['name'],
                'type': video_obj['type'],
                'is_playing': video_obj['is_playing']
            })
        return videos
    
    def is_video_file(self, filepath):
        """检查文件是否是支持的视频格式"""
        if not filepath:
            return False
        
        ext = os.path.splitext(filepath)[1].lower()
        return ext in self.supported_formats

# 使用示例（集成到现有的 MyWorld 类中）:
"""
# 在 MyWorld 类的 __init__ 方法中添加：
self.video_manager = VideoManager(self)

# 在文件拖放处理中添加视频支持：
def dropEvent(self, event):
    if event.mimeData().hasUrls():
        for url in event.mimeData().urls():
            filepath = url.toLocalFile()
            if self.world.video_manager.is_video_file(filepath):
                # 创建视频屏幕
                self.world.video_manager.create_video_screen(
                    pos=(0, 0, 2), 
                    video_path=filepath, 
                    name=f"video_{len(self.world.video_manager.video_objects)}"
                )
            elif filepath.lower().endswith(('.egg', '.bam', '.obj', '.fbx')):
                self.world.importModel(filepath)
""" 