using System;
using System.Diagnostics;
using System.Windows;
using System.Windows.Input;
using System.Windows.Threading;
using System.Collections.Generic;

namespace PerformanceCounterDemo
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        // Performance monitoring counter values
        private int clickCountPerSec = 0;
        private int mouseMoveCountPerSec = 0;

        private PerformanceCounter performanceCounterButtonClicks;
        private PerformanceCounter performanceCounterButtonClicksPerSec;
        private PerformanceCounter performanceCounterMouseMoveEvents;
        private PerformanceCounter performanceCounterMouseMoveEventsPerSec;



        private const string perfomanceCounterCategoryName = "Wrox Performance Counters";
        private string instanceName = "PerformanceCounterDemo";
        private SortedList<string, Tuple<string, string>> perfCountNames;

        private DispatcherTimer timer;


        public MainWindow()
        {
            InitializeComponent();
            InitializePerfomanceCountNames();
            InitializePerformanceCounts();
            if (PerformanceCounterCategory.Exists(perfomanceCounterCategoryName))
            {
                buttonCount.IsEnabled = true;
                timer = new DispatcherTimer(TimeSpan.FromSeconds(1),
                    DispatcherPriority.Background,
                    delegate
                    {
                        this.performanceCounterButtonClicksPerSec.RawValue = this.clickCountPerSec;
                        this.clickCountPerSec = 0;
                        this.performanceCounterMouseMoveEventsPerSec.RawValue = this.mouseMoveCountPerSec;
                        this.mouseMoveCountPerSec = 0;
                    },
                    Dispatcher.CurrentDispatcher);
                timer.Start();
            }
        }

        private void InitializePerfomanceCountNames()
        {
            perfCountNames = new SortedList<string, Tuple<string, string>>();
            perfCountNames.Add("clickCount", Tuple.Create("# of button Clicks", "Total # of button clicks"));
            perfCountNames.Add("clickSec", Tuple.Create("# of button clicks/sec", "# of mouse button clicks in one second"));
            perfCountNames.Add("mouseCount", Tuple.Create("# of mouse move events", "Total # of mouse move events"));
            perfCountNames.Add("mouseSec", Tuple.Create("# of mouse move events/sec", "# of mouse move events in one second"));
        }

        private void InitializePerformanceCounts()
        {
            performanceCounterButtonClicks = new PerformanceCounter
            {
                CategoryName = perfomanceCounterCategoryName,
                CounterName = perfCountNames["clickCount"].Item1,
                ReadOnly = false,
                MachineName = ".",
                InstanceLifetime = PerformanceCounterInstanceLifetime.Process,
                InstanceName = this.instanceName
            };
            performanceCounterButtonClicksPerSec = new PerformanceCounter
            {
                CategoryName = perfomanceCounterCategoryName,
                CounterName = perfCountNames["clickSec"].Item1,
                ReadOnly = false,
                MachineName = ".",
                InstanceLifetime = PerformanceCounterInstanceLifetime.Process,
                InstanceName = this.instanceName
            };
            performanceCounterMouseMoveEvents = new PerformanceCounter
            {
                CategoryName = perfomanceCounterCategoryName,
                CounterName =  perfCountNames["mouseCount"].Item1,
                ReadOnly = false,
                MachineName = ".",
                InstanceLifetime = PerformanceCounterInstanceLifetime.Process,
                InstanceName = this.instanceName
            };
            performanceCounterMouseMoveEventsPerSec = new PerformanceCounter
            {
                CategoryName = perfomanceCounterCategoryName,
                CounterName =  perfCountNames["mouseSec"].Item1,
                ReadOnly = false,
                MachineName = ".",
                InstanceLifetime = PerformanceCounterInstanceLifetime.Process,
                InstanceName = this.instanceName
            };
        }

        private void OnButtonClick(object sender, RoutedEventArgs e)
        {
            this.performanceCounterButtonClicks.Increment();
            this.clickCountPerSec++;
        }

        private void OnMouseMove(object sender, MouseEventArgs e)
        {
            
            this.performanceCounterMouseMoveEvents.Increment();
            this.mouseMoveCountPerSec++;
        }

        private void OnRegisterCounts(object sender, RoutedEventArgs e)
        {
            if (!PerformanceCounterCategory.Exists(perfomanceCounterCategoryName))
            {

                var counterCreationData = new CounterCreationData[4];
                counterCreationData[0] = new CounterCreationData
                {
                    CounterName = perfCountNames["clickCount"].Item1,
                    CounterType = PerformanceCounterType.NumberOfItems32,
                    CounterHelp = perfCountNames["clickCount"].Item2
                };
                counterCreationData[1] = new CounterCreationData
                {
                    CounterName = perfCountNames["clickSec"].Item1,
                    CounterType = PerformanceCounterType.RateOfCountsPerSecond32,
                    CounterHelp = perfCountNames["clickSec"].Item2,
                };
                counterCreationData[2] = new CounterCreationData
                {
                    CounterName = perfCountNames["mouseCount"].Item1,
                    CounterType = PerformanceCounterType.NumberOfItems32,
                    CounterHelp = perfCountNames["mouseCount"].Item2,
                };
                counterCreationData[3] = new CounterCreationData
                {
                    CounterName = perfCountNames["mouseSec"].Item1,
                    CounterType = PerformanceCounterType.RateOfCountsPerSecond32,
                    CounterHelp = perfCountNames["mouseSec"].Item2,
                };
                var counters =
                    new CounterCreationDataCollection(counterCreationData);

                var category = PerformanceCounterCategory.Create(perfomanceCounterCategoryName,
                    "Sample Counters for Professional C#",
                    PerformanceCounterCategoryType.MultiInstance,
                    counters);

                MessageBox.Show(String.Format("category {0} successfully created", category.CategoryName));

            }

        }
    }
}
