using System;
using System.Collections.Generic;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Media3D;
using Ounibo.Catalog.Viewer3D;

namespace Ounibo.Catalog.App
{
    /// <summary>
    /// 3D 预览控件: Viewport3D + 鼠标左键拖拽旋转 + 滚轮缩放。
    /// </summary>
    public class ViewerControl : UserControl
    {
        Viewport3D _vp;
        PerspectiveCamera _cam;
        Model3DGroup _root;
        Point _last;
        double _theta = 0.6, _phi = 0.9, _dist = 300;
        bool _dragging;

        public ViewerControl()
        {
            _root = new Model3DGroup();
            _root.Children.Add(new DirectionalLight(Colors.White, new Vector3D(-1, -1, -2)));
            _root.Children.Add(new DirectionalLight(Colors.White, new Vector3D(1, 0.5, 1)));

            _cam = new PerspectiveCamera
            {
                Position = new Point3D(0, 0, 300),
                LookDirection = new Vector3D(0, 0, -1),
                UpDirection = new Vector3D(0, 1, 0),
                FieldOfView = 45
            };
            _vp = new Viewport3D { Camera = _cam };
            _vp.Children.Add(new ModelVisual3D { Content = _root });
            Content = new Border { Background = Brushes.White, Child = _vp };

            _vp.MouseLeftButtonDown += (s, e) => { _dragging = true; _last = e.GetPosition(_vp); _vp.CaptureMouse(); };
            _vp.MouseMove += (s, e) =>
            {
                if (!_dragging) return;
                var p = e.GetPosition(_vp);
                var dx = p.X - _last.X;
                var dy = p.Y - _last.Y;
                _last = p;
                _theta -= dx * 0.01;
                _phi = Math.Max(-1.45, Math.Min(1.45, _phi + dy * 0.01));
                UpdateCamera();
            };
            _vp.MouseLeftButtonUp += (s, e) => { _dragging = false; _vp.ReleaseMouseCapture(); };
            _vp.MouseWheel += (s, e) =>
            {
                _dist *= (e.Delta > 0) ? 0.88 : 1.13;
                _dist = Math.Max(20, Math.Min(4000, _dist));
                UpdateCamera();
            };
        }

        public void Clear()
        {
            var lights = new List<Light>();
            foreach (var m in _root.Children)
                if (m is Light) lights.Add((Light)m);
            _root.Children.Clear();
            foreach (var l in lights) _root.Children.Add(l);
        }

        /// <summary>加载圆柱列表并自动取景。</summary>
        public void Load(List<Cyl> cyls)
        {
            Clear();
            if (cyls == null || cyls.Count == 0) return;

            // 颜色: 0 后盖 / 1 缸体 / 2 前盖 / 3 活塞杆
            var brushes = new[]
            {
                new SolidColorBrush(Color.FromRgb(0x8C, 0x8C, 0x8C)),
                new SolidColorBrush(Color.FromRgb(0x2F, 0x6F, 0xB3)),
                new SolidColorBrush(Color.FromRgb(0x8C, 0x8C, 0x8C)),
                new SolidColorBrush(Color.FromRgb(0xC8, 0xC8, 0xC8))
            };
            for (int i = 0; i < cyls.Count; i++)
            {
                var mesh = StepMesh.BuildMesh(cyls[i]);
                var mat = new DiffuseMaterial(brushes[i % brushes.Length]);
                _root.Children.Add(new GeometryModel3D(mesh, mat) { BackMaterial = mat });
            }

            double cx, cy, cz, r, h;
            StepMesh.Bounds(cyls, out cx, out cy, out cz, out r, out h);
            _dist = Math.Max(120, Math.Max(r * 5.0, h * 1.6));
            _theta = 0.55; _phi = 0.85;
            UpdateCamera();
        }

        void UpdateCamera()
        {
            double x = _dist * Math.Sin(_theta) * Math.Cos(_phi);
            double y = _dist * Math.Sin(_phi);
            double z = _dist * Math.Cos(_theta) * Math.Cos(_phi);
            _cam.Position = new Point3D(x, y, z);
            _cam.LookDirection = new Vector3D(-x, -y, -z);
        }
    }
}
