using Arction.Wpf.ChartingMVVM.Axes;
using Arction.Wpf.ChartingMVVM;
using Arction.Wpf.ChartingMVVM.Series3D;
using Arction.Wpf.ChartingMVVM.Views.View3D;
using Prism.Events;
using Prism.Mvvm;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Color = System.Windows.Media.Color;
using Colors = System.Windows.Media.Colors;
using Txgy.EWS.Client.Common.MessageEvents;
using Txgy.EWS.Client.Common;
using Txgy.EWS.Client.PageModule.Models;
using Txgy.Microseismic.BaseLib.Models;
using Arction.Wpf.ChartingMVVM.Titles;
using System.Windows;

namespace Txgy.EWS.Client.PageModule.ViewModels
{
    public class StereogramViewModel : BindableBase
    {
        private IEventAggregator _ea;
        public Color eventLayerColor = Colors.Red;
        public Color eventColor = Colors.Red;
        public Color eventTextColor = Colors.Blue;
        public double eventLayerLineWeight = 1;
        public double eventSize = 10;
        public double eventTextSize = 12;
        

        private ChartTitle _chartTitle;

        public ChartTitle ChartTitle
        {
            get { return _chartTitle; }
            set
            {
                SetProperty(ref _chartTitle, value);
            }
        }
        private double _scale = 1;

        public double Scale
        {
            get { return _scale; }
            set
            {
                SetProperty(ref _scale, value);
            }
        }

        #region ***LightningChart属性***
        public SizeDoubleXYZ EventSize;
        private int _widthRS = 100;
        public int WidthRS
        {
            get { return _widthRS; }
            set
            {
                SetProperty(ref _widthRS, value);
            }
        }
        private int _heightRS = 50;
        public int HeightRS
        {
            get { return _heightRS; }
            set
            {
                SetProperty(ref _heightRS, value);
            }
        }
        private int _depthRS = 100;
        public int DepthRS
        {
            get { return _depthRS; }
            set
            {
                SetProperty(ref _depthRS, value);
            }
        }
        private double _sideRotationRS = 0;
        public double SideRotationRS
        {
            get { return _sideRotationRS; }
            set
            {
                SetProperty(ref _sideRotationRS, value);
            }
        }
        private double _horizontalRotationRS = -30;
        public double HorizontalRotationRS
        {
            get { return _horizontalRotationRS; }
            set
            {
                SetProperty(ref _horizontalRotationRS, value);
            }
        }
        private double _verticalRotationRS = 30;
        public double VerticalRotationRS
        {
            get { return _verticalRotationRS; }
            set
            {
                //Console.WriteLine(value.ToString());
                SetProperty(ref _verticalRotationRS, value);

            }
        }
        private double _distanceRS = 200;
        public double DistanceRS
        {
            get { return _distanceRS; }
            set
            {
                //Console.WriteLine(value.ToString());
                SetProperty(ref _distanceRS, value);

            }
        }
        private bool _clipDispaly = false;
        public bool ClipDispaly
        {
            get { return _clipDispaly; }
            set
            {
                SetProperty(ref _clipDispaly, value);
            }
        }
        private WallXZ _bottomWall;
        public WallXZ BottomWall
        {
            get { return _bottomWall; }
            set
            {
                SetProperty(ref _bottomWall, value);
            }
        }
        private WallXZ _topWall;
        public WallXZ TopWall
        {
            get { return _topWall; }
            set
            {
                SetProperty(ref _topWall, value);
            }
        }
        private WallYZ _leftWall;
        public WallYZ LeftWall
        {
            get { return _leftWall; }
            set
            {
                SetProperty(ref _leftWall, value);
            }
        }
        private WallYZ _rightWall;
        public WallYZ RightWall
        {
            get { return _rightWall; }
            set
            {
                SetProperty(ref _rightWall, value);
            }
        }
        private WallXY _frontWall;
        public WallXY FrontWall
        {
            get { return _frontWall; }
            set
            {
                SetProperty(ref _frontWall, value);
            }
        }
        private WallXY _backWall;
        public WallXY BackWall
        {
            get { return _backWall; }
            set
            {
                SetProperty(ref _backWall, value);
            }
        }
        private AxisX3D _axisXPri3D;
        public AxisX3D AxisXPri3D
        {
            get { return _axisXPri3D; }
            set
            {
                SetProperty(ref _axisXPri3D, value);
            }
        }
        private AxisY3D _axisYPri3D;
        public AxisY3D AxisYPri3D
        {
            get { return _axisYPri3D; }
            set
            {
                SetProperty(ref _axisYPri3D, value);
            }
        }
        private AxisZ3D _axisZPri3D;
        public AxisZ3D AxisZPri3D
        {
            get { return _axisZPri3D; }
            set
            {
                SetProperty(ref _axisZPri3D, value);
            }
        }
        private ProjectionType _projectionTypeRS = ProjectionType.Perspective;
        public ProjectionType ProjectionTypeRS
        {
            get { return _projectionTypeRS; }
            set
            {
                SetProperty(ref _projectionTypeRS, value);
            }
        }
        private Fill _chartBackGround = new Fill();


        public Fill ChartBackGround
        {
            get { return _chartBackGround; }
            set
            {
                SetProperty(ref _chartBackGround, value);
            }
        }
        public List<PointLineSeries3D> eventList;
        public Light3DCollection Lights { get; set; }
        public PointLineSeries3DCollection ChartPointLineCollection { get; set; }
        public Annotation3DCollection ChartAnnotationCollection { get; set; }
        public Rectangle3DCollection ChartDepthLayerCollection { get; set; }
        #endregion

        public StereogramViewModel(IEventAggregator ea)
        {
            _ea = ea;
            _chartBackGround.GradientFill = GradientFill.Solid;
            _chartBackGround.GradientColor = Colors.White;

            _chartTitle = new ChartTitle();
            _chartTitle.Visible = false;
            _chartTitle.Text = "三维视图";

            _bottomWall = new WallXZ();
            _bottomWall.Material = new Material3D() { DiffuseColor = Color.FromArgb(0, 248, 248, 255) };
            _bottomWall.SetGridStripColor1(Color.FromArgb(0, 248, 248, 255));
            _bottomWall.SetGridStripColor2(Color.FromArgb(0, 248, 248, 255));
            _topWall = new WallXZ();
            _topWall.Material = new Material3D() { DiffuseColor = Color.FromArgb(0, 248, 248, 255) };
            _topWall.SetGridStripColor1(Color.FromArgb(0, 248, 248, 255));
            _topWall.SetGridStripColor2(Color.FromArgb(0, 248, 248, 255));
            _leftWall = new WallYZ();
            _leftWall.Material = new Material3D() { DiffuseColor = Color.FromArgb(0, 248, 248, 255) };
            _leftWall.SetGridStripColor1(Color.FromArgb(0, 248, 248, 255));
            _leftWall.SetGridStripColor2(Color.FromArgb(0, 248, 248, 255));
            _rightWall = new WallYZ();
            _rightWall.Material = new Material3D() { DiffuseColor = Color.FromArgb(0, 248, 248, 255) };
            _rightWall.SetGridStripColor1(Color.FromArgb(0, 248, 248, 255));
            _rightWall.SetGridStripColor2(Color.FromArgb(0, 248, 248, 255));
            _frontWall = new WallXY();
            _frontWall.Material = new Material3D() { DiffuseColor = Color.FromArgb(0, 248, 248, 255) };
            _frontWall.SetGridStripColor1(Color.FromArgb(0, 248, 248, 255));
            _frontWall.SetGridStripColor2(Color.FromArgb(0, 248, 248, 255));
            _backWall = new WallXY();
            _backWall.Material = new Material3D() { DiffuseColor = Color.FromArgb(0, 248, 248, 255) };
            _backWall.SetGridStripColor1(Color.FromArgb(0, 248, 248, 255));
            _backWall.SetGridStripColor2(Color.FromArgb(0, 248, 248, 255));
            Lights = View3D.CreateDefaultLights();

            //WidthRS = (int)((GlobalConfig.ProjectConfig.WorkArea.EMax - GlobalConfig.ProjectConfig.WorkArea.EMin) / Scale);
            //HeightRS = (int)((GlobalConfig.ProjectConfig.WorkArea.ZMax - GlobalConfig.ProjectConfig.WorkArea.ZMin) / Scale);
            //DepthRS = (int)((GlobalConfig.ProjectConfig.WorkArea.NMax - GlobalConfig.ProjectConfig.WorkArea.NMin) / Scale);


            AxisXPri3D = new AxisX3D();
            //AxisXPri3D.Minimum = (GlobalConfig.ProjectConfig.WorkArea.EMin - GlobalConfig.BaseX) / Scale;
            //AxisXPri3D.Maximum = (GlobalConfig.ProjectConfig.WorkArea.EMax - GlobalConfig.BaseX) / Scale;
            //AxisXPri3D.MajorDiv = 0.5;
            AxisXPri3D.Maximum = GlobalConfig.ProjectConfig.WorkArea.EMax / Scale;
            AxisXPri3D.Minimum = GlobalConfig.ProjectConfig.WorkArea.EMin / Scale;
            AxisXPri3D.Title.Text = "西东";
            AxisXPri3D.LabelsVisible = true;
            AxisXPri3D.LabelsColor = Colors.Black;
            AxisXPri3D.Orientation = PlaneXAxis3D.XZ;
            AxisXPri3D.Location = AxisXLocation3D.BottomFront;
            AxisXPri3D.LabelsNumberFormat = "00000000";
            AxisXPri3D.AutoFormatLabels = false;

            AxisYPri3D = new AxisY3D();
            AxisYPri3D.Title.Text = "海拔";
            AxisYPri3D.Minimum = (GlobalConfig.ProjectConfig.WorkArea.ZMin / Scale);
            AxisYPri3D.Maximum = ((GlobalConfig.ProjectConfig.WorkArea.ZMax + 50) / Scale);
            AxisYPri3D.Reversed = true;
            AxisYPri3D.LabelsColor = Colors.Black;
            //AxisYPri3D.Visible = false;

            AxisZPri3D = new AxisZ3D();
            //AxisZPri3D.Minimum = (GlobalConfig.ProjectConfig.WorkArea.NMin - GlobalConfig.BaseY) / Scale;
            //AxisZPri3D.Maximum = (GlobalConfig.ProjectConfig.WorkArea.NMax - GlobalConfig.BaseY) / Scale;
            //AxisZPri3D.MajorDiv = 0.5;
            AxisZPri3D.Maximum = GlobalConfig.ProjectConfig.WorkArea.NMax / Scale;
            AxisZPri3D.Minimum = GlobalConfig.ProjectConfig.WorkArea.NMin / Scale;
            AxisZPri3D.Title.Text = "南北";
            AxisZPri3D.Orientation = PlaneZAxis3D.XZ;
            AxisZPri3D.Location = AxisZLocation3D.BottomRight;
            AxisZPri3D.LabelsColor = Colors.Black;
            AxisZPri3D.LabelsNumberFormat = "0000000";
            AxisZPri3D.AutoFormatLabels = false;

            //Polygons = _lcModel.CreatePolygons();
            ChartPointLineCollection = new PointLineSeries3DCollection();
            ChartAnnotationCollection = new Annotation3DCollection();
            //CreateBackgroudByDwg();

            EventSize = new SizeDoubleXYZ(GlobalConfig.eventDSize, GlobalConfig.eventDSize, GlobalConfig.eventDSize);

            //_ea = ea;
            //this._ea.GetEvent<UpdateEventsMessage>().Subscribe(u =>
            //{
            //    CreateEventList();
            //});
            //CreateEventList();
            //ChartDepthLayerCollection = new Rectangle3DCollection();
            //ChartDepthLayerCollection.Add(GetRectangle(-300/Scale));
        }
        public void CreateEventList()
        {
            if (!GlobalData.AppendEvent)
            {
                List<PointLineSeries3D> newCollection = ChartPointLineCollection.ToList();
                //Console.WriteLine(newCollection.Count);
                newCollection.RemoveAll(x => x.Title.Text.Contains("微地震事件"));
                //Console.WriteLine(newCollection.Count);
                ChartPointLineCollection.Clear();
                ChartPointLineCollection.AddRange(newCollection);

                ChartPointLineCollection.ToList().RemoveAll(x => x.Title.Text.Contains("微地震事件"));
            }
            if (GlobalData.SearchEvents.Count > 0)
            {
                eventList = new List<PointLineSeries3D>();
                PointLineSeries3D pls3d = new PointLineSeries3D();
                pls3d.Title.Text = "微地震事件";
                pls3d.Tag = "mm-event";
                pls3d.IndividualPointColors = true;
                pls3d.IndividualPointSizes = true;
                pls3d.LineVisible = false;
                pls3d.AllowUserInteraction = true;
                pls3d.PointsVisible = true;
                pls3d.PointStyle.Shape3D = PointShape3D.Sphere;
                pls3d.PointStyle.Size3D = EventSize;
                List<SeriesPoint3D> sp3List = new List<SeriesPoint3D>();
                //SeriesPoint3D[] sp3s = new SeriesPoint3D[GlobalData.EventResults.Count];
                foreach (var item in GlobalData.SearchEvents)
                {
                    float sizeFactor = (float)(((4f + item.ML) / (4f)) * 2f) + 0.1f;
                    //int colorIndex = (int)((item.Z - GlobalConfig.ProjectConfig.WorkArea.ZMin) / 100);
                    int colorIndex = (int)(((item.Z - GlobalConfig.ProjectConfig.WorkArea.ZMin)
                            / Math.Abs(GlobalConfig.ProjectConfig.WorkArea.ZMax - GlobalConfig.ProjectConfig.WorkArea.ZMin))
                            * GlobalConfig.ColorCountDefault);
                    Color ec = GlobalConfig.eventDepthColor[colorIndex];
                    sp3List.Add(new SeriesPoint3D((item.Y - GlobalConfig.BaseX) / Scale, (GlobalConfig.BaseZ - item.Z)/Scale, (item.X - GlobalConfig.BaseY) / Scale, ec, sizeFactor));
                }
                pls3d.AddPoints(sp3List.ToArray(), true);
                ChartPointLineCollection.Add(pls3d);
                //Application.Current.Dispatcher.BeginInvoke(new Action(() =>
                //    {
                //        ChartPointLineCollection.Add(pls3d);
                //    }));
                //ChartPointLineCollection.Add(pls3d);
                //ChartPointLineCollection.Add(new PointLineSeries3D());
                //if (ChartPointLineCollection.IsFrozen)
                //{
                //    Application.Current.Dispatcher.BeginInvoke(new Action(() =>
                //    {
                //        ChartPointLineCollection.Add(pls3d);
                //    }));
                //}
                //if (ChartPointLineCollection.CanFreeze)
                //{
                //    ChartPointLineCollection.Freeze();

                //}

                //UpdateEvents(false);
            }

        }
        public Rectangle3D GetRectangle(double depth)
        {
            //Rotated clipped plane 
            Rectangle3D r2 = new Rectangle3D();
            r2.Center.SetValues(1, depth, 1);
            r2.Size.Width = 50; //Set large enough, to reach over the walls 
            r2.Size.Height = 50;
            r2.Fill.UseImage = false;
            r2.Fill.Material.DiffuseColor = Color.FromArgb(150, 50, 50, 50);
            r2.Rotation.SetValues(0, 0, 0);
            r2.Highlight = Highlight.Simple;
            return r2;
        }
        public static PointLineSeries3D CreateDxfLwPolyline(string tag, string title, bool allowUser, int lineStyle, double lineWidth, SeriesPoint3D[] points, bool closeLine)
        {
            PointLineSeries3D pls3d = new PointLineSeries3D();
            pls3d.Tag = tag;
            pls3d.Title.Text = title;
            pls3d.MultiColorLine = true;
            pls3d.AllowUserInteraction = allowUser;
            pls3d.PointsVisible = false;
            pls3d.LineStyle.LineOptimization = (LineOptimization)lineStyle;
            pls3d.LineStyle.Width = lineWidth;
            pls3d.Points = points;
            pls3d.ClosedLine = closeLine;
            return pls3d;
        }
        public PointLineSeries3D EventModel2Pls3d(MmEvent mm)
        {
            PointLineSeries3D pls3d = new PointLineSeries3D();
            pls3d.Title.Text = mm.EventTimeStr;
            pls3d.Tag = "mm-event";
            pls3d.IndividualPointColors = true;
            pls3d.IndividualPointSizes = true;
            pls3d.LineVisible = false;
            pls3d.AllowUserInteraction = true;
            pls3d.PointsVisible = true;
            pls3d.PointStyle.Shape3D = PointShape3D.Sphere;
            pls3d.PointStyle.Size3D = EventSize;
            return pls3d;
        }
    }
}
