// Joseph Garcia

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Media.Media3D;
using System.Windows.Navigation;
using System.Windows.Shapes;

namespace MEMS_Visualizer
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        private VisualizationRenderer renderer;
        private MovementData movementData = new MovementData();

        public MainWindow()
        {
            InitializeComponent();
            
            // handle keyboard key down events
            this.KeyDown += MainWindow_KeyDown;

            renderer = new VisualizationRenderer(movementData);
            modelView.Child = renderer.Viewport;
        }

        // handle right and left arrow keypresses to advance through animations
        void MainWindow_KeyDown(object sender, KeyEventArgs e)
        {
            if (e.Key == Key.Right)
                NextButton.RaiseEvent(new RoutedEventArgs(Button.ClickEvent, NextButton));
            if (e.Key == Key.Left)
                PreviousButton.RaiseEvent(new RoutedEventArgs(Button.ClickEvent, PreviousButton));
        }

        // close when exit is clicked
        private void fileExitMenuItem_Click(object sender, RoutedEventArgs e)
        {
            this.Close();
        }

        // show open file dialog and load file when file->open selected
        private void fileOpenMenuItem_Click(object sender, RoutedEventArgs e)
        {
            // Configure open file dialog box
            Microsoft.Win32.OpenFileDialog dlg = new Microsoft.Win32.OpenFileDialog();
            dlg.DefaultExt = ".txt"; // Default file extension
            dlg.Filter = "Text Documents (.txt)|*.txt"; // Filter files by extension 

            // Show open file dialog box
            Nullable<bool> result = dlg.ShowDialog();

            // Process open file dialog box results 
            if (result == true)
            {
                // clear movementData
                movementData.clearData();

                // Open document 
                string filename = dlg.FileName;
                FileLoader fileLoader = new FileLoader(filename, movementData);

                // create renderer from movementData
                renderer = new VisualizationRenderer(movementData);
                modelView.Child = renderer.Viewport;

                // update labels
                xRotationLabel.Text = renderer.CurrentHandRotation.X.ToString();
                yRotationLabel.Text = renderer.CurrentHandRotation.Y.ToString();
                zRotationLabel.Text = renderer.CurrentHandRotation.Z.ToString();
                thumbPositionLabel.Text = renderer.CurrentThumbPosition.ToString();
                xThumbRotationLabel.Text = renderer.CurrentThumbRotation.X.ToString();
                yThumbRotationLabel.Text = renderer.CurrentThumbRotation.Y.ToString();
                zThumbRotationLabel.Text = renderer.CurrentThumbRotation.Z.ToString();
                currentIndexTextbox.Text = renderer.currentRotationIndex.ToString() + "/" + (renderer.TotalAnimations - 1);
            }
        }
        
        // load next animation on next button click
        private void NextButton_Click(object sender, RoutedEventArgs e)
        {
            // load next animation
            renderer.startNextAnimation();

            // update labels
            xRotationLabel.Text = renderer.CurrentHandRotation.X.ToString();
            yRotationLabel.Text = renderer.CurrentHandRotation.Y.ToString();
            zRotationLabel.Text = renderer.CurrentHandRotation.Z.ToString();
            thumbPositionLabel.Text = renderer.CurrentThumbPosition.ToString();
            xThumbRotationLabel.Text = renderer.CurrentThumbRotation.X.ToString();
            yThumbRotationLabel.Text = renderer.CurrentThumbRotation.Y.ToString();
            zThumbRotationLabel.Text = renderer.CurrentThumbRotation.Z.ToString();
            currentIndexTextbox.Text = renderer.currentRotationIndex.ToString() + "/" + (renderer.TotalAnimations - 1);
        }

        // load previous animation on previous button click
        private void PreviousButton_Click(object sender, RoutedEventArgs e)
        {
            // load previous animation
            renderer.startPreviousAnimation();

            // update labels
            xRotationLabel.Text = renderer.CurrentHandRotation.X.ToString();
            yRotationLabel.Text = renderer.CurrentHandRotation.Y.ToString();
            zRotationLabel.Text = renderer.CurrentHandRotation.Z.ToString();
            thumbPositionLabel.Text = renderer.CurrentThumbPosition.ToString();
            xThumbRotationLabel.Text = renderer.CurrentThumbRotation.X.ToString();
            yThumbRotationLabel.Text = renderer.CurrentThumbRotation.Y.ToString();
            zThumbRotationLabel.Text = renderer.CurrentThumbRotation.Z.ToString();
            currentIndexTextbox.Text = renderer.currentRotationIndex.ToString() + "/" + (renderer.TotalAnimations - 1); 
        }

        // update rotations if labels have data entered
        private void xRotationLabel_TextChanged(object sender, TextChangedEventArgs e)
        {
            labelUpdated();
        }

        private void yRotationLabel_TextChanged(object sender, TextChangedEventArgs e)
        {
            labelUpdated();
        }

        private void zRotationLabel_TextChanged(object sender, TextChangedEventArgs e)
        {
            labelUpdated();
        }

        private void thumbPositionLabel_TextChanged(object sender, TextChangedEventArgs e)
        {
            labelUpdated();
        }

        private void xThumbRotationLabel_TextChanged(object sender, TextChangedEventArgs e)
        {
            labelUpdated();
        }

        private void yThumbRotationLabel_TextChanged(object sender, TextChangedEventArgs e)
        {
            labelUpdated();
        }

        private void zThumbRotationLabel_TextChanged(object sender, TextChangedEventArgs e)
        {
            labelUpdated();
        }

        // update rotations with data from labels
        private void labelUpdated()
        {
            if (renderer != null)
            {
                double hx, hy, hz, tx, ty, tz, theta;
                if (!double.TryParse(xRotationLabel.Text, out hx))
                    return;
                if (!double.TryParse(yRotationLabel.Text, out hy))
                    return;
                if (!double.TryParse(zRotationLabel.Text, out hz))
                    return;
                if (!double.TryParse(xThumbRotationLabel.Text, out tx))
                    return;
                if (!double.TryParse(yThumbRotationLabel.Text, out ty))
                    return;
                if (!double.TryParse(zThumbRotationLabel.Text, out tz))
                    return;
                if (!double.TryParse(thumbPositionLabel.Text, out theta))
                    return;

                renderer.rotationsFromLabels(
                    new Vector3D(hx, hy, hz),
                    new Vector3D(tx, ty, tz),
                    theta);
            }
        }
    }
}
