using System;
using System.Collections.Generic;
using HarmonyLib;

namespace TerraTech {
    [HarmonyPatch]
    public class WheelPropertiesManager {
        private static Dictionary<ModuleWheels, float> torques = new Dictionary<ModuleWheels, float>();
        private static Dictionary<ModuleWheels, float> maxRpm = new Dictionary<ModuleWheels, float>();

        [HarmonyPrefix]
        [HarmonyPatch(typeof(ModuleWheels), "OnAttached")]
        static void PostfixCreate(ModuleWheels __instance) {
            // Console.WriteLine("ModuleWheels.OnAttached");
            if (!torques.ContainsKey(__instance)) {
                torques.Add(__instance, __instance.m_TorqueParams.torqueCurveMaxTorque);
                maxRpm.Add(__instance, __instance.m_TorqueParams.torqueCurveMaxRpm);
                // Console.WriteLine("Patching {0}; m_TorqueParams.torqueCurveMaxTorque: {1}; m_TorqueParams.torqueCurveMaxRpm: {2}", __instance.name,
                    // __instance.m_TorqueParams.torqueCurveMaxTorque,
                    // __instance.m_TorqueParams.torqueCurveMaxRpm);
                DoPatchSingle(__instance);
                // Console.WriteLine("Patched {0}; m_TorqueParams.torqueCurveMaxTorque: {1}; m_TorqueParams.torqueCurveMaxRpm: {2}", __instance.name,
                    // __instance.m_TorqueParams.torqueCurveMaxTorque,
                    // __instance.m_TorqueParams.torqueCurveMaxRpm);
            }
        }

        [HarmonyPrefix]
        [HarmonyPatch(typeof(ModuleWheels), "OnDetaching")]
        static void PostfixDestroy(ModuleWheels __instance) {
            // Console.WriteLine("ModuleWheels.OnDetaching");
            // Console.WriteLine("Restoring {0}; m_TorqueParams.torqueCurveMaxTorque: {1}; m_TorqueParams.torqueCurveMaxRpm: {2}", __instance.name,
                // __instance.m_TorqueParams.torqueCurveMaxTorque,
                // __instance.m_TorqueParams.torqueCurveMaxRpm);
            DoRestoreSingle(__instance);
            // Console.WriteLine("Restored {0}; m_TorqueParams.torqueCurveMaxTorque: {1}; m_TorqueParams.torqueCurveMaxRpm: {2}", __instance.name,
                // __instance.m_TorqueParams.torqueCurveMaxTorque,
                // __instance.m_TorqueParams.torqueCurveMaxRpm);
            torques.Remove(__instance);
            maxRpm.Remove(__instance);
        }

        public static void DoPatch() {
            // Console.WriteLine("Modifying {0} ModuleWheels", torques.Count);
            foreach (KeyValuePair<ModuleWheels, float> keyValuePair in torques) {
                DoRestoreSingle(keyValuePair.Key);
                DoPatchSingle(keyValuePair.Key);
            }
        }

        static void DoPatchSingle(ModuleWheels moduleWheels) {
            moduleWheels.m_TorqueParams.torqueCurveMaxRpm = maxRpm[moduleWheels] * Main.wheelSpeedMultiplier.Value;
            moduleWheels.m_TorqueParams.torqueCurveMaxTorque = torques[moduleWheels] * Main.wheelTorqueMultiplier.Value;
        }

        static void DoRestoreSingle(ModuleWheels moduleWheels) {
            if (torques.ContainsKey(moduleWheels)) {
                moduleWheels.m_TorqueParams.torqueCurveMaxTorque = torques[moduleWheels];
                moduleWheels.m_TorqueParams.torqueCurveMaxRpm = maxRpm[moduleWheels];
            }
        }
    }
}