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

namespace TerraTech {
    [HarmonyPatch]
    public class GeneratorPropertiesManager {
        private static Dictionary<ModuleEnergy, float> generators = new Dictionary<ModuleEnergy, float>();

        [HarmonyPrefix]
        [HarmonyPatch(typeof(ModuleEnergy), "OnAttached")]
        static void PostfixCreate(ModuleEnergy __instance) {
            // Console.WriteLine("ModuleEnergy.OnAttached");
            if (!generators.ContainsKey(__instance)) {
                generators.Add(__instance, GetValue(__instance));
                // Console.WriteLine("Patching {0}; m_OutputPerSecond: {1}", __instance.name, GetValue(__instance));
                DoPatchSingle(__instance);
                // Console.WriteLine("Patched {0}; m_OutputPerSecond: {1}", __instance.name, GetValue(__instance));
            }
        }

        [HarmonyPrefix]
        [HarmonyPatch(typeof(ModuleEnergy), "OnDetaching")]
        static void PostfixDestroy(ModuleEnergy __instance) {
            // Console.WriteLine("ModuleEnergy.OnDetaching");
            // Console.WriteLine("Restoring {0}; m_OutputPerSecond: {1}", __instance.name, GetValue(__instance));
            DoRestoreSingle(__instance);
            // Console.WriteLine("Restored {0}; m_OutputPerSecond: {1}", __instance.name, GetValue(__instance));
            generators.Remove(__instance);
        }

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

        static void DoPatchSingle(ModuleEnergy moduleEnergy) {
            SetValue(moduleEnergy, generators[moduleEnergy] * Main.energyGenMultiplier.Value);
        }

        static void DoRestoreSingle(ModuleEnergy moduleEnergy) {
            if (generators.ContainsKey(moduleEnergy)) {
                SetValue(moduleEnergy, generators[moduleEnergy]);
            }
        }

        private static float GetValue(ModuleEnergy moduleEnergy) {
            return Traverse.Create(moduleEnergy).Field("m_OutputPerSecond").GetValue() as float? ?? 0f;
        }

        private static void SetValue(ModuleEnergy moduleEnergy, float value) {
            Traverse.Create(moduleEnergy).Field("m_OutputPerSecond").SetValue(value);
        }
    }
}