using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
using ConeCalorimeter.ViewModels;

namespace ConeCalorimeter.Views;

public partial class SmokeDensitySettingsView : UserControl
{
    public SmokeDensitySettingsView()
    {
        InitializeComponent();
    }

    private void CalibrationButton_PreviewMouseLeftButtonDown(object sender, MouseButtonEventArgs e)
    {
        StartCalibration(sender);

        if (sender is Button button)
        {
            button.CaptureMouse();
        }
    }

    private void CalibrationButton_PreviewMouseLeftButtonUp(object sender, MouseButtonEventArgs e)
    {
        StopCalibration(sender);
        ReleaseMouseCapture(sender);
    }

    private void CalibrationButton_MouseLeave(object sender, MouseEventArgs e)
    {
        if (sender is Button { IsMouseCaptured: true })
        {
            StopCalibration(sender);
            ReleaseMouseCapture(sender);
        }
    }

    private void CalibrationButton_LostMouseCapture(object sender, MouseEventArgs e)
    {
        StopCalibration(sender);
    }

    private void CalibrationButton_TouchDown(object sender, TouchEventArgs e)
    {
        StartCalibration(sender);

        if (sender is Button button)
        {
            button.CaptureTouch(e.TouchDevice);
        }

        e.Handled = true;
    }

    private void CalibrationButton_TouchUp(object sender, TouchEventArgs e)
    {
        StopCalibration(sender);
        ReleaseTouchCapture(sender, e.TouchDevice);
        e.Handled = true;
    }

    private void CalibrationButton_TouchLeave(object sender, TouchEventArgs e)
    {
        StopCalibration(sender);
        ReleaseTouchCapture(sender, e.TouchDevice);
    }

    private void CalibrationButton_LostTouchCapture(object sender, TouchEventArgs e)
    {
        StopCalibration(sender);
    }

    private void StartCalibration(object sender)
    {
        if (TryGetCalibrationContext(sender, out var viewModel, out var action))
        {
            viewModel.PressCalibration(action.Label);
        }
    }

    private void StopCalibration(object sender)
    {
        if (TryGetCalibrationContext(sender, out var viewModel, out var action))
        {
            viewModel.ReleaseCalibration(action.Label);
        }
    }

    private bool TryGetCalibrationContext(
        object sender,
        out SmokeDensitySettingsViewModel viewModel,
        out SmokeDensityCalibrationViewModel action)
    {
        viewModel = null!;
        action = null!;

        if (DataContext is not SmokeDensitySettingsViewModel smokeDensitySettingsViewModel
            || sender is not Button { DataContext: SmokeDensityCalibrationViewModel calibrationAction })
        {
            return false;
        }

        viewModel = smokeDensitySettingsViewModel;
        action = calibrationAction;
        return true;
    }

    private static void ReleaseMouseCapture(object sender)
    {
        if (sender is Button { IsMouseCaptured: true } button)
        {
            button.ReleaseMouseCapture();
        }
    }

    private static void ReleaseTouchCapture(object sender, TouchDevice touchDevice)
    {
        if (sender is Button button)
        {
            button.ReleaseTouchCapture(touchDevice);
        }
    }
}
