﻿/*
 * Rainbow Neon
 * Author: libertylocked
 * Version: 0.11
 */
using System;
using System.Drawing;
using System.Windows.Forms;
using GTA;
using GTA.Native;

namespace GTAVMod_NeonColorChanger
{
    public class RainbowNeon : Script
    {
        // You can change the tick interval if you want to adjust transition speed
        const int TICK_INTERVAL = 50;

        int huePercent = 0;
        int mult = 1;

        public RainbowNeon()
        {
            this.Interval = TICK_INTERVAL;
            this.Tick += OnTick;
        }

        void OnTick(object sender, EventArgs e)
        {
            Player player = Game.Player;
            if (player != null && player.CanControlCharacter && player.IsAlive
                && player.Character != null && player.Character.IsInVehicle())
            {
                // Increment hue
                huePercent += 1 * mult;
                if (huePercent >= 99 || huePercent <= 0) mult *= -1;

                SetNeonColor(player.Character.CurrentVehicle, HSL2RGB((double)huePercent / 100, 0.5, 0.5));
            }
        }

        void SetNeonColor(Vehicle vehicle, Color color)
        {
            // void _SET_VEHICLE_NEON_LIGHTS_COLOUR(Vehicle vehicleHandle, int r, int g, int b) // 0x8E0A582209A62695
            //Function.Call(Hash._0x8E0A582209A62695, vehicle, color.R, color.G, color.B);
            vehicle.NeonLightsColor = color;
        }

        // Given H,S,L in range of 0-1
        // Returns a Color (RGB struct) in range of 0-255
        public static Color HSL2RGB(double h, double sl, double l)
        {
            double v;
            double r, g, b;

            r = l;   // default to gray
            g = l;
            b = l;
            v = (l <= 0.5) ? (l * (1.0 + sl)) : (l + sl - l * sl);
            if (v > 0)
            {
                double m;
                double sv;
                int sextant;
                double fract, vsf, mid1, mid2;

                m = l + l - v;
                sv = (v - m) / v;
                h *= 6.0;
                sextant = (int)h;
                fract = h - sextant;
                vsf = v * sv * fract;
                mid1 = m + vsf;
                mid2 = v - vsf;
                switch (sextant)
                {
                    case 0:
                        r = v;
                        g = mid1;
                        b = m;
                        break;
                    case 1:
                        r = mid2;
                        g = v;
                        b = m;
                        break;
                    case 2:
                        r = m;
                        g = v;
                        b = mid1;
                        break;
                    case 3:
                        r = m;
                        g = mid2;
                        b = v;
                        break;
                    case 4:
                        r = mid1;
                        g = m;
                        b = v;
                        break;
                    case 5:
                        r = v;
                        g = m;
                        b = mid2;
                        break;
                }
            }
            int colorR = Math.Min(Convert.ToInt32(r * 255.0f), 255);
            int colorG = Math.Min(Convert.ToInt32(g * 255.0f), 255);
            int colorB = Math.Min(Convert.ToInt32(b * 255.0f), 255);
            return Color.FromArgb(colorR, colorG, colorB);
        }
    }
}
