using System;
using System.Windows.Forms;
using ComponentFramework;
using FullScreenShaders.Services;
using FullScreenShaders.Structure;

namespace FullScreenShaders.Forms
{
    partial class MainWindow : Form
    {
        ICore Core { get; set; }

        public MainWindow(ICore core)
        {
            InitializeComponent();
            Core = core;
        }

        void QuitButton_Click(object sender, EventArgs e)
        {
            Core.Exit();
        }

        void NoDownscaleChoice_CheckedChanged(object sender, EventArgs e)
        {
            SampleState.DownscaleFactor = 1;

            DownsamplingGroup.Enabled = !NoDownscaleChoice.Checked;
            InterpolationGroup.Enabled = !NoDownscaleChoice.Checked;
            KaiserGroup.Enabled = !NoDownscaleChoice.Checked && KaiserChoice.Checked;
        }
        void Downscale2xChoice_CheckedChanged(object sender, EventArgs e)
        {
            SampleState.DownscaleFactor = 2;
        }
        void Downscale4xChoice_CheckedChanged(object sender, EventArgs e)
        {
            SampleState.DownscaleFactor = 4;

            TentChoice.Enabled = Downscale4xChoice.Checked;
            if (!TentChoice.Enabled && TentChoice.Checked)
                BlitChoice.Checked = true;

            DoubleBlitChoice.Enabled = Downscale4xChoice.Checked;
            if (!DoubleBlitChoice.Enabled && DoubleBlitChoice.Checked)
                BlitChoice.Checked = true;
        }

        void HighPassCheck_CheckedChanged(object sender, EventArgs e)
        {
            SampleState.HighPass = HighPassCheck.Checked;
        }
        void GrayscaleCheck_CheckedChanged(object sender, EventArgs e)
        {
            SampleState.GrayScale = GrayscaleCheck.Checked;
        }
        void GaussBlurCheck_CheckedChanged(object sender, EventArgs e)
        {
            SampleState.GaussianBlur = GaussBlurCheck.Checked;
            GaussianGroup.Enabled = SampleState.GaussianBlur;
        }
        void VignetteCheck_CheckedChanged(object sender, EventArgs e)
        {
            SampleState.Vignette = VignetteCheck.Checked;
        }

        void DrawingTarget_MouseEnter(object sender, EventArgs e)
        {
            SampleState.MouseInViewport = true;
        }
        void DrawingTarget_MouseLeave(object sender, EventArgs e)
        {
            SampleState.MouseInViewport = false;
        }

        void RotationCheck_CheckedChanged(object sender, EventArgs e)
        {
            SampleState.Rotation = RotationCheck.Checked;
        }

        void BlitChoice_CheckedChanged(object sender, EventArgs e)
        {
            SampleState.DownsamplingMode = DownsamplingMode.Blit;
        }
        void DoubleBlitChoice_CheckedChanged(object sender, EventArgs e)
        {
            SampleState.DownsamplingMode = DownsamplingMode.DoubleBlit;
        }
        void TentChoice_CheckedChanged(object sender, EventArgs e)
        {
            SampleState.DownsamplingMode = DownsamplingMode.Tent;
        }
        void KaiserChoice_CheckedChanged(object sender, EventArgs e)
        {
            SampleState.DownsamplingMode = DownsamplingMode.Kaiser;
            KaiserGroup.Enabled = KaiserChoice.Checked;
        }
        void BicubicDownChoice_CheckedChanged(object sender, EventArgs e)
        {
            SampleState.DownsamplingMode = DownsamplingMode.Bicubic;
        }

        void Kaiser4TapChoice_CheckedChanged(object sender, EventArgs e)
        {
            SampleState.KaiserTaps = 4;
        }
        void Kaiser8TapChoice_CheckedChanged(object sender, EventArgs e)
        {
            SampleState.KaiserTaps = 8;
        }
        void Kaiser16TapChoice_CheckedChanged(object sender, EventArgs e)
        {
            SampleState.KaiserTaps = 16;
        }
        void Kaiser32TapChoice_CheckedChanged(object sender, EventArgs e)
        {
            SampleState.KaiserTaps = 32;
        }
        void Kaiser64TapChoice_CheckedChanged(object sender, EventArgs e)
        {
            SampleState.KaiserTaps = 64;
        }
        void Kaiser128TapChoice_CheckedChanged(object sender, EventArgs e)
        {
            SampleState.KaiserTaps = 128;
        }

        void FastGaussianCheck_CheckedChanged(object sender, EventArgs e)
        {
            SampleState.FastGaussian = FastGaussianCheck.Checked;
            GaussianTapChooser.Maximum = SampleState.FastGaussian ? 17 : 9;
        }

        void GaussianTapChooser_ValueChanged(object sender, EventArgs e)
        {
            if (GaussianTapChooser.Value % 2 == 0)
                GaussianTapChooser.Value--;

            SampleState.GaussianTaps = (int)GaussianTapChooser.Value;
            StandardDeviationChooser.Value = 50;
            UpdateStandardDeviation();
        }

        void StandardDeviationChooser_ValueChanged(object sender, EventArgs e)
        {
            UpdateStandardDeviation();
        }

        void UpdateStandardDeviation()
        {
            double ideal = GaussianKernel.IdealStandardDeviation(SampleState.GaussianTaps);
            double current = (StandardDeviationChooser.Value - 50) / 100.0;
            if (current > 0) current *= 5 * ideal * ideal;
            SampleState.GaussianStandardDeviation = ideal + current * ideal * 2;

            StandardDeviationLabel.Text = string.Format("Standard Deviation : {0:0.###}", SampleState.GaussianStandardDeviation);
            LostLightLabel.Text = string.Format("Lost Light : {0:##0.##%}, Box-Likeness : {1:##0.##%}", 
                Math.Max(GaussianKernel.LostLight(SampleState.GaussianTaps, SampleState.GaussianStandardDeviation), 0),
                GaussianKernel.BoxLikeness(SampleState.GaussianTaps, SampleState.GaussianStandardDeviation));
        }

        void NearestChoice_CheckedChanged(object sender, EventArgs e)
        {
            SampleState.InterpolationMode = InterpolationMode.Nearest;
        }
        void BilinearChoice_CheckedChanged(object sender, EventArgs e)
        {
            SampleState.InterpolationMode = InterpolationMode.Bilinear;
        }
        void BicubicChoice_CheckedChanged(object sender, EventArgs e)
        {
            SampleState.InterpolationMode = InterpolationMode.Bicubic;
        }

        void DrawingTarget_Click(object sender, EventArgs e)
        {
            DrawingTarget.Focus();
        }

        public ISampleState SampleState 
        {
            get { return Core.GetService<ISampleState>(); }
        }
    }
}