public static double SimpleLinearVal(WaveData low_betaWD, WaveData high_betaWD)
 {
     return((low_betaWD.NormalizedValue() + high_betaWD.NormalizedValue()) / 2.0);
 }
        static void Application_Idle(object sender, EventArgs e)
        {
            Stopwatch stopWatch           = new Stopwatch();
            double    currentAcceleration = 0;
            double    currentPosition     = 0;

            double maxAcceleration = 1;

            bool haveWon = false;

            while (true)
            {
                if (engine.EngineGetNumUser() > 0)
                {
                    engine.IEE_FFTSetWindowingType(0, EdkDll.IEE_WindowingTypes.IEE_HAMMING);
                }

                engine.ProcessEvents(100);

                WaveData alphaWD     = new WaveData("alpha");
                WaveData low_betaWD  = new WaveData("low_beta");
                WaveData high_betaWD = new WaveData("high_beta");
                WaveData gammaWD     = new WaveData("gamma");
                WaveData thetaWD     = new WaveData("theta");

                double[] alpha     = new double[1];
                double[] low_beta  = new double[1];
                double[] high_beta = new double[1];
                double[] gamma     = new double[1];
                double[] theta     = new double[1];

                EdkDll.IEE_DataChannel_t[] channelList = new EdkDll.IEE_DataChannel_t[5] {
                    EdkDll.IEE_DataChannel_t.IED_AF3, EdkDll.IEE_DataChannel_t.IED_AF4, EdkDll.IEE_DataChannel_t.IED_T7,
                    EdkDll.IEE_DataChannel_t.IED_T8, EdkDll.IEE_DataChannel_t.IED_O1
                };

                for (int i = 0; i < 5; i++)
                {
                    engine.IEE_GetAverageBandPowers(0, channelList[i], theta, alpha, low_beta, high_beta, gamma);
                    //Console.Write(theta[0] + ",");
                    //Console.Write(alpha[0] + ",");
                    //Console.Write(low_beta[0] + ",");
                    //Console.Write(high_beta[0] + ",");
                    //Console.WriteLine(gamma[0] + ",");

                    //Console.WriteLine("");

                    alphaWD.AddVal(alpha[0]);
                    low_betaWD.AddVal(low_beta[0]);
                    high_betaWD.AddVal(high_beta[0]);
                    gammaWD.AddVal(gamma[0]);
                    thetaWD.AddVal(theta[0]);
                }
                if (!stopWatch.IsRunning)
                {
                    stopWatch.Start();
                    Console.WriteLine("Starting stopwatch.");
                }
                else
                {
                    stopWatch.Stop();
                    long timeDeltaTicks = stopWatch.ElapsedTicks;


                    double accChange = AccelerationChange(alphaWD, low_betaWD, high_betaWD, thetaWD, gammaWD);
                    //Console.WriteLine("Acceleration change: " + accChange);

                    currentAcceleration = BindToMaxValue(currentAcceleration + accChange, maxAcceleration);
                    //double newPosition = currentPosition + 0.5 * currentAcceleration * timeDeltaTicks * timeDeltaTicks;
                    double newPosition = currentPosition + 0.5 * currentAcceleration; // Time is unitary

                    Console.WriteLine("CurrAcc: {0}, TimeDelta: {1}, NewPos: {2}",
                                      currentAcceleration, timeDeltaTicks, newPosition);

                    displayInputHandler.ApplyNewScaledValueForMeasure(Math.Log(Math.Abs(newPosition), 100));

                    if (newPosition > 1)
                    {
                        haveWon = true;


                        // END PROGRAM
                    }
                    else if (newPosition < 0)
                    {
                        currentPosition     = 0;
                        currentAcceleration = 0;
                    }
                    else
                    {
                        currentPosition = newPosition;
                    }

                    //double currentPosition = SimpleLinearVal(low_betaWD, high_betaWD);
                    Console.WriteLine(currentPosition);

                    if (!Double.IsNaN(currentPosition))
                    {
                        //Console.WriteLine("New position (formerly Awesome value):" + currentPosition);
                        displayInputHandler.ApplyNewScaledValueForBall(currentPosition);
                    }
                    stopWatch.Reset();
                    stopWatch.Start();
                }

                Application.DoEvents();

                if (haveWon)
                {
                    ThreadPool.QueueUserWorkItem(
                        delegate(object param)
                    {
                        WMPLib.WindowsMediaPlayer player = new WMPLib.WindowsMediaPlayer();
                        try
                        {
                            player.URL = "resources\\bell.mp3";
                        }
                        catch (Exception)
                        {
                            // Nada
                        }

                        player.controls.play();
                    });

                    Console.WriteLine("VICTORY!");
                    Thread.Sleep(3000);
                    exitGame();
                }
                Thread.Sleep(30);
            }
        }
        // Assumption: brain waves are equally likely to be of any power. Goal: keep return value of this function statistically between -1 and 1.
        // Method: tinker with
        public static double AccelerationChange(WaveData alphaWD, WaveData low_betaWD, WaveData high_betaWD, WaveData thetaWD, WaveData gammaWD)
        {
            Console.WriteLine("Waves: A: {0}, LB: {1}, HB: {2}, T: {3}, G: {4}", alphaWD.DecibelValue(), low_betaWD.DecibelValue(), high_betaWD.DecibelValue(), thetaWD.DecibelValue(), gammaWD.DecibelValue());
            double sum           = 0;
            double scalingFactor = 1;
            double gravity       = 0;

            double[] waveValues = new double[] { low_betaWD.DecibelValue(), high_betaWD.DecibelValue(), alphaWD.DecibelValue(), thetaWD.DecibelValue(), gammaWD.DecibelValue() };

            //// SUMS

            //double weightedSum = 1.0 * low_betaWD.NormalizedValue() + 1.0 * high_betaWD.NormalizedValue() + 0.5 * alphaWD.NormalizedValue() - 1.5 * thetaWD.NormalizedValue() - 0.5 * gammaWD.NormalizedValue();
            double mixedWeightedSum    = 1.0 * low_betaWD.DecibelValue() + 1.0 * high_betaWD.DecibelValue() + 0.5 * alphaWD.DecibelValue() - 1.5 * thetaWD.DecibelValue() - 0.5 * gammaWD.DecibelValue();
            double positiveWeightedSum = 1.0 * low_betaWD.DecibelValue() + 1.0 * high_betaWD.DecibelValue() + 0.5 * alphaWD.DecibelValue() + 0.5 * thetaWD.DecibelValue() + 0.5 * gammaWD.DecibelValue();
            double simpleSum           = waveValues.Sum();


            //// Scaling-used values

            double span    = waveValues.Max() - waveValues.Min();
            double average = waveValues.Average();


            //// Different scaling showcases, intended to be more consistent across the magnitude space

            // Span-inversely-proportional scaling
            //scalingFactor = 1 / span;

            // Magnitude-inversely-proportional scaling
            //scalingFactor = 1 / average;

            // Magnitude-complement-proportional scaling
            //scalingFactor = 1 - average;

            //// Packaged scalings

            // Best Relaxation Tailoring
            sum           = simpleSum;
            scalingFactor = 1 - average;
            gravity       = 1.2;


            return(sum * scalingFactor - gravity); // Alternatively, gravity could be subtracted from sum directly
        }