using Earthblend.DynamicCompile;
using Earthblend.Nts.Common;
using Earthblend.Tts.Common.Core.Extentions;
using Earthblend.Tts.Common.Core.Interfaces;
using Earthblend.Tts.Common.Core.Members;
using Earthblend.Tts.Common.Core.Services;
using Earthblend.Tts.Common.Core.Statics;
using HelixToolkit.Wpf;
using System;
using System.Collections.ObjectModel;
using System.IO;
using System.Linq;
using System.Runtime.InteropServices;
using System.Threading;
using System.Windows;
using System.Windows.Input;
using System.Windows.Media.Animation;
using System.Windows.Media.Media3D;
using System.Windows.Threading;
using System.Xml.Serialization;
using VirtualCanvasTestCode.Extensions;
using VirtualCanvasTestCode.Services;

namespace VirtualCanvasTestCode.Models
{
    public static class Taskbar
    {
        [DllImport("user32.dll", SetLastError = true, CharSet = CharSet.Auto)]
        private static extern IntPtr FindWindow(
            string lpClassName,
            string lpWindowName);

        [DllImport("user32.dll", SetLastError = true)]
        private static extern int SetWindowPos(
            IntPtr hWnd,
            IntPtr hWndInsertAfter,
            int x,
            int y,
            int cx,
            int cy,
            uint uFlags
        );

        [Flags]
        private enum SetWindowPosFlags : uint
        {
            HideWindow = 128,
            ShowWindow = 64
        }

        public static void Show()
        {
            var window = FindWindow("Shell_traywnd", "");
            SetWindowPos(window, IntPtr.Zero, 0, 0, 0, 0, (uint)SetWindowPosFlags.ShowWindow);
        }

        public static void Hide()
        {
            var window = FindWindow("Shell_traywnd", "");
            SetWindowPos(window, IntPtr.Zero, 0, 0, 0, 0, (uint)SetWindowPosFlags.HideWindow);
        }
    }

    public class RangeViewModel : CustomBindableBase, ICommands
    {
        public event EventHandler<EventArgs> RenderRequest;

        protected virtual void OnRenderRequestChanged(EventArgs e)
        {
            EventHandler<EventArgs> handler = RenderRequest;
            if (handler != null)
            {
                handler(this, e);
            }
        }

        private ICommand _toggleFullScreenCommandIc; [XmlIgnore] public ICommand ToggleFullScreenCommandIc => _toggleFullScreenCommandIc ?? (_toggleFullScreenCommandIc = new Earthblend.DynamicCompile.RelayCommand<Object>(ToggleFullScreenCommandIcExecuted));
        private void ToggleFullScreenCommandIcExecuted(Object sender)
        {
            UIServices.Busy();
            FullScreen = !FullScreen;
            //if (FullScreen) Taskbar.Show(); else Taskbar.Hide();
        }

        private ICommand _exitCommandIc; [XmlIgnore] public ICommand ExitCommandIcCommandIc => _exitCommandIc ?? (_exitCommandIc = new Earthblend.DynamicCompile.RelayCommand<Object>(ExitCommandIcCommandIcExecuted));
        private void ExitCommandIcCommandIcExecuted(Object sender)
        {
            UIServices.Busy();
            Environment.Exit(0);
        }


        private ICommand _toggleRenderTextCommandIc; [XmlIgnore] public ICommand ToggleRenderTextCommandIc => _toggleRenderTextCommandIc ?? (_toggleRenderTextCommandIc = new Earthblend.DynamicCompile.RelayCommand<Object>(ToggleRenderTextCommandIcExecuted));
        private void ToggleRenderTextCommandIcExecuted(Object sender)
        {
            UIServices.Busy();
            dc.RenderText = !dc.RenderText;
            OnRenderRequestChanged(new EventArgs());
        }

        private Boolean _fullScreen = false;
        [XmlIgnore]
        public Boolean FullScreen
        {
            get { return _fullScreen; }
            set { SetProperty(ref _fullScreen, value); }
        }


        [XmlIgnore] public HelixViewport3D Vp { get; set; }
        [XmlIgnore] public HelixViewport3D Vp2 { get; set; }

        private ObservableCollection<RibbonItem> _ribbonItems = new ObservableCollection<RibbonItem>();
        [XmlIgnore] public ObservableCollection<RibbonItem> RibbonItems
        {
            get { return _ribbonItems; }
            set { SetProperty(ref _ribbonItems, value); }
        }

        private ICommand _nothingCommandIc; [XmlIgnore] public ICommand NothingCommandIc => _nothingCommandIc ?? (_nothingCommandIc = new Earthblend.DynamicCompile.RelayCommand<Object>(NothingCommandIcExecuted));
        private void NothingCommandIcExecuted(Object sender)
        {
            UIServices.Busy();

        }

        private ICommand _stopCommandIc; [XmlIgnore] public ICommand StopCommandIc => _stopCommandIc ?? (_stopCommandIc = new Earthblend.DynamicCompile.RelayCommand<Object>(StopCommandIcExecuted));
        private void StopCommandIcExecuted(Object sender)
        {
            UIServices.Busy();
            Stop = true;
        }

        private Boolean Stop { get; set; } = false;
        private EquationTester dc = null;
        public void Initialize(EquationTester dcValue)
        {
            dc = dcValue;
            LoadWorldDataItems(dcValue);
            LoadCanvasDataItems(dcValue);
            LoadTargetDataItems(dcValue);

            RibbonService ribbonService = new RibbonService(this as ICommands);
            RibbonItems.AddRange<RibbonItem>(ribbonService.CreateMainRibbon());
            //ribbonService = null;
            NotifyPropertyChanged("RibbonItems");
        }

        private void LoadWorldDataItems(EquationTester dc)
        {
            String path = VirtualSystemUtil.TestCodeStorageFolder + @"VirtualCanvasTestCode\VirtualCanvasTestCode\VirtualWorldDataItems.xml";

            //if(!File.Exists(path))
            //{
                FileInfo fileInfo = new FileInfo(System.Reflection.Assembly.GetExecutingAssembly().Location);
                var executingAssembly = fileInfo.DirectoryName + @"\Resources\Images\VirtualWorldDataItems.xml";
                fileInfo = null;

                if(File.Exists(executingAssembly))
                {
                    path = executingAssembly;
                }
            //}

            if (File.Exists(path))
            {
                StreamReader sr = new StreamReader(path);
                String xml = sr.ReadToEnd();
                sr.Close();
                sr.Dispose();
                sr = null;

                FileService fileService = new FileService();
                var dataItems = fileService.LoadFromXml<WorldItemsExport>(xml, XmlUtil.LoadSaveTypes);
                fileService = null;

                WorldItems = dataItems;
            }
        }

        private void LoadCanvasDataItems(EquationTester dc)
        {
            String path = VirtualSystemUtil.TestCodeStorageFolder + @"VirtualCanvasTestCode\VirtualCanvasTestCode\Slates.xml";

            //if (!File.Exists(path))
            //{
                FileInfo fileInfo = new FileInfo(System.Reflection.Assembly.GetExecutingAssembly().Location);
                var executingAssembly = fileInfo.DirectoryName + @"\Resources\Images\Slates.xml";
                fileInfo = null;

                if (File.Exists(executingAssembly))
                {
                    path = executingAssembly;
                }
            //}

            if (File.Exists(path))
            {
                StreamReader sr = new StreamReader(path);
                String xml = sr.ReadToEnd();
                sr.Close();
                sr.Dispose();
                sr = null;

                FileService fileService = new FileService();
                var dataItems = fileService.LoadFromXml<CanvasItemsExport>(xml, XmlUtil.LoadSaveTypes);
                fileService = null;

                CanvasItems = dataItems;
                dc.CanvasItems = dataItems;
            }
        }
        private void LoadTargetDataItems(EquationTester dc)
        {
            String path = VirtualSystemUtil.TestCodeStorageFolder + @"VirtualCanvasTestCode\VirtualCanvasTestCode\Targets.xml";

            //if (!File.Exists(path))
            //{
                FileInfo fileInfo = new FileInfo(System.Reflection.Assembly.GetExecutingAssembly().Location);
                var executingAssembly = fileInfo.DirectoryName + @"\Resources\Images\Targets.xml";
                fileInfo = null;

                if (File.Exists(executingAssembly))
                {
                    path = executingAssembly;
                }
            //}


            if (File.Exists(path))
            {

                StreamReader sr = new StreamReader(path);
                String xml = sr.ReadToEnd();
                sr.Close();
                sr.Dispose();
                sr = null;

                FileService fileService = new FileService();
                var dataItems = fileService.LoadFromXml<TargetItemsExport>(xml, XmlUtil.LoadSaveTypes);
                fileService = null;

                TargetItems = dataItems;

            }
        }
        private ICommand _runCommandIc; [XmlIgnore] public ICommand RunCommandIc => _runCommandIc ?? (_runCommandIc = new Earthblend.DynamicCompile.RelayCommand<Object>(RunCommandIcExecuted));
        private void RunCommandIcExecuted(Object sender)
        {
            MatchResults.Clear();
            EquationTester dc = (EquationTester)sender;
            Et = dc;
            dc.MathChange = true;
            dc.TextModel3DGroup.Children.Clear();
            UIServices.DoEvents();
            //for (Double w = WStart; w <= WEnd; w += WStep)
            //{
            //    dc.WSub1 = w; UIServices.DoEvents(); Thread.Sleep(1);

            //    for (Double h = HStart; h <= HEnd; h += HStep)
            //    {
            //        dc.HSub1 = h; UIServices.DoEvents(); Thread.Sleep(1);

            //        for (Double z = ZStart; z <= ZEnd; z += ZStep)
            //        {
            //            //dc.ZSub1 = z; UIServices.DoEvents(); Thread.Sleep(1);

            //            //if (dc.ASub4 >= StartRange && dc.ASub4 <= EndRange)
            //            //{
            //                //var equationTester = RenderGenerated3D(dc, dc.WSub1, dc.HSub1, dc.ZSub1);

            //                //MatchResult matchResult = new MatchResult() { W = dc.WSub1, H = dc.HSub1, D = dc.DSub1, Z = dc.ZSub1, CuFt = dc.ASub4 };
            //                //matchResult.Model = equationTester.MainModel3DGroup;
            //                //MatchResults.Add(matchResult);
            //            //}
            //            if (Stop == true) { Stop = false; return; }
            //            UIServices.DoEvents();
            //        }
            //    }
            //}

            RenderText(dc);
        }

        private ICommand _startSpinXCommandIc; [XmlIgnore] public ICommand StartSpinXCommandIc => _startSpinXCommandIc ?? (_startSpinXCommandIc = new Earthblend.DynamicCompile.RelayCommand<Object>(StartSpinXCommandIcExecuted));
        private void StartSpinXCommandIcExecuted(Object sender)  
        {
            UIServices.Busy();

            if (Vp == null || Vp2 == null) return;

            Storyboard s1 = (Storyboard)Vp.Resources["SpinModelX"];
            Storyboard s2 = (Storyboard)Vp.Resources["SpinTextX"];
            Storyboard s3 = (Storyboard)Vp2.Resources["SpinModelXPanel2"];
            Storyboard s4 = (Storyboard)Vp2.Resources["SpinTextXPanel2"];

            if (s1 != null) s1.Begin();
            if (s2 != null) s2.Begin();
            if (s3 != null) s3.Begin();
            if (s4 != null) s4.Begin();

            //var camera1 = Vp.Camera as PerspectiveCamera;
            //camera1.FieldOfView++;
        }

        private ICommand _startSpinYCommandIc; [XmlIgnore] public ICommand StartSpinYCommandIc => _startSpinYCommandIc ?? (_startSpinYCommandIc = new Earthblend.DynamicCompile.RelayCommand<Object>(StartSpinYCommandIcExecuted));
        private void StartSpinYCommandIcExecuted(Object sender) 
        { 
            UIServices.Busy();

            if (Vp == null || Vp2 == null) return;

            Storyboard s1 = (Storyboard)Vp.Resources["SpinModelY"];
            Storyboard s2 = (Storyboard)Vp.Resources["SpinTextY"];
            Storyboard s3 = (Storyboard)Vp2.Resources["SpinModelYPanel2"];
            Storyboard s4 = (Storyboard)Vp2.Resources["SpinTextYPanel2"];

            if (s1 != null) s1.Begin();
            if (s2 != null) s2.Begin();
            if (s3 != null) s3.Begin();
            if (s4 != null) s4.Begin();
        }

        private ICommand _startSpinZCommandIc; [XmlIgnore] public ICommand StartSpinZCommandIc => _startSpinZCommandIc ?? (_startSpinZCommandIc = new Earthblend.DynamicCompile.RelayCommand<Object>(StartSpinZCommandIcExecuted));
        private void StartSpinZCommandIcExecuted(Object sender) 
        { 
            UIServices.Busy();

            if (Vp == null || Vp2 == null) return;

            Storyboard s1 = (Storyboard)Vp.Resources["SpinModelZ"];
            Storyboard s2 = (Storyboard)Vp.Resources["SpinTextZ"];
            Storyboard s3 = (Storyboard)Vp2.Resources["SpinModelZPanel2"];
            Storyboard s4 = (Storyboard)Vp2.Resources["SpinTextZPanel2"];
            
            if (s1 != null) s1.Begin();
            if (s2 != null) s2.Begin();
            if (s3 != null) s3.Begin();
            if (s4 != null) s4.Begin();
        }

        private ICommand _StopSpinXCommandIc; [XmlIgnore] public ICommand StopSpinXCommandIc => _StopSpinXCommandIc ?? (_StopSpinXCommandIc = new Earthblend.DynamicCompile.RelayCommand<Object>(StopSpinXCommandIcExecuted));
        private void StopSpinXCommandIcExecuted(Object sender) 
        {
            UIServices.Busy();

            if (Vp == null || Vp2 == null) return;

            Storyboard s1 = (Storyboard)Vp.Resources["SpinModelX"];
            Storyboard s2 = (Storyboard)Vp.Resources["SpinTextX"];
            Storyboard s3 = (Storyboard)Vp2.Resources["SpinModelXPanel2"];
            Storyboard s4 = (Storyboard)Vp2.Resources["SpinTextXPanel2"];

            if (s1 != null) s1.Stop();
            if (s2 != null) s2.Stop();
            if (s3 != null) s3.Stop();
            if (s4 != null) s4.Stop();

            //var camera1 = Vp.Camera as PerspectiveCamera;
            //camera1.FieldOfView--;
        }

        private ICommand _StopSpinYCommandIc; [XmlIgnore] public ICommand StopSpinYCommandIc => _StopSpinYCommandIc ?? (_StopSpinYCommandIc = new Earthblend.DynamicCompile.RelayCommand<Object>(StopSpinYCommandIcExecuted));
        private void StopSpinYCommandIcExecuted(Object sender) 
        { 
            UIServices.Busy();

            if (Vp == null || Vp2 == null) return;

            Storyboard s1 = (Storyboard)Vp.Resources["SpinModelY"];
            Storyboard s2 = (Storyboard)Vp.Resources["SpinTextY"];
            Storyboard s3 = (Storyboard)Vp2.Resources["SpinModelYPanel2"];
            Storyboard s4 = (Storyboard)Vp2.Resources["SpinTextYPanel2"];

            if (s1 != null) s1.Stop();
            if (s2 != null) s2.Stop();
            if (s3 != null) s3.Stop();
            if (s4 != null) s4.Stop();
        }

        private ICommand _StopSpinZCommandIc; [XmlIgnore] public ICommand StopSpinZCommandIc => _StopSpinZCommandIc ?? (_StopSpinZCommandIc = new Earthblend.DynamicCompile.RelayCommand<Object>(StopSpinZCommandIcExecuted));
        private void StopSpinZCommandIcExecuted(Object sender) 
        { 
            UIServices.Busy();

            if (Vp == null || Vp2 == null) return;

            Storyboard s1 = (Storyboard)Vp.Resources["SpinModelZ"];
            Storyboard s2 = (Storyboard)Vp.Resources["SpinTextZ"];
            Storyboard s3 = (Storyboard)Vp2.Resources["SpinModelZPanel2"];
            Storyboard s4 = (Storyboard)Vp2.Resources["SpinTextZPanel2"];

            if (s1 != null) s1.Stop();
            if (s2 != null) s2.Stop();
            if (s3 != null) s3.Stop();
            if (s4 != null) s4.Stop();
        }
        private ICommand _gridXCommandIc; [XmlIgnore] public ICommand GridXCommandIc => _gridXCommandIc ?? (_gridXCommandIc = new Earthblend.DynamicCompile.RelayCommand<Object>(GridXCommandIcExecuted));
        private void GridXCommandIcExecuted(Object sender) { UIServices.Busy(); dc.ShowGridX = !dc.ShowGridX; }

        private ICommand _GridYCommandIc; [XmlIgnore] public ICommand GridYCommandIc => _GridYCommandIc ?? (_GridYCommandIc = new Earthblend.DynamicCompile.RelayCommand<Object>(GridYCommandIcExecuted));
        private void GridYCommandIcExecuted(Object sender) { UIServices.Busy(); dc.ShowGridY = !dc.ShowGridY; }

        private ICommand _GridZCommandIc; [XmlIgnore] public ICommand GridZCommandIc => _GridZCommandIc ?? (_GridZCommandIc = new Earthblend.DynamicCompile.RelayCommand<Object>(GridZCommandIcExecuted));
        private void GridZCommandIcExecuted(Object sender) { UIServices.Busy(); dc.ShowGridZ = !dc.ShowGridZ; }



        private ICommand _saveCommandIc; [XmlIgnore] public ICommand SaveCommandIc => _saveCommandIc ?? (_saveCommandIc = new Earthblend.DynamicCompile.RelayCommand<Object>(SaveCommandIcExecuted));
        private void SaveCommandIcExecuted(Object sender)
        {
            UIServices.Busy();

            FileService fileService = new FileService();
            var xml = fileService.SaveToXml<RangeViewModel>(this, XmlUtil.LoadSaveTypes);
            String path = VirtualSystemUtil.ApplicationStorageFolder + @"ConfigurationModels\Configuration.xml";
            StreamWriter sw = new StreamWriter(path);
            sw.WriteLine(xml);
            sw.Close();
            sw.Dispose();
            sw = null;
            fileService = null;
        }




        [XmlIgnore] public WorldItemsExport WorldItems { get; set; } = null;
        [XmlIgnore] public CanvasItemsExport CanvasItems { get; set; } = null;
        [XmlIgnore] public TargetItemsExport TargetItems { get; set; } = null;

        //public void RenderSaved3D(EquationTester dc)
        //{
        //    foreach(var match in MatchResults)
        //    {
        //        match.Model.Children.Clear();
        //        EquationTester equationTester = new EquationTester();
        //        equationTester.WSub1 = match.W;
        //        equationTester.HSub1 = match.H;
        //        equationTester.DSub1 = match.D;
        //        equationTester.ZSub1 = match.Z;

        //        Model3DGroupRenderService service = new Model3DGroupRenderService();
        //        FileService fileService = new FileService();
        //        var xmlWorld = fileService.SaveToXml<WorldItemsExport>(WorldItems, XmlUtil.LoadSaveTypes);
        //        var xmlCanvas = fileService.SaveToXml<CanvasItemsExport>(CanvasItems, XmlUtil.LoadSaveTypes);
        //        var xmlTargets = fileService.SaveToXml<TargetItemsExport>(TargetItems, XmlUtil.LoadSaveTypes);

        //        service.VirtualWorldDataItems = fileService.LoadFromXml<WorldItemsExport>(xmlWorld, XmlUtil.LoadSaveTypes).Items.ToObservableCollection();
        //        service.VirtualCanvasPluginDataItems = fileService.LoadFromXml<CanvasItemsExport>(xmlCanvas, XmlUtil.LoadSaveTypes).Items.ToObservableCollection();
        //        service.TargetDefinitions = fileService.LoadFromXml<TargetItemsExport>(xmlTargets, XmlUtil.LoadSaveTypes).Items.ToObservableCollection();
        //        fileService = null;

        //        #region Populate Class Values

        //        new TestCodeViewModel().UpdateClassValues(service, equationTester);

        //        #endregion

        //        foreach (var target in service.TargetDefinitions)
        //        {
        //            var canvasItem = service.VirtualCanvasPluginDataItems.Where(c => c.EquationId == target.EquationId && c.SymbolType == Earthblend.Tts.Common.Core.Enumerations.MathSymbolType.EquationVariable && c.Sequence == 1);
        //            var answerCanvasItem = service.VirtualCanvasPluginDataItems.Where(c => c.EquationId == target.EquationId && c.SymbolType == Earthblend.Tts.Common.Core.Enumerations.MathSymbolType.Answer);

        //            if (canvasItem != null)
        //            {
        //                target.VirtualResult = dc.GetFieldValue(new SubscriptService().TranslateSubscript(canvasItem.FirstOrDefault().DisplayText), equationTester);

        //                if (answerCanvasItem.Any())
        //                {
        //                    answerCanvasItem.FirstOrDefault().DisplayText = target.VirtualResult.ToString();
        //                }
        //            }
        //        }

        //        #region Repopulate non target answers

        //        foreach (var item in service.VirtualCanvasPluginDataItems.Where(c => c.SymbolType == Earthblend.Tts.Common.Core.Enumerations.MathSymbolType.EquationVariable))
        //        {
        //            var answerCheck = service.VirtualCanvasPluginDataItems.Where(c => c.EquationId == item.EquationId && c.SymbolType == Earthblend.Tts.Common.Core.Enumerations.MathSymbolType.Answer);
        //            if (answerCheck.Any())
        //            {
        //                answerCheck.FirstOrDefault().DisplayText = dc.GetFieldValue(new SubscriptService().TranslateSubscript(item.DisplayText), equationTester).ToString();
        //            }
        //        }

        //        #endregion

        //        match.Model.Children.Add(service.Render(Guid.Empty, service.VirtualWorldDataItems));

        //    }
        //}


        public EquationTester RenderGenerated3D(EquationTester dc,Double w, Double h, Double z)
        {
            EquationTester equationTester = new EquationTester();
            //equationTester.WSub1 = w;
            //equationTester.HSub1 = h;
            //equationTester.ZSub1 = z;

            Model3DGroupRenderService service = new Model3DGroupRenderService();
            FileService fileService = new FileService();
            var xmlWorld = fileService.SaveToXml<WorldItemsExport>(WorldItems, XmlUtil.LoadSaveTypes);
            var xmlCanvas = fileService.SaveToXml<CanvasItemsExport>(CanvasItems, XmlUtil.LoadSaveTypes);
            var xmlTargets = fileService.SaveToXml<TargetItemsExport>(TargetItems, XmlUtil.LoadSaveTypes);

            service.VirtualWorldDataItems = fileService.LoadFromXml<WorldItemsExport>(xmlWorld, XmlUtil.LoadSaveTypes).Items.ToObservableCollection();
            service.VirtualCanvasPluginDataItems = fileService.LoadFromXml<CanvasItemsExport>(xmlCanvas, XmlUtil.LoadSaveTypes).Items.ToObservableCollection();
            service.TargetDefinitions = fileService.LoadFromXml<TargetItemsExport>(xmlTargets, XmlUtil.LoadSaveTypes).Items.ToObservableCollection();
            fileService = null;

            #region Populate Class Values

            new TestCodeViewModel().UpdateClassValues(service, equationTester);

            #endregion

            foreach (var target in service.TargetDefinitions)
            {
                var canvasItem = service.VirtualCanvasPluginDataItems.Where(c =>
                    c.EquationId == target.EquationId
                && c.SymbolType == Earthblend.Tts.Common.Core.Enumerations.MathSymbolType.EquationVariable
                && c.Sequence == 1);

                var answerCanvasItem = service.VirtualCanvasPluginDataItems.Where(c =>
                    c.EquationId == target.EquationId
                && c.SymbolType == Earthblend.Tts.Common.Core.Enumerations.MathSymbolType.Answer);

                if (canvasItem != null)
                {
                    target.VirtualResult = dc.GetFieldValue(new SubscriptService().TranslateSubscript(canvasItem.FirstOrDefault().DisplayText), dc);

                    if (answerCanvasItem.Any())
                    {
                        answerCanvasItem.FirstOrDefault().DisplayText = target.VirtualResult.ToString();
                    }
                }
            }

            #region Repopulate non target answers

            foreach (var item in CanvasItems.Items.Where(c => c.SymbolType == Earthblend.Tts.Common.Core.Enumerations.MathSymbolType.EquationVariable))
            {
                var answerCheck = CanvasItems.Items.Where(c => c.EquationId == item.EquationId && c.SymbolType == Earthblend.Tts.Common.Core.Enumerations.MathSymbolType.Answer);
                if (answerCheck.Any())
                {
                    answerCheck.FirstOrDefault().DisplayText = dc.GetFieldValue(new SubscriptService().TranslateSubscript(item.DisplayText), dc).ToString();
                }
            }

            #endregion

            equationTester.MainModel3DGroup.Children.Add(service.Render(Guid.Empty, service.VirtualWorldDataItems));

            return equationTester;
        }

        public void RenderText(EquationTester dc)
        {
            Application.Current.Dispatcher.Invoke(DispatcherPriority.Background, new Action(() =>
            {
                dc.TextModel3DGroup.Children.Clear();

                LetterService letterService = new LetterService();

                var textDataItems = WorldItems.Items.Where(c => !String.IsNullOrEmpty(c.Text));

                //if (textDataItems.Any()) { }

                foreach (var dataItem in textDataItems)
                {
                    var textDataItem = dataItem;
                    textDataItem.TextFontSize = dataItem.TextFontSize;
                    textDataItem.FontDepth = dataItem.FontDepth;
                    dc.TextModel3DGroup.Children.Add(letterService.AddRibbonTextItem(textDataItem));
                }

                letterService = null;
            }));
        }

        #region W
        private ICommand _decreaseWStartCommandIc; [XmlIgnore] public ICommand DecreaseWStartCommandIc => _decreaseWStartCommandIc ?? (_decreaseWStartCommandIc = new Earthblend.DynamicCompile.RelayCommand<Object>(DecreaseWStartCommandIcExecuted));
        public void DecreaseWStartCommandIcExecuted(Object sender)
        {
            WStart--;
        }

        private ICommand _increaseWStartCommandIc; [XmlIgnore] public ICommand IncreaseWStartCommandIc => _increaseWStartCommandIc ?? (_increaseWStartCommandIc = new Earthblend.DynamicCompile.RelayCommand<Object>(IncreaseWStartCommandIcExecuted));
        public void IncreaseWStartCommandIcExecuted(Object sender)
        {
            WStart++;
        }


        private ICommand _decreaseWEndCommandIc; [XmlIgnore] public ICommand DecreaseWEndCommandIc => _decreaseWEndCommandIc ?? (_decreaseWEndCommandIc = new Earthblend.DynamicCompile.RelayCommand<Object>(DecreaseWEndCommandIcExecuted));
        public void DecreaseWEndCommandIcExecuted(Object sender)
        {
            WEnd--;
        }

        private ICommand _increaseWEndCommandIc; [XmlIgnore] public ICommand IncreaseWEndCommandIc => _increaseWEndCommandIc ?? (_increaseWEndCommandIc = new Earthblend.DynamicCompile.RelayCommand<Object>(IncreaseWEndCommandIcExecuted));
        public void IncreaseWEndCommandIcExecuted(Object sender)
        {
            WEnd++;
        }


        private ICommand _decreaseWStepCommandIc; [XmlIgnore] public ICommand DecreaseWStepCommandIc => _decreaseWStepCommandIc ?? (_decreaseWStepCommandIc = new Earthblend.DynamicCompile.RelayCommand<Object>(DecreaseWStepCommandIcExecuted));
        public void DecreaseWStepCommandIcExecuted(Object sender)
        {
            if (WStep == 1)
            {
                WStep = .1;
            }
            else if (WStep < 1 && WStep > .0001)
            {
                String str = WStep.ToString().Replace("0.","");
                str = str.Insert(0, ".0");
                WStep = Convert.ToDouble(str);
            }
            else if (WStep > 1)
            {
                WStep--;
            } 
        }
        
        private ICommand _increaseWStepCommandIc; [XmlIgnore] public ICommand IncreaseWStepCommandIc => _increaseWStepCommandIc ?? (_increaseWStepCommandIc = new Earthblend.DynamicCompile.RelayCommand<Object>(IncreaseWStepCommandIcExecuted));
        public void IncreaseWStepCommandIcExecuted(Object sender)
        {
            if (WStep >= 1)
            {
                WStep++;
            }
            else if (WStep < .1)
            {
                String str = WStep.ToString().Substring(1, WStep.ToString().Length - 1);
                str = "." + str.Substring(1, str.Length - 3) + "1";
                WStep = Convert.ToDouble(str);
            }
            else WStep = 1;
        }

        #endregion

        #region H
        private ICommand _decreaseHStartCommandIc; [XmlIgnore] public ICommand DecreaseHStartCommandIc => _decreaseHStartCommandIc ?? (_decreaseHStartCommandIc = new Earthblend.DynamicCompile.RelayCommand<Object>(DecreaseHStartCommandIcExecuted));
        public void DecreaseHStartCommandIcExecuted(Object sender)
        {
            HStart--;
        }

        private ICommand _increaseHStartCommandIc; [XmlIgnore] public ICommand IncreaseHStartCommandIc => _increaseHStartCommandIc ?? (_increaseHStartCommandIc = new Earthblend.DynamicCompile.RelayCommand<Object>(IncreaseHStartCommandIcExecuted));
        public void IncreaseHStartCommandIcExecuted(Object sender)
        {
            HStart++;
        }


        private ICommand _decreaseHEndCommandIc; [XmlIgnore] public ICommand DecreaseHEndCommandIc => _decreaseHEndCommandIc ?? (_decreaseHEndCommandIc = new Earthblend.DynamicCompile.RelayCommand<Object>(DecreaseHEndCommandIcExecuted));
        public void DecreaseHEndCommandIcExecuted(Object sender)
        {
            HEnd--;
        }

        private ICommand _increaseHEndCommandIc; [XmlIgnore] public ICommand IncreaseHEndCommandIc => _increaseHEndCommandIc ?? (_increaseHEndCommandIc = new Earthblend.DynamicCompile.RelayCommand<Object>(IncreaseHEndCommandIcExecuted));
        public void IncreaseHEndCommandIcExecuted(Object sender)
        {
            HEnd++;
        }


        private ICommand _decreaseHStepCommandIc; [XmlIgnore] public ICommand DecreaseHStepCommandIc => _decreaseHStepCommandIc ?? (_decreaseHStepCommandIc = new Earthblend.DynamicCompile.RelayCommand<Object>(DecreaseHStepCommandIcExecuted));
        public void DecreaseHStepCommandIcExecuted(Object sender)
        {
            if (HStep == 1)
            {
                HStep = .1;
            }
            else if (HStep < 1 && HStep > .0001)
            {
                String str = HStep.ToString().Replace("0.", "");
                str = str.Insert(0, ".0");
                HStep = Convert.ToDouble(str);
            }
            else if (HStep > 1)
            {
                HStep--;
            }
        }

        private ICommand _increaseHStepCommandIc; [XmlIgnore] public ICommand IncreaseHStepCommandIc => _increaseHStepCommandIc ?? (_increaseHStepCommandIc = new Earthblend.DynamicCompile.RelayCommand<Object>(IncreaseHStepCommandIcExecuted));
        public void IncreaseHStepCommandIcExecuted(Object sender)
        {
            if (HStep >= 1)
            {
                HStep++;
            }
            else if (HStep < .1)
            {
                String str = HStep.ToString().Substring(1, HStep.ToString().Length - 1);
                str = "." + str.Substring(1, str.Length - 3) + "1";
                HStep = Convert.ToDouble(str);
            }
            else HStep = 1;
        }

        #endregion

        #region D
        private ICommand _decreaseDStartCommandIc; [XmlIgnore] public ICommand DecreaseDStartCommandIc => _decreaseDStartCommandIc ?? (_decreaseDStartCommandIc = new Earthblend.DynamicCompile.RelayCommand<Object>(DecreaseDStartCommandIcExecuted));
        public void DecreaseDStartCommandIcExecuted(Object sender)
        {
            DStart--;
        }

        private ICommand _increaseDStartCommandIc; [XmlIgnore] public ICommand IncreaseDStartCommandIc => _increaseDStartCommandIc ?? (_increaseDStartCommandIc = new Earthblend.DynamicCompile.RelayCommand<Object>(IncreaseDStartCommandIcExecuted));
        public void IncreaseDStartCommandIcExecuted(Object sender)
        {
            DStart++;
        }


        private ICommand _decreaseDEndCommandIc; [XmlIgnore] public ICommand DecreaseDEndCommandIc => _decreaseDEndCommandIc ?? (_decreaseDEndCommandIc = new Earthblend.DynamicCompile.RelayCommand<Object>(DecreaseDEndCommandIcExecuted));
        public void DecreaseDEndCommandIcExecuted(Object sender)
        {
            DEnd--;
        }

        private ICommand _increaseDEndCommandIc; [XmlIgnore] public ICommand IncreaseDEndCommandIc => _increaseDEndCommandIc ?? (_increaseDEndCommandIc = new Earthblend.DynamicCompile.RelayCommand<Object>(IncreaseDEndCommandIcExecuted));
        public void IncreaseDEndCommandIcExecuted(Object sender)
        {
            DEnd++;
        }


        private ICommand _decreaseDStepCommandIc; [XmlIgnore] public ICommand DecreaseDStepCommandIc => _decreaseDStepCommandIc ?? (_decreaseDStepCommandIc = new Earthblend.DynamicCompile.RelayCommand<Object>(DecreaseDStepCommandIcExecuted));
        public void DecreaseDStepCommandIcExecuted(Object sender)
        {
            if (DStep == 1)
            {
                DStep = .1;
            }
            else if (DStep < 1 && DStep > .0001)
            {
                String str = DStep.ToString().Replace("0.", "");
                str = str.Insert(0, ".0");
                DStep = Convert.ToDouble(str);
            }
            else if (DStep > 1)
            {
                DStep--;
            }
        }

        private ICommand _increaseDStepCommandIc; [XmlIgnore] public ICommand IncreaseDStepCommandIc => _increaseDStepCommandIc ?? (_increaseDStepCommandIc = new Earthblend.DynamicCompile.RelayCommand<Object>(IncreaseDStepCommandIcExecuted));
        public void IncreaseDStepCommandIcExecuted(Object sender)
        {
            if (DStep >= 1)
            {
                DStep++;
            }
            else if (DStep < .1)
            {
                String str = DStep.ToString().Substring(1, DStep.ToString().Length - 1);
                str = "." + str.Substring(1, str.Length - 3) + "1";
                DStep = Convert.ToDouble(str);
            }
            else DStep = 1;
        }

        #endregion

        #region Z
        private ICommand _decreaseZStartCommandIc; [XmlIgnore] public ICommand DecreaseZStartCommandIc => _decreaseZStartCommandIc ?? (_decreaseZStartCommandIc = new Earthblend.DynamicCompile.RelayCommand<Object>(DecreaseZStartCommandIcExecuted));
        public void DecreaseZStartCommandIcExecuted(Object sender)
        {
            ZStart--;
        }

        private ICommand _increaseZStartCommandIc; [XmlIgnore] public ICommand IncreaseZStartCommandIc => _increaseZStartCommandIc ?? (_increaseZStartCommandIc = new Earthblend.DynamicCompile.RelayCommand<Object>(IncreaseZStartCommandIcExecuted));
        public void IncreaseZStartCommandIcExecuted(Object sender)
        {
            ZStart++;
        }


        private ICommand _decreaseZEndCommandIc; [XmlIgnore] public ICommand DecreaseZEndCommandIc => _decreaseZEndCommandIc ?? (_decreaseZEndCommandIc = new Earthblend.DynamicCompile.RelayCommand<Object>(DecreaseZEndCommandIcExecuted));
        public void DecreaseZEndCommandIcExecuted(Object sender)
        {
            ZEnd--;
        }

        private ICommand _increaseZEndCommandIc; [XmlIgnore] public ICommand IncreaseZEndCommandIc => _increaseZEndCommandIc ?? (_increaseZEndCommandIc = new Earthblend.DynamicCompile.RelayCommand<Object>(IncreaseZEndCommandIcExecuted));
        public void IncreaseZEndCommandIcExecuted(Object sender)
        {
            ZEnd++;
        }


        private ICommand _decreaseZStepCommandIc; [XmlIgnore] public ICommand DecreaseZStepCommandIc => _decreaseZStepCommandIc ?? (_decreaseZStepCommandIc = new Earthblend.DynamicCompile.RelayCommand<Object>(DecreaseZStepCommandIcExecuted));
        public void DecreaseZStepCommandIcExecuted(Object sender)
        {
            if (ZStep == 1)
            {
                ZStep = .1;
            }
            else if (ZStep < 1 && ZStep > .0001)
            {
                String str = ZStep.ToString().Replace("0.", "");
                str = str.Insert(0, ".0");
                ZStep = Convert.ToDouble(str);
            }
            else if (ZStep > 1)
            {
                ZStep--;
            }
        }

        private ICommand _increaseZStepCommandIc; [XmlIgnore] public ICommand IncreaseZStepCommandIc => _increaseZStepCommandIc ?? (_increaseZStepCommandIc = new Earthblend.DynamicCompile.RelayCommand<Object>(IncreaseZStepCommandIcExecuted));
        public void IncreaseZStepCommandIcExecuted(Object sender)
        {
            if (ZStep >= 1)
            {
                ZStep++;
            }
            else if (ZStep < .1)
            {
                String str = ZStep.ToString().Substring(1, ZStep.ToString().Length - 1);
                str = "." + str.Substring(1, str.Length - 3) + "1";
                ZStep = Convert.ToDouble(str);
            }
            else ZStep = 1;
        }

        #endregion


        private ICommand _decreaseStartRangeCommandIc; [XmlIgnore] public ICommand DecreaseStartRangeCommandIc => _decreaseStartRangeCommandIc ?? (_decreaseStartRangeCommandIc = new Earthblend.DynamicCompile.RelayCommand<Object>(DecreaseStartRangeCommandIcExecuted));
        public void DecreaseStartRangeCommandIcExecuted(Object sender)
        {
            StartRange--;
        }

        private ICommand _increaseStartRangeCommandIc; [XmlIgnore] public ICommand IncreaseStartRangeCommandIc => _increaseStartRangeCommandIc ?? (_increaseStartRangeCommandIc = new Earthblend.DynamicCompile.RelayCommand<Object>(IncreaseStartRangeCommandIcExecuted));
        public void IncreaseStartRangeCommandIcExecuted(Object sender)
        {
            StartRange++;
        }


        private ICommand _decreaseEndRangeCommandIc; [XmlIgnore] public ICommand DecreaseEndRangeCommandIc => _decreaseEndRangeCommandIc ?? (_decreaseEndRangeCommandIc = new Earthblend.DynamicCompile.RelayCommand<Object>(DecreaseEndRangeCommandIcExecuted));
        public void DecreaseEndRangeCommandIcExecuted(Object sender)
        {
            EndRange--;
        }

        private ICommand _increaseEndRangeCommandIc; [XmlIgnore] public ICommand IncreaseEndRangeCommandIc => _increaseEndRangeCommandIc ?? (_increaseEndRangeCommandIc = new Earthblend.DynamicCompile.RelayCommand<Object>(IncreaseEndRangeCommandIcExecuted));
        public void IncreaseEndRangeCommandIcExecuted(Object sender)
        {
            EndRange++;
        }





        private ICommand _selectItemCommandIc; [XmlIgnore] public ICommand SelectItemCommandIc => _selectItemCommandIc ?? (_selectItemCommandIc = new Earthblend.DynamicCompile.RelayCommand<Object>(SelectItemCommandIcExecuted));
        public void SelectItemCommandIcExecuted(Object sender) 
        {
            SelectedMatchResult = (MatchResult)sender;
            //dc.WSub1 = SelectedMatchResult.W;
            //dc.HSub1 = SelectedMatchResult.H;
            //dc.DSub1 = SelectedMatchResult.D;
            //dc.ZSub1 = SelectedMatchResult.Z;
        }

        [XmlIgnore] public EquationTester Et { get; set; } = null;

        public RangeViewModel()
        {
         
        }
        public RangeViewModel(EquationTester et)
        {
            Et = et;    
        }

        #region Private Variables

        private Double _wStart = 1;
        private Double _hStart = 1;
        private Double _dStart = 2;
        private Double _zStart = -3;

        private Double _wEnd = 20;
        private Double _hEnd = 20;
        private Double _dEnd = 20;
        private Double _zEnd = 3;

        private Double _wStep = 1D;
        private Double _hStep = 1D;
        private Double _dStep = 1D;
        private Double _zStep = 1D;

        private MatchResult _selectedMatchResult = null;
        private ObservableCollection<MatchResult> _matchResults = new ObservableCollection<MatchResult>();

        #endregion

        #region Public Clr Properties
        public MatchResult SelectedMatchResult { get { return _selectedMatchResult; } set { SetProperty(ref _selectedMatchResult, value);

                if (_selectedMatchResult != null)
                {
                    if (Et != null)
                    {
                        //Et.WSub1 = _selectedMatchResult.W;
                        //Et.HSub1 = _selectedMatchResult.H;
                        //Et.DSub1 = _selectedMatchResult.D;
                        Et.RenderText = true;
                        //Et.ZSub1 = _selectedMatchResult.Z;
                        Et.RenderText = false;
                    }
                }
            }
        }

        public ObservableCollection<MatchResult> MatchResults { get { return _matchResults; } set { SetProperty(ref _matchResults, value); } }

        public Double WStart { get { return _wStart; } set { SetProperty(ref _wStart, value); } }
        public Double HStart { get { return _hStart; } set { SetProperty(ref _hStart, value); } }
        public Double DStart { get { return _dStart; } set { SetProperty(ref _dStart, value); } }
        public Double ZStart { get { return _zStart; } set { SetProperty(ref _zStart, value); } }


        public Double WEnd { get { return _wEnd; } set { SetProperty(ref _wEnd, value); } }
        public Double HEnd { get { return _hEnd; } set { SetProperty(ref _hEnd, value); } }
        public Double DEnd { get { return _dEnd; } set { SetProperty(ref _dEnd, value); } }
        public Double ZEnd { get { return _zEnd; } set { SetProperty(ref _zEnd, value); } }

        public Double WStep { get { return _wStep; } set { SetProperty(ref _wStep, value); } }
        public Double HStep { get { return _hStep; } set { SetProperty(ref _hStep, value); } }
        public Double DStep { get { return _dStep; } set { SetProperty(ref _dStep, value); } }
        public Double ZStep { get { return _zStep; } set { SetProperty(ref _zStep, value); } }

        private Double _startRange = 0;
        private Double _endRange = 0;

        public Double StartRange { get { return _startRange; } set { SetProperty(ref _startRange, value); } }
        public Double EndRange { get { return _endRange; } set { SetProperty(ref _endRange, value); } }

        #endregion
    }
}