using GTA; // This is a reference that is needed! do not edit this
using GTA.Math;
using GTA.Native; // This is a reference that is needed! do not edit this
using System; // This is a reference that is needed! do not edit this
using System.Windows.Forms; // This is a reference that is needed! do not edit this
using System.IO;

namespace TwoWheelDriving
{
    public class TwoWheelDriving : Script // declare Modname as a script
    {
        //Two Wheel Driving / Weight Shifting 1.3

        Keys ModToggleKey1 = Keys.ControlKey;
        Keys ModToggleKey2 = Keys.C;

        bool ModToggle = true;
        bool LeftWeightShift;
        bool RightWeightShift;
        float LeftWeightDegrees;
        float RightWeightDegrees;
        float WheelieDegrees;
        bool DoWheelie;
        float Speed;
        //float Pitch;
        Vector3 PitchWheelie;
        float Roll;
        Vector3 Rotation;
        Vector3 Roll2;
        float HeightAboveGround;
        float HydraulicSpeed = 2.5f;
        float TurningRadius = 0.5f;
        float TurningRadius2 = 4.0f;

        public TwoWheelDriving() // main function
        {
            Tick += OnTick;
            KeyDown += OnKeyDown;
            KeyUp += OnKeyUp;
            INISettings();
        }

        void INISettings()
        {
            ScriptSettings config = ScriptSettings.Load(@"scripts\TwoWheelDriving.ini");

            ModToggleKey1 = config.GetValue<Keys>("Mod Toggle", "Mod Toggle Key 1", Keys.ControlKey);
            ModToggleKey2 = config.GetValue<Keys>("Mod Toggle", "Mod Toggle Key 2", Keys.C);
            ModToggle = config.GetValue<bool>("Mod Toggle", "Mod ON by default?", true);

            HydraulicSpeed = config.GetValue<float>("Settings", "Hydraulic Speed", 2.5f);
            TurningRadius = config.GetValue<float>("Settings", "Normal Turning Radius", 0.5f);
            TurningRadius2 = config.GetValue<float>("Settings", "Turning Radius when Handbraking", 4.0f);
        }

        void OnTick(object sender, EventArgs e) // This is where most of your script goes
        {
            if (Game.IsKeyPressed(ModToggleKey2))
            {
                INISettings();
                if (!Game.IsKeyPressed(ModToggleKey1))
                {
                    UI.Notify("Two Wheel Driving Settings ~g~reloaded");
                }
                if (Game.IsKeyPressed(ModToggleKey1))
                {
                    if (ModToggle)
                    {
                        ModToggle = false;
                        Function.Call(Hash._SET_NOTIFICATION_TEXT_ENTRY, "STRING");
                        Function.Call(Hash._ADD_TEXT_COMPONENT_STRING, "Two Wheel Driving: ~r~Off");
                        Function.Call(Hash._DRAW_NOTIFICATION, 0, 0);
                        Wait(200);
                    }
                    else if (!ModToggle)
                    {
                        ModToggle = true;
                        Function.Call(Hash._SET_NOTIFICATION_TEXT_ENTRY, "STRING");
                        Function.Call(Hash._ADD_TEXT_COMPONENT_STRING, "Two Wheel Driving: ~g~On");
                        Function.Call(Hash._DRAW_NOTIFICATION, 0, 0);
                        Wait(200);
                    }
                }
            }
            if (Game.Player.Character.IsSittingInVehicle() && ModToggle) //If the player is in any vehicle
            {
                Vehicle veh = Game.Player.Character.CurrentVehicle;
                Vector3 VehVelocity = veh.Velocity;
                Vector3 vehDirection = veh.ForwardVector;
                //Pitch = Function.Call<float>(Hash.GET_ENTITY_PITCH, veh);
                Rotation = Function.Call<Vector3>(Hash.GET_ENTITY_ROTATION, veh, 2);
                bool UsingKeyboard = Function.Call<bool>(Hash._GET_LAST_INPUT_METHOD, 2);
                float HeightAboveGround = Function.Call<float>(Hash.GET_ENTITY_HEIGHT_ABOVE_GROUND, veh);

                //UI.ShowSubtitle(Rotation.Y.ToString()); //show roll
                //Two Wheel and Wheelie section
                if (Game.IsControlPressed(2, GTA.Control.VehicleAccelerate))
                {
                    if ((Game.IsControlPressed(2, GTA.Control.VehicleHandbrake) || Game.IsControlPressed(2, GTA.Control.PhoneSelect)) && HeightAboveGround < 3 && veh.Speed >= 7)
                    {
                        if (UsingKeyboard == false)
                        {
                            Game.DisableControl(2, GTA.Control.VehicleSelectNextWeapon);
                            Game.DisableControl(2, GTA.Control.VehicleCinCam);
                        }
                        if (UsingKeyboard == true)
                        {
                            Game.DisableControl(2, GTA.Control.VehicleRadioWheel);
                            Game.DisableControl(2, GTA.Control.VehicleHorn);
                        }

                        if (Game.IsControlJustPressed(2, GTA.Control.VehicleSelectNextWeapon) || (Game.IsControlJustPressed(2, GTA.Control.VehicleRadioWheel) && UsingKeyboard == true))
                        {
                            if (veh.ClassType != VehicleClass.Cycles && veh.ClassType != VehicleClass.Motorcycles && veh.ClassType != VehicleClass.Planes && veh.ClassType != VehicleClass.Helicopters && veh.ClassType != VehicleClass.Boats && veh.IsOnAllWheels)
                            {
                                Roll = Function.Call<float>(Hash.GET_ENTITY_ROLL, veh);
                                Roll2 = Function.Call<Vector3>(Hash.GET_ENTITY_ROTATION, veh, 2);
                                LeftWeightShift = true;
                                LeftWeightDegrees = Roll - 60.0f;
                                Speed = veh.Speed;
                            }
                            if (veh.ClassType == VehicleClass.Motorcycles)
                            {
                                PitchWheelie = Function.Call<Vector3>(Hash.GET_ENTITY_ROTATION, veh, 2);
                                DoWheelie = true;
                                WheelieDegrees = PitchWheelie.X + 20.0f;
                                Speed = veh.Speed;
                            }
                        }

                        if (Game.IsControlJustPressed(2, GTA.Control.VehicleCinCam) || (Game.IsControlJustPressed(2, GTA.Control.VehicleHorn) && UsingKeyboard == true))
                        {
                            if (veh.ClassType != VehicleClass.Cycles && veh.ClassType != VehicleClass.Motorcycles && veh.ClassType != VehicleClass.Planes && veh.ClassType != VehicleClass.Helicopters && veh.ClassType != VehicleClass.Boats && veh.IsOnAllWheels)
                            {
                                Roll = Function.Call<float>(Hash.GET_ENTITY_ROLL, veh);
                                Roll2 = Function.Call<Vector3>(Hash.GET_ENTITY_ROTATION, veh, 2);
                                RightWeightShift = true;
                                RightWeightDegrees = Roll + 60.0f;
                                Speed = veh.Speed;
                            }
                            if (veh.ClassType == VehicleClass.Motorcycles)
                            {
                                PitchWheelie = Function.Call<Vector3>(Hash.GET_ENTITY_ROTATION, veh, 2);
                                DoWheelie = true;
                                WheelieDegrees = PitchWheelie.X + 20.0f;
                                Speed = veh.Speed;
                            }
                        }
                    }

                    //Timers section
                    if (LeftWeightShift == true)
                    {
                        if (LeftWeightDegrees < Roll2.Y)
                        {
                            Function.Call(Hash.SET_ENTITY_ROTATION, veh, Rotation.X, Roll2.Y -= HydraulicSpeed, Rotation.Z, 2, 1);
                        }
                        else
                        {
                            Function.Call(Hash.SET_ENTITY_ROTATION, veh, Rotation.X, LeftWeightDegrees, Rotation.Z, 2, 1);
                        }
                    }

                    if (RightWeightShift == true)
                    {
                        if (RightWeightDegrees > Roll2.Y)
                        {
                            Function.Call(Hash.SET_ENTITY_ROTATION, veh, Rotation.X, Roll2.Y += HydraulicSpeed, Rotation.Z, 2, 1);
                        }
                        else
                        {
                            Function.Call(Hash.SET_ENTITY_ROTATION, veh, Rotation.X, RightWeightDegrees, Rotation.Z, 2, 1);
                        }
                    }

                    if (DoWheelie == true)
                    {
                        if (PitchWheelie.X < WheelieDegrees)
                        {
                            if (Rotation.Y > 0.0f)
                            {
                                Function.Call(Hash.SET_ENTITY_ROTATION, veh, PitchWheelie.X += 0.5f, Rotation.Y, Rotation.Z, 2, 1);
                            }
                            else
                            {
                                Function.Call(Hash.SET_ENTITY_ROTATION, veh, PitchWheelie.X += 0.5f, Rotation.Y, Rotation.Z, 2, 1);
                            }
                        }
                        else
                        {
                            Function.Call(Hash.SET_ENTITY_ROTATION, veh, WheelieDegrees, Rotation.Y, Rotation.Z, 2, 1);
                        }
                    }
                    //////Movement section
                    if (LeftWeightShift == true || RightWeightShift == true || DoWheelie == true)
                    {
                        if (veh.ClassType != VehicleClass.Cycles && veh.ClassType != VehicleClass.Motorcycles && veh.ClassType != VehicleClass.Commercial)
                        {
                            if (Game.IsControlPressed(2, GTA.Control.VehicleMoveLeftOnly))
                            {
                                if (HeightAboveGround < 1.75f)
                                {
                                    if (!Game.IsControlPressed(2, GTA.Control.VehicleHandbrake))
                                    {
                                        Function.Call(Hash.SET_ENTITY_ROTATION, veh, Rotation.X, Roll2.Y, Rotation.Z += TurningRadius, 2, 1);
                                        veh.Speed += 1;
                                        veh.Speed -= 1;
                                    }
                                    else if (Game.IsControlPressed(2, GTA.Control.VehicleHandbrake))
                                    {
                                        Function.Call(Hash.SET_ENTITY_ROTATION, veh, Rotation.X, Roll2.Y, Rotation.Z += TurningRadius2, 2, 1);
                                        veh.Speed += 1;
                                        veh.Speed -= 1;
                                    }
                                }
                            }
                            if (Game.IsControlPressed(2, GTA.Control.VehicleMoveRightOnly))
                            {
                                if (HeightAboveGround < 1.75f)
                                {
                                    if (!Game.IsControlPressed(2, GTA.Control.VehicleHandbrake))
                                    {
                                        Function.Call(Hash.SET_ENTITY_ROTATION, veh, Rotation.X, Roll2.Y, Rotation.Z -= TurningRadius, 2, 1);
                                        veh.Speed += 1;
                                        veh.Speed -= 1;
                                    }
                                    else if (Game.IsControlPressed(2, GTA.Control.VehicleHandbrake))
                                    {
                                        Function.Call(Hash.SET_ENTITY_ROTATION, veh, Rotation.X, Roll2.Y, Rotation.Z -= TurningRadius2, 2, 1);
                                        veh.Speed += 1;
                                        veh.Speed -= 1;
                                    }
                                }
                            }
                        }
                        if (veh.ClassType == VehicleClass.Motorcycles)
                        {
                            if (Game.IsControlPressed(2, GTA.Control.VehicleMoveLeftOnly))
                            {
                                Function.Call(Hash.SET_ENTITY_ROTATION, veh, PitchWheelie.X, Rotation.Y, Rotation.Z += 2, 2, 1);
                                veh.ApplyForce(veh.RightVector * -0.5f);
                            }
                            if (Game.IsControlPressed(2, GTA.Control.VehicleMoveRightOnly))
                            {
                                Function.Call(Hash.SET_ENTITY_ROTATION, veh, PitchWheelie.X, Rotation.Y, Rotation.Z -= 2, 2, 1);
                                veh.ApplyForce(veh.RightVector * +(0.5f));
                            }
                        }
                        if (Game.IsControlPressed(2, GTA.Control.VehicleMoveUpOnly))
                        {
                            veh.Speed += 0.2f;
                        }
                        if (HeightAboveGround >= 1.75)
                        {
                            LeftWeightShift = false;
                            RightWeightShift = false;
                            DoWheelie = false;
                        }
                    }
                    //UI.ShowSubtitle(Roll.ToString());
                }
                else
                {
                    LeftWeightShift = false;
                    RightWeightShift = false;
                    DoWheelie = false;
                }
                if ((veh.Speed < (Speed - 11)) || (veh.Speed < 7)) //Stop Weight Shifting if your speed slows down by 11 m/s (39 km/h, 24 Miles/hr), or if your speed is less than 7 m/s (25 km/h, 16 Miles/hr)
                {
                    LeftWeightShift = false;
                    RightWeightShift = false;
                    DoWheelie = false;
                }

                //Cycles section
                if (veh.ClassType == VehicleClass.Cycles)
                {
                    veh.MaxSpeed = 40;
                    if (Game.IsControlPressed(2, GTA.Control.VehicleMoveUpOnly) && veh.IsOnAllWheels)
                    {
                        veh.Speed += 0.2f;
                    }
                    if (Game.IsControlPressed(2, GTA.Control.VehicleMoveDownOnly) && Game.IsControlPressed(2, GTA.Control.VehicleBrake) && veh.IsOnAllWheels)
                    {
                        veh.ApplyForce(veh.ForwardVector * -1.0f);
                    }
                    if (veh.IsInAir)
                    {
                        veh.HasGravity = false;
                    }
                }
            }
        }
        //CurrentVelocity = veh.Velocity;
        //Heading = veh.Heading;
        //Pitch = Function.Call<float>(Hash.GET_ENTITY_PITCH, veh); //Pitch is rotation from front to back, Positive meaning the front goes upwards.
        //Roll = Function.Call<float>(Hash.GET_ENTITY_ROLL, veh); //Roll is the rotation from side to side.
        //Rotation = Function.Call<Vector3>(Hash.GET_ENTITY_ROTATION, veh, 2); //Rotation.Z is the yaw.
        //Function.Call(Hash.SET_ENTITY_ROTATION, veh, Pitch, Roll, Rotation.Z, 2, 1);
        //http://www.real3dtutorials.com/images/img00035.png
        void OnKeyDown(object sender, KeyEventArgs e)
        {
        }

        void OnKeyUp(object sender, KeyEventArgs e)
        {
        }
    }
}