import java.io.*;
import java.util.*;
import java.util.regex.*;

public class ConfigParser {
    
    public static class YellowEffectDelayConfig {
        public boolean enabled = false;
        public String triggerCondition = "";
        public float hitSpread = 0.0f;
        public float hitDelay = 0.0f;
        public float trackHitDelay = 0.0f;
        public float hitExpand = 0.0f;
        public float expand = 0.0f;
        public float track = 0.0f;
        public float subtrack = 0.0f;
        public float effectDelay = 0.0f;
        public float effectRange = 0.0f;
        public float enemyEnhance = 0.0f;
        public float enemyProb = 0.0f;
        public float maxDistance = 0.0f;
        public float minDistance = 0.0f;
        public float triggerRate = 0.0f;
        public float triggerSpeed = 0.0f;
        public float hitProb = 0.0f;
        public float intensity = 0.0f;
    }
    
    public static class DynamicEffectDelayConfig {
        public float legDelay = 0.0f;
        public float armDelay = 0.0f;
        public float thirdpersonSideDelay = 0.0f;
        public float thirdpersonBackDelay = 0.0f;
        public float crouchDelay = 0.0f;
        public float jumpDelay = 0.0f;
        public float movingDelay = 0.0f;
        public float idleDelay = 0.0f;
        public float hitFeedbackDelay = 0.0f;
        public float recoilDelay = 0.0f;
        public float headshotDelay = 0.0f;
        public float penetrateDelay = 0.0f;
        public float multiHitDelay = 0.0f;
        public float ricochetDelay = 0.0f;
        public float longRangeDelay = 0.0f;
        public float closeRangeDelay = 0.0f;
    }
    
    public static class BoneDelayConfig {
        public float boneHitDelay = 0.0f;
        public float closeBoneHitDelay = 0.0f;
        public float farBoneHitDelay = 0.0f;
        public float boneTriggerRateDelay = 0.0f;
        public float boneHitDelay2 = 0.0f;
        public float boneYellowProbDelay = 0.0f;
        public float staticBoneYellowDelay = 0.0f;
        public float dynamicBoneYellowDelay = 0.0f;
        public float trackBoneYellowDelay = 0.0f;
        public float boneRangeYellowDelay = 0.0f;
        public float boneYellowEffectDelay = 0.0f;
        public float trackBoneYellowEffectDelay = 0.0f;
        public float subtrackBoneYellowDelay = 0.0f;
        public float boneYellowDelayProb = 0.0f;
        public float boneDoubleYellowDelay = 0.0f;
        public float boneYellowYellowDelay = 0.0f;
        public float boneYellowDelayTime = 0.0f;
        public float boneYellowDelayProb2 = 0.0f;
        public float boneYellowDelayTrigger = 0.0f;
        public float boneYellowMaxDistance = 0.0f;
        public float boneYellowMinDistance = 0.0f;
        public float boneEffectTriggerCond = 0.0f;
        public float boneEffectExplosion = 0.0f;
    }
    
    public static class EffectDelayConfig {
        public float hitYellowDelay = 0.0f;
        public float hitYellowDelayProb = 0.0f;
        public float hitYellowDelay2 = 0.0f;
        public float followTarget = 0.0f;
        public float effectDelay = 0.0f;
        public float characterEffectDelay = 0.0f;
    }
    
    public static class YellowEffectConfig {
        public float particleParams = 0.0f;
        public float highBrightnessSaturation = 0.0f;
        public float dynamicRadialBlur = 0.0f;
        public float impactEnhance = 0.0f;
        public float delayEffect = 0.0f;
        public float yellowEffectDelay = 0.0f;
    }
    
    public static class GameConfig {
        public YellowEffectDelayConfig yellowEffectDelay = new YellowEffectDelayConfig();
        public DynamicEffectDelayConfig dynamicEffect = new DynamicEffectDelayConfig();
        public BoneDelayConfig boneDelay = new BoneDelayConfig();
        public EffectDelayConfig effectDelay = new EffectDelayConfig();
        public YellowEffectConfig yellowEffect = new YellowEffectConfig();
    }
    
    private static final Pattern SECTION_PATTERN = Pattern.compile("\\[(.*?)\\]");
    private static final Pattern KEY_VALUE_PATTERN = Pattern.compile("([^=]+)=(.*)");
    private static final Pattern UNIT_PATTERN = Pattern.compile("([0-9.]+)([a-zA-Z]+)?");
    
    public static GameConfig loadConfig(String filename) throws IOException {
        GameConfig config = new GameConfig();
        BufferedReader reader = null;
        
        try {
            reader = new BufferedReader(new FileReader(filename));
            String line;
            String currentSection = "";
            
            while ((line = reader.readLine()) != null) {
                line = line.trim();
                
                if (line.isEmpty() || line.startsWith(";") || line.startsWith("#")) {
                    continue;
                }
                
                Matcher sectionMatcher = SECTION_PATTERN.matcher(line);
                if (sectionMatcher.matches()) {
                    currentSection = sectionMatcher.group(1).trim();
                    continue;
                }
                
                Matcher kvMatcher = KEY_VALUE_PATTERN.matcher(line);
                if (kvMatcher.matches()) {
                    String key = kvMatcher.group(1).trim();
                    String value = kvMatcher.group(2).trim();
                    
                    switch (currentSection) {
                        case "YellowEffectDelaySettings":
                            setYellowEffectDelayValue(config.yellowEffectDelay, key, value);
                            break;
                        case "DynamicEffectDelaySettings":
                            setDynamicEffectValue(config.dynamicEffect, key, value);
                            break;
                        case "BoneDelaySettings":
                            setBoneDelayValue(config.boneDelay, key, value);
                            break;
                        case "EffectDelaySettings":
                            setEffectDelayValue(config.effectDelay, key, value);
                            break;
                        case "YellowEffectSettings":
                            setYellowEffectValue(config.yellowEffect, key, value);
                            break;
                    }
                }
            }
        } finally {
            if (reader != null) {
                reader.close();
            }
        }
        
        return config;
    }
    
    private static float parseValue(String value) {
        if (value == null || value.isEmpty()) {
            return 0.0f;
        }
        
        Matcher matcher = UNIT_PATTERN.matcher(value);
        if (matcher.find()) {
            try {
                return Float.parseFloat(matcher.group(1));
            } catch (NumberFormatException e) {
                return 0.0f;
            }
        }
        
        try {
            return Float.parseFloat(value);
        } catch (NumberFormatException e) {
            return 0.0f;
        }
    }
    
    private static void setYellowEffectDelayValue(YellowEffectDelayConfig settings, String key, String value) {
        switch (key) {
            case "EffectDelay":
                settings.enabled = "Enabled".equals(value);
                break;
            case "TriggerCondition":
                settings.triggerCondition = value;
                break;
            case "HitSpread":
                settings.hitSpread = parseValue(value);
                break;
            case "HitDelay":
                settings.hitDelay = parseValue(value);
                break;
            case "TrackHitDelay":
                settings.trackHitDelay = parseValue(value);
                break;
            case "HitExpand":
                settings.hitExpand = parseValue(value);
                break;
            case "Expand":
                settings.expand = parseValue(value);
                break;
            case "Track":
                settings.track = parseValue(value);
                break;
            case "Subtrack":
                settings.subtrack = parseValue(value);
                break;
            case "EffectDelayValue":
                settings.effectDelay = parseValue(value);
                break;
            case "EffectRange":
                settings.effectRange = parseValue(value);
                break;
            case "EnemyEnhance":
                settings.enemyEnhance = parseValue(value);
                break;
            case "EnemyProb":
                settings.enemyProb = parseValue(value);
                break;
            case "MaxDistance":
                settings.maxDistance = parseValue(value);
                break;
            case "MinDistance":
                settings.minDistance = parseValue(value);
                break;
            case "TriggerRate":
                settings.triggerRate = parseValue(value);
                break;
            case "TriggerSpeed":
                settings.triggerSpeed = parseValue(value);
                break;
            case "HitProb":
                settings.hitProb = parseValue(value);
                break;
            case "Intensity":
                settings.intensity = parseValue(value);
                break;
        }
    }
    
    private static void setDynamicEffectValue(DynamicEffectDelayConfig settings, String key, String value) {
        switch (key) {
            case "LegDelay":
                settings.legDelay = parseValue(value);
                break;
            case "ArmDelay":
                settings.armDelay = parseValue(value);
                break;
            case "ThirdpersonSideDelay":
                settings.thirdpersonSideDelay = parseValue(value);
                break;
            case "ThirdpersonBackDelay":
                settings.thirdpersonBackDelay = parseValue(value);
                break;
            case "CrouchDelay":
                settings.crouchDelay = parseValue(value);
                break;
            case "JumpDelay":
                settings.jumpDelay = parseValue(value);
                break;
            case "MovingDelay":
                settings.movingDelay = parseValue(value);
                break;
            case "IdleDelay":
                settings.idleDelay = parseValue(value);
                break;
            case "HitFeedbackDelay":
                settings.hitFeedbackDelay = parseValue(value);
                break;
            case "RecoilDelay":
                settings.recoilDelay = parseValue(value);
                break;
            case "HeadshotDelay":
                settings.headshotDelay = parseValue(value);
                break;
            case "PenetrateDelay":
                settings.penetrateDelay = parseValue(value);
                break;
            case "MultiHitDelay":
                settings.multiHitDelay = parseValue(value);
                break;
            case "RicochetDelay":
                settings.ricochetDelay = parseValue(value);
                break;
            case "LongRangeDelay":
                settings.longRangeDelay = parseValue(value);
                break;
            case "CloseRangeDelay":
                settings.closeRangeDelay = parseValue(value);
                break;
        }
    }
    
    private static void setBoneDelayValue(BoneDelayConfig settings, String key, String value) {
        switch (key) {
            case "BoneHitDelay":
                if (settings.boneHitDelay == 0.0f) {
                    settings.boneHitDelay = parseValue(value);
                } else {
                    settings.boneHitDelay2 = parseValue(value);
                }
                break;
            case "CloseBoneHitDelay":
                settings.closeBoneHitDelay = parseValue(value);
                break;
            case "FarBoneHitDelay":
                settings.farBoneHitDelay = parseValue(value);
                break;
            case "BoneTriggerRateDelay":
                settings.boneTriggerRateDelay = parseValue(value);
                break;
            case "BoneYellowProbDelay":
                settings.boneYellowProbDelay = parseValue(value);
                break;
            case "StaticBoneYellowDelay":
                settings.staticBoneYellowDelay = parseValue(value);
                break;
            case "DynamicBoneYellowDelay":
                settings.dynamicBoneYellowDelay = parseValue(value);
                break;
            case "TrackBoneYellowDelay":
                settings.trackBoneYellowDelay = parseValue(value);
                break;
            case "BoneRangeYellowDelay":
                settings.boneRangeYellowDelay = parseValue(value);
                break;
            case "BoneYellowEffectDelay":
                settings.boneYellowEffectDelay = parseValue(value);
                break;
            case "TrackBoneYellowEffectDelay":
                settings.trackBoneYellowEffectDelay = parseValue(value);
                break;
            case "SubtrackBoneYellowDelay":
                settings.subtrackBoneYellowDelay = parseValue(value);
                break;
            case "BoneYellowDelayProb":
                if (settings.boneYellowDelayProb == 0.0f) {
                    settings.boneYellowDelayProb = parseValue(value);
                } else {
                    settings.boneYellowDelayProb2 = parseValue(value);
                }
                break;
            case "BoneDoubleYellowDelay":
                settings.boneDoubleYellowDelay = parseValue(value);
                break;
            case "BoneYellowYellowDelay":
                settings.boneYellowYellowDelay = parseValue(value);
                break;
            case "BoneYellowDelayTime":
                settings.boneYellowDelayTime = parseValue(value);
                break;
            case "BoneYellowDelayTrigger":
                settings.boneYellowDelayTrigger = parseValue(value);
                break;
            case "BoneYellowMaxDistance":
                settings.boneYellowMaxDistance = parseValue(value);
                break;
            case "BoneYellowMinDistance":
                settings.boneYellowMinDistance = parseValue(value);
                break;
            case "BoneEffectTriggerCond":
                settings.boneEffectTriggerCond = parseValue(value);
                break;
            case "BoneEffectExplosion":
                settings.boneEffectExplosion = parseValue(value);
                break;
        }
    }
    
    private static void setEffectDelayValue(EffectDelayConfig settings, String key, String value) {
        switch (key) {
            case "HitYellowDelay":
                if (settings.hitYellowDelay == 0.0f) {
                    settings.hitYellowDelay = parseValue(value);
                } else {
                    settings.hitYellowDelay2 = parseValue(value);
                }
                break;
            case "HitYellowDelayProb":
                settings.hitYellowDelayProb = parseValue(value);
                break;
            case "FollowTarget":
                settings.followTarget = parseValue(value);
                break;
            case "EffectDelay":
                settings.effectDelay = parseValue(value);
                break;
            case "CharacterEffectDelay":
                settings.characterEffectDelay = parseValue(value);
                break;
        }
    }
    
    private static void setYellowEffectValue(YellowEffectConfig settings, String key, String value) {
        switch (key) {
            case "ParticleParams":
                settings.particleParams = parseValue(value);
                break;
            case "HighBrightnessSaturation":
                settings.highBrightnessSaturation = parseValue(value);
                break;
            case "DynamicRadialBlur":
                settings.dynamicRadialBlur = parseValue(value);
                break;
            case "ImpactEnhance":
                settings.impactEnhance = parseValue(value);
                break;
            case "DelayEffect":
                settings.delayEffect = parseValue(value);
                break;
            case "YellowEffectDelay":
                settings.yellowEffectDelay = parseValue(value);
                break;
        }
    }
    
    public static void createConfigFile(String filename) throws IOException {
        try (PrintWriter writer = new PrintWriter(new FileWriter(filename))) {
            writer.println("[YellowEffectDelaySettings]");
            writer.println("EffectDelay=Enabled");
            writer.println("TriggerCondition=Fire");
            writer.println("HitSpread=999.0f");
            writer.println("HitDelay=999.0f");
            writer.println("TrackHitDelay=999.0f");
            writer.println("HitExpand=999.0 f");
            writer.println("Expand=999.0f");
            writer.println("Track=999.0f");
            writer.println("Subtrack=999.0f");
            writer.println("EffectDelayValue=999.0f");
            writer.println("EffectRange=999.0f");
            writer.println("EnemyEnhance=999.0f");
            writer.println("EnemyProb=999.0f");
            writer.println("MaxDistance=100m");
            writer.println("MinDistance=0m");
            writer.println("TriggerRate=999.0f");
            writer.println("TriggerSpeed=0s");
            writer.println("HitProb=999.0f");
            writer.println("Intensity=999.0f");
            writer.println();
            
            writer.println("[DynamicEffectDelaySettings]");
            writer.println("LegDelay=999.0f");
            writer.println("ArmDelay=999.0f");
            writer.println("ThirdpersonSideDelay=999.0f");
            writer.println("ThirdpersonBackDelay=999.0f");
            writer.println("CrouchDelay=999.0f");
            writer.println("JumpDelay=999.0f");
            writer.println("MovingDelay=999.0f");
            writer.println("IdleDelay=999.0f");
            writer.println("HitFeedbackDelay=999.0f");
            writer.println("RecoilDelay=999.0f");
            writer.println("HeadshotDelay=999.0f");
            writer.println("PenetrateDelay=999.0f");
            writer.println("MultiHitDelay=999.0f");
            writer.println("RicochetDelay=999.0f");
            writer.println("LongRangeDelay=999.0f");
            writer.println("CloseRangeDelay=999.0f");
            writer.println();
            
            writer.println("[BoneDelaySettings]");
            writer.println("BoneHitDelay=999.0f");
            writer.println("CloseBoneHitDelay=999.0f");
            writer.println("FarBoneHitDelay=999.0f");
            writer.println("BoneTriggerRateDelay=999.0f");
            writer.println("BoneHitDelay=999.0f");
            writer.println("BoneYellowProbDelay=999.0f");
            writer.println("StaticBoneYellowDelay=999.0f");
            writer.println("DynamicBoneYellowDelay=999.0f");
            writer.println("TrackBoneYellowDelay=999.00f");
            writer.println("BoneRangeYellowDelay=999.00f");
            writer.println("BoneYellowEffectDelay=999.00f");
            writer.println("TrackBoneYellowEffectDelay=999.00f");
            writer.println("SubtrackBoneYellowDelay=999.00f");
            writer.println("BoneYellowDelayProb=999.00f");
            writer.println("BoneDoubleYellowDelay=999.00f");
            writer.println("BoneYellowYellowDelay=999.0f");
            writer.println("BoneYellowDelayTime=0s");
            writer.println("BoneYellowDelayProb=999.0f");
            writer.println("BoneYellowDelayTrigger=999.00f");
            writer.println("BoneYellowMaxDistance=100m");
            writer.println("BoneYellowMinDistance=10m");
            writer.println("BoneEffectTriggerCond=999.0f");
            writer.println("BoneEffectExplosion=999.00f");
            writer.println();
            
            writer.println("[EffectDelaySettings]");
            writer.println("HitYellowDelay=999.0f");
            writer.println("HitYellowDelayProb=999.0f");
            writer.println("HitYellowDelay=999.0f");
            writer.println("FollowTarget=999.0f");
            writer.println("EffectDelay=999.0f");
            writer.println("CharacterEffectDelay=999.0f");
            writer.println();
            
            writer.println("[YellowEffectSettings]");
            writer.println("ParticleParams=999.0f");
            writer.println("HighBrightnessSaturation=999.0f");
            writer.println("DynamicRadialBlur=999.0f");
            writer.println("ImpactEnhance=999.0f");
            writer.println("DelayEffect=999.0f");
            writer.println("YellowEffectDelay=999.0f");
        }
    }
    
    public static void displayConfig(GameConfig config) {
        System.out.println("=== Game Configuration ===\n");
        
        System.out.println("[Yellow Effect Delay Settings]");
        System.out.println("Effect Delay: " + (config.yellowEffectDelay.enabled ? "Enabled" : "Disabled"));
        System.out.println("Trigger Condition: " + config.yellowEffectDelay.triggerCondition);
        System.out.println("Hit Spread: " + config.yellowEffectDelay.hitSpread);
        System.out.println("Hit Delay: " + config.yellowEffectDelay.hitDelay);
        System.out.println("Max Distance: " + config.yellowEffectDelay.maxDistance + "m");
        System.out.println("Min Distance: " + config.yellowEffectDelay.minDistance + "m");
        System.out.println();
        
        System.out.println("[Dynamic Effect Delay Settings]");
        System.out.println("Leg Delay: " + config.dynamicEffect.legDelay);
        System.out.println("Arm Delay: " + config.dynamicEffect.armDelay);
        System.out.println("Headshot Delay: " + config.dynamicEffect.headshotDelay);
        System.out.println();
        
        System.out.println("[Bone Delay Settings]");
        System.out.println("Bone Hit Delay: " + config.boneDelay.boneHitDelay);
        System.out.println("Close Bone Hit Delay: " + config.boneDelay.closeBoneHitDelay);
        System.out.println("Far Bone Hit Delay: " + config.boneDelay.farBoneHitDelay);
        System.out.println("Bone Yellow Max Distance: " + config.boneDelay.boneYellowMaxDistance + "m");
        System.out.println();
        
        System.out.println("[Effect Delay Settings]");
        System.out.println("Hit Yellow Delay: " + config.effectDelay.hitYellowDelay);
        System.out.println("Hit Yellow Delay Probability: " + config.effectDelay.hitYellowDelayProb);
        System.out.println();
        
        System.out.println("[Yellow Effect Settings]");
        System.out.println("Particle Parameters: " + config.yellowEffect.particleParams);
        System.out.println("Impact Enhancement: " + config.yellowEffect.impactEnhance);
        System.out.println("Yellow Effect Delay: " + config.yellowEffect.yellowEffectDelay);
    }
    
    public static void main(String[] args) {
        try {
            createConfigFile("game_config.ini");
            System.out.println("Configuration file created successfully!");
            
            GameConfig config = loadConfig("game_config.ini");
            System.out.println("Configuration loaded successfully!\n");
            
            displayConfig(config);
            
        } catch (IOException e) {
            System.err.println("File operation error: " + e.getMessage());
        }
    }
}