void OnTick(object sender, EventArgs e)
        {
            if (!loaded)
            {
                if (!Game.Player.CanControlCharacter || Game.IsLoading)
                {
                    return;
                }

                if (loadDelayTimer == null)
                {
                    loadDelayTimer = DateTime.Now.AddMilliseconds(Config.LoadStartDelay);
                }

                Decorators.DEntity = Game.Player.Character;

                if (loadDelayTimer < DateTime.Now || Decorators.ScriptHasLoadedOnce)
                {
                    if (Config.DisplayHelpText)
                    {
                        UI.ShowSubtitle("Loading Custom Radios...");
                    }

                    SetupRadio();
                    SetupEvents();

                    // Allow playing MP audio sounds and scenes
                    Function.Call(Hash.SET_AUDIO_FLAG, "LoadMPData", true);

                    RadioNativeFunctions.DashboardScaleform = new ScaleformHelper.Scaleform("dashboard", true);

                    if (!Decorators.ScriptHasLoadedOnce)
                    {
                        Decorators.Init(Game.Player.Character);
                    }

                    loaded = true;

                    if (Config.DisplayHelpText)
                    {
                        UI.ShowSubtitle("Custom Radios Loaded");
                    }

                    if (Config.CustomWheelAsDefault && WheelVars.RadioWheels.Count > 0)
                    {
                        lastRadioWasCustom     = true;
                        canResumeCustomStation = true;
                    }
                }

                return; // Return if loaded is still not true
            }

            if (WheelVars.RadioWheels.Count == 0)
            {
                return;
            }

            if (GTAFunction.HasCheatStringJustBeenEntered("radio_reload"))
            {
                Config.LoadINI();
                Config.UpdateWheelsVisuals();
                Config.ReloadStationINIs();
                Config.RescanForTracklists();
                UI.ShowSubtitle("Custom Radio INIs reloaded:\n- settings.ini\n- station.ini files\n- Scanned for tracklists");
                Wait(150);
            }

            if (VanillaOrCustomRadioWheelIsVisible())
            {
                if (GTAFunction.UsingGamepad() && Game.IsControlJustPressed(2, Config.GP_Toggle))
                {
                    HandleRadioWheelToggle();
                }

                if (lastRadioWasCustom)
                {
                    WheelVars.CurrentRadioWheel.Visible = true;
                }

                lastPlayedOnFoot = Game.Player.Character.IsInVehicle() ? false : true;
            }

            if (Game.IsControlJustReleased(2, GTA.Control.VehicleRadioWheel))
            {
                if (WheelVars.CurrentRadioWheel.Visible)
                {
                    WheelVars.CurrentRadioWheel.Visible = false;
                }
            }

            Wheel.ControlTransitions(Config.EnableWheelSlowmotion);
            WheelVars.RadioWheels.ForEach(w => w.ProcessSelectorWheel());
            HandleRadioWheelQueue();
            SoundFile.ManageSoundEngine();
            RadioStation.ManageStations();
            HandleRadioWheelExtraControls();
            HandleQueuedStationActions();
            HandleEnterExitVehicles();
            UpdateDashboardInfo();
            HandleGamePause();
            GeneralEvents.Update();
        }
        public void SetupRadio()
        {
            // Get folders in script's main folder "Custom Radio Stations"
            string[] wheelDirectories = Directory.GetDirectories(mainPath, "*", SearchOption.TopDirectoryOnly);

            foreach (var wheelDir in wheelDirectories)
            {
                Logger.Log("Loading " + wheelDir);

                Logger.Log("Checking if " + wheelDir + "\\settings.ini exists");

                var wheelIni = Config.LoadWheelINI(wheelDir);

                // Create wheel obj
                Wheel radioWheel = new Wheel("Radio Wheel", wheelDir, 0, 0, new System.Drawing.Size(wheelIni.iconX, wheelIni.iconY), 200, wheelIni.wheelRadius);

                // Get folders in script's main folder "Custom Radio Stations"
                string[] stationDirectories = Directory.GetDirectories(wheelDir, "*", SearchOption.TopDirectoryOnly);

                Logger.Log("Number of stations: " + stationDirectories.Count());

                // Specify file extensions to search for in the next step
                var extensions = new List <string> {
                    ".mp3", ".wav", ".flac", ".lnk"
                };

                // Keep count of the number of station folders with actual music files
                int populatedStationCount = 0;

                // Generate wheel categories for each folder, which will be our individual stations on the wheel
                foreach (var stationDir in stationDirectories)
                {
                    Logger.Log("Loading " + stationDir);

                    // Get all files that have the above-mentioned extensions.
                    var musicFilePaths = Directory.GetFiles(stationDir, "*.*", SearchOption.TopDirectoryOnly)
                                         .Where(x => extensions.Contains(Path.GetExtension(x)));

                    // Don't make a station out of an empty folder
                    if (musicFilePaths.Count() == 0)
                    {
                        Logger.Log("Skipping " + Path.GetFileName(stationDir) + " as there are no music files.");
                        continue;
                    }

                    // Increase count
                    populatedStationCount++;

                    WheelCategory stationCat = new WheelCategory(Path.GetFileName(stationDir));
                    radioWheel.AddCategory(stationCat);
                    WheelCategoryItem stationItem = new WheelCategoryItem(stationCat.Name);
                    stationCat.AddItem(stationItem);

                    RadioStation station = new RadioStation(stationCat, musicFilePaths);

                    // Add wheel category-station combo to a station list
                    StationWheelPair pair = new StationWheelPair(radioWheel, stationCat, station);
                    StationWheelPair.List.Add(pair);

                    // Get description
                    pair.LoadStationINI(Path.Combine(stationDir, "station.ini"));

                    radioWheel.OnCategoryChange += (sender, selectedCategory, selectedItem, wheelJustOpened) =>
                    {
                        // HandleRadioWheelToggle() handles what happens when the wheel is opened.
                        // So we will only use this anonymous method for when the station is actually changed.
                        //if (wheelJustOpened) return;

                        if (selectedCategory == stationCat)
                        {
                            // If there is no input for a short amount of time, set the selected station as next to play
                            ActionQueued = ActionOptions.PlayQueued;

                            RadioStation.NextQueuedStation = station;

                            // If radio is still being decided, add delay before station changes
                            SetActionDelay(Config.WheelActionDelay);

                            lastRadioWasCustom = true;
                        }
                    };

                    radioWheel.OnItemChange += (sender, selectedCategory, selectedItem, wheelJustOpened, goTo) =>
                    {
                        if (wheelJustOpened)
                        {
                            return;
                        }

                        if (radioWheel.Visible && radioWheel == WheelVars.CurrentRadioWheel && WheelVars.NextQueuedWheel == null)
                        {
                            if (goTo == GoTo.Next)
                            {
                                radioWheel.Visible        = false;
                                WheelVars.NextQueuedWheel = WheelVars.RadioWheels.GetNext(radioWheel);
                            }
                            else if (goTo == GoTo.Prev)
                            {
                                radioWheel.Visible        = false;
                                WheelVars.NextQueuedWheel = WheelVars.RadioWheels.GetPrevious(radioWheel);
                            }
                        }
                    };
                }

                if (populatedStationCount > 0)
                {
                    WheelVars.RadioWheels.Add(radioWheel);
                    radioWheel.Origin = new Vector2(0.5f, 0.45f);
                    radioWheel.SetCategoryBackgroundIcons(iconBgPath, Config.IconBG, Config.IconBgSizeMultiple, iconhighlightPath, Config.IconHL, Config.IconHlSizeMultiple);
                    radioWheel.CalculateCategoryPlacement();
                }

                Logger.Log(@"/\/\/\/\/\/\/\/\/\/\/\/\/\/\");
            }

            if (WheelVars.RadioWheels.Count > 0)
            {
                WheelVars.CurrentRadioWheel = WheelVars.RadioWheels[0];
            }
            else
            {
                UI.ShowSubtitle("No music found in Custom Radio Stations. " +
                                "Please add music and reload script with the INS key.");
                Logger.Log("ERROR: No music found in any station directory. Aborting script...");
                Tick -= OnTick;
            }
        }
 public StationWheelPair(SelectorWheel.Wheel wheel, SelectorWheel.WheelCategory category, RadioStation station)
 {
     Wheel    = wheel;
     Category = category;
     Station  = station;
 }