public void CanvasMouseBtnLDown(MouseEventArgs e)
        {
            var itemsControl = e.Source as ItemsControl;
            _mousePosition = new Point(e.GetPosition(itemsControl).X, e.GetPosition(itemsControl).Y); //get mousePos
            if (itemsControl?.Items.Count > 0 && !IsDrawBonesMode && !IsAnimationMode)
            {
                //Filter out  images and bones that the cursor overlaps
                var texlist = new List<Texture2D>();
                var bonelist = new List<Bone>();
                try
                {
                    texlist = ViewportCollection.OfType<Texture2D>().ToList();
                    bonelist = ViewportCollection.OfType<Bone>().ToList();
                }
                catch (Exception ex)
                {
                    MessageBox.Show(ex.Message);
                }
                

                var texOverlapList = texlist.Where(item => item.IsMouseOver).ToList();
                var boneOverlapList = bonelist.Where(item => item.IsMouseOver).ToList();
                if (texOverlapList.Count > 0 || boneOverlapList.Count > 0)
                {
                    Texture2D tex = null;
                    Bone bone = null;

                    if (texOverlapList.Count >= 1 ) tex = texOverlapList.Aggregate((i1, i2) => i1.Zindex > i2.Zindex ? i1 : i2);
                    if (boneOverlapList.Count >= 1) bone = boneOverlapList.Aggregate((i1, i2) => i1.Zindex > i2.Zindex ? i1 : i2);

                    if (bone != null)
                    {
                        //Set Everything else as not selected
                        foreach (var obj in ViewportCollection)
                        {
                            if (obj is Texture2D) ((Texture2D)obj).Selected = false;
                            else if (obj is Bone) ((Bone)obj).Selected = false;
                        }
                        Cursor = Cursors.SizeAll;
                        bone.Selected = true;
                        DraggedObject = bone;
                        _objPreTranslated = new Bone(bone);
                    }
                    else if (tex != null)
                    {
                        //check if cursor is in scale region
                        if (_mousePosition.X > (tex.PosX + tex.Width * tex.ScaleX) - _scaleOffsetArea &&
                            _mousePosition.X < (tex.PosX + tex.Width * tex.ScaleX) + _scaleOffsetArea &&
                            _mousePosition.Y > (tex.PosY + tex.Height * tex.ScaleY) - _scaleOffsetArea &&
                            _mousePosition.Y < (tex.PosY + tex.Height * tex.ScaleY) + _scaleOffsetArea)
                        {
                            ScaledTexture = tex;
                            _objPreTranslated = new Texture2D(tex);
                            Cursor = Cursors.SizeNWSE;
                        }
                        else //cursor was inside image 
                        {
                            //Set Everything else as not selected
                            foreach (var obj in itemsControl.Items)
                            {
                                if (obj is Texture2D) ((Texture2D)obj).Selected = false;
                                else if (obj is Bone) ((Bone)obj).Selected = false;
                            }
                            Cursor = Cursors.SizeAll;
                            tex.Selected = true;
                            DraggedObject = tex;
                            _objPreTranslated = new Texture2D(tex);
                        }
                    }
                }
                else //Cursor is clicking on empty canvas 
                {
                    //check if a bone or texture is selected if so it will be rotated in the mousemove
                    foreach (var texture in texlist) 
                    {
                        if (texture.Selected) 
                        {
                            RotatedObject = texture;
                            _objPreTranslated = new Texture2D(texture);
                        }
                    }
                    if (RotatedObject == null)
                    {
                        foreach (var bone in bonelist)
                        {
                            if (bone.Selected)
                            {
                                RotatedObject = bone;
                                _objPreTranslated = new Bone(bone);
                                break;
                            }
                        }
                    }
                }
            }
            else if(IsDrawBonesMode && !IsAnimationMode)
            {
                if (_boneDrawn == null)
                {
                    _boneDrawn = new Bone(_mousePosition.X,_mousePosition.Y, _mousePosition.X, _mousePosition.Y, string.Empty, 1.0,1.0) {Selected = true};
                    ViewportCollection.Add(_boneDrawn);
                }
                else
                {
                    //On second left click we are done drawing the bone
                    //Add Undo Action
                    var bone = _boneDrawn; //make a copy of the ref
                    AddUndoAction(new UnRedoPair(() => 
                    UndoDrop(new List<object>() { bone }), 
                    () => { _clearRedoStack = false; RedoDrop(new List<object>() { bone }); }));

                    _boneDrawn.Selected = false;
                    _boneDrawn = null;
                }

            }
            UpdateSelectedItem();
        }
        public Texture2D(Texture2D tex)
        {
            if (tex != null)
            {
                Texture = tex.Texture;
                Name = tex.Name;
                Rotation = tex.Rotation;
                ScaleX = tex.ScaleX;
                ScaleY = tex.ScaleY;
                Width = tex.Width;
                Height = tex.Height;
                Zindex = tex.Zindex;
                PosX = tex.PosX;
                PosY = tex.PosY;
                Selected = tex.Selected;

                var rand = new Random();
                Id = rand.Next(1000000000);
            }
            else
            {
                //TODO HANDLE THIS BETTER
                MessageBox.Show("An error occured!");
            }

        }
        private void LBoxRightClickReset(object obj)
        {
            if (obj is Texture2D && !IsAnimationMode)
            {
                var tex = obj as Texture2D;
                var undoTex = new Texture2D(tex);
                tex.PosX = 0;
                tex.PosY = 0;
                tex.ScaleX = 1;
                tex.ScaleY = 1;
                tex.Rotation = 0;

                 AddUndoAction(new UnRedoPair(() =>
                 {
                     tex.PosX = undoTex.PosX;
                     tex.PosY = undoTex.PosY; 
                    tex.ScaleX = undoTex.ScaleX;
                    tex.ScaleY = undoTex.ScaleY;
                    tex.Rotation = undoTex.Rotation;
                 }, () => 
                 { _clearRedoStack = false; LBoxRightClickReset(obj); }));
            }
            else if (obj is Bone && !IsAnimationMode)
            {
                var bone = obj as Bone;
                var undoBone = new Bone(bone);
                bone.Selected = false;
                bone.Rotation = 0;
                bone.ScaleX = 1;
                bone.ScaleY = 1;

                AddUndoAction(new UnRedoPair(() =>
                {
                    bone.Selected = undoBone.Selected;
                    bone.Rotation = undoBone.Rotation;
                    bone.ScaleX = undoBone.ScaleX;
                    bone.ScaleY = undoBone.ScaleY;
                }, () => { _clearRedoStack = false; LBoxRightClickReset(obj); }));
            }
            UpdateSelectedItem();
        }
        //TODO IMPLEMENT COMMANDS RIGHT CLICK AND MOVE

        private void ImportTexture()
        {
            var dialog = new OpenFileDialog
            {
                Filter = "Image Files (.jpg, .jpeg, .gif, .bmp, .png)|*.jpg; *.jpeg; *.gif; *.bmp; *.png",
                Multiselect = true
            };

            if (dialog.ShowDialog() == true)
            {
                int i = 0;
                foreach (var fName in dialog.FileNames)
                {
                    var bitmap = new BitmapImage(new Uri(fName, UriKind.RelativeOrAbsolute));
                    var image = new Image { Source = bitmap };
                    var name = string.IsNullOrEmpty(dialog.SafeFileNames[i]) ? dialog.FileName : dialog.SafeFileNames[i];

                    Texture2D tex = new Texture2D
                    {
                        Texture = image,
                        Name = name,
                        Height = (float)image.Source.Height,
                        Width = (float)image.Source.Width,
                        PosX = 0,
                        PosY = 0,
                        ScaleX = 1.0,
                        ScaleY = 1.0,
                        Selected = false
                    };

                    TextureCollection.Add(tex);
                    i++;
                }
            }
        }
        public void InputGrid()
        {
            var undoObj = SelectedItem; //Make Ref of SelectedItem for undo
            if (_objPreTranslatedGrid is Texture2D)
            {
                var sTex = new Texture2D(SelectedItem as Texture2D);
                var sOrigTex = new Texture2D(_objPreTranslatedGrid as Texture2D);

                if (sTex.PosX != sOrigTex.PosX || sTex.PosY != sOrigTex.PosY || sTex.ScaleX != sOrigTex.ScaleX ||
                    sTex.ScaleY != sOrigTex.ScaleY || sTex.Rotation != sOrigTex.Rotation)
                {
                    AddUndoAction(new UnRedoPair(() =>
                    { Translate(undoObj, sOrigTex.PosX, sOrigTex.PosY, sOrigTex.ScaleX, sOrigTex.ScaleY, sOrigTex.Rotation, true); },
                    () => { Translate(undoObj, sTex.PosX, sTex.PosY, sTex.ScaleX, sTex.ScaleY, sTex.Rotation, false); }));
                }
            }
            else if (_objPreTranslatedGrid is Bone)
            {
                var sBone = new Bone(SelectedItem as Bone);
                var sOrigBone = new Bone(_objPreTranslatedGrid as Bone);

                if (sBone.PosX != sOrigBone.PosX || sBone.PosY != sOrigBone.PosY || sBone.ScaleX != sOrigBone.ScaleX ||
                    sBone.ScaleY != sOrigBone.ScaleY || sBone.Rotation != sOrigBone.Rotation)
                {
                    AddUndoAction(new UnRedoPair(() =>
                    { Translate(undoObj, sOrigBone.PosX, sOrigBone.PosY, sOrigBone.ScaleX, sOrigBone.ScaleY, sOrigBone.Rotation, true); },
                    () => { Translate(undoObj, sBone.PosX, sBone.PosY, sBone.ScaleX, sBone.ScaleY, sBone.Rotation, false); }));
                }
            }
            _objPreTranslatedGrid = null;
        }
 public void PotentialInputGrid()
 {
     if(SelectedItem is Texture2D)
         _objPreTranslatedGrid = new Texture2D((Texture2D) SelectedItem);
     else if (SelectedItem is Bone)
         _objPreTranslatedGrid = new Bone((Bone) SelectedItem);
 }
        public void Drop(IDropInfo dropInfo)
        {
            var tex = dropInfo.Data as Texture2D;
            var texArr = dropInfo.Data as List<Texture2D>;
            var dataObject = (dropInfo.Data as IDataObject);

            //Undo   
            List<object> undoTexList = new List<object>();

            if (tex != null) //Import one texture from listbox resources
            {
                tex.Zindex = ViewportCollection.Count;
                if (!ViewportCollection.Contains(tex))
                {
                    //Scale Image if larger then canvas
                    var vTex = new Texture2D(tex);
                    double scale = (vTex.Height * vTex.Width) / (WindowHeight * (WindowWidth - 100));
                    if (scale > 1)
                    {
                        vTex.ScaleX /= scale / 2;
                        vTex.ScaleY /= scale / 2;
                    }

                    ViewportCollection.Add(vTex); //add copy of texture2D to viewportcollection
                    undoTexList.Add(vTex);
                }
            }
            else if (texArr != null) //Import multiple texture from listbox resources
            {
                foreach (var texture in texArr)
                {
                    texture.Zindex = ViewportCollection.Count;
                    if (!ViewportCollection.Contains(texture))
                    {
                        //Scale Image if larger then canvas
                        var vTex = new Texture2D(texture);
                        double scale = (vTex.Height * vTex.Width) / (WindowHeight * (WindowWidth - 100));
                        if (scale > 1)
                        {
                            vTex.ScaleX /= scale / 2;
                            vTex.ScaleY /= scale / 2;
                        }
                        ViewportCollection.Add(vTex); //add copy of texture2D to viewportcollection
                        undoTexList.Add(vTex);
                    }
                }
            }
            else if (dataObject != null && dataObject.GetDataPresent(DataFormats.FileDrop, true)) //Import from filexplorer
            {
                string[] filenames = (string[])dataObject.GetData(DataFormats.FileDrop, true);
                foreach (var fName in filenames)
                {
                    var name = Path.GetFileName(fName);
                    if (!string.IsNullOrEmpty(fName))
                    {
                        try
                        {
                            var bitmap = new BitmapImage(new Uri(fName, UriKind.RelativeOrAbsolute));
                            var image = new Image { Source = bitmap };
                            Texture2D texture = new Texture2D
                            {
                                Texture = image,
                                Name = name,
                                Height = (float)image.Source.Height,
                                Width = (float)image.Source.Width,
                                PosX = 0,
                                PosY = 0,
                                ScaleX = 1.0,
                                ScaleY = 1.0,
                                Selected = false
                            };
                            texture.Zindex = ViewportCollection.Count;
                            TextureCollection.Add(texture);

                            //Scale Image if larger then canvas
                            var vTex = new Texture2D(texture);
                            double scale = (vTex.Height * vTex.Width) / (WindowHeight * (WindowWidth - 100));
                            if (scale > 1)
                            {
                                vTex.ScaleX /= scale / 2;
                                vTex.ScaleY /= scale / 2;
                            }

                            ViewportCollection.Add(vTex); 
                            undoTexList.Add(vTex);
                        }
                        catch (Exception)
                        {
                            //await this.ShowMessageAsync("This is the title", "Some message");
                            MessageBox.Show($"There was a problem importing a file!\n" +
                                            $"2D Skeleton Animator does not support files of type {Path.GetExtension(fName)}." +
                                            $"\nOnly files with extension: .jpg, .jpeg, .gif, .bmp, .jpg, .jpeg, .gif, .bmp " +
                                            $"\nare currently supported.", "Error importing file!", MessageBoxButton.OK, MessageBoxImage.Error);
                        }
                    }
                }
            }
            AddUndoAction(new UnRedoPair(() => UndoDrop(undoTexList), () => { _clearRedoStack = false; RedoDrop(undoTexList); }));
        }