import os
from datetime import datetime

# ==============================================================================
# ROTOR GEOMETRY FIXED PARAMETERS
# ==============================================================================
ROTOR_RADIUS = 0.50       # meters (R)
ROTOR_HEIGHT = 0.50       # meters (H)
NUM_BLADES = 3            # (N)
PITCH_AXIS = 0.50000      # 50% of chord
NUM_STATIONS = 10         # Spanwise discretization points
POLAR_FILE = "Polars/NACA_0018_MultiRePolar.plr"

# ==============================================================================
# HIGH-DENSITY PARAMETRIC SEARCH GRID (25 x 16 = 400 Geometries)
# ==============================================================================
NUM_TWIST_STEPS = 25       # 0.0 to 120.0 deg (5.0 deg step)
NUM_SOLIDITY_STEPS = 16    # 0.15 to 0.45 (0.02 step)

TWIST_MIN, TWIST_MAX = 0.0, 120.0
SOLIDITY_MIN, SOLIDITY_MAX = 0.15, 0.45

# Generate linear steps
TWIST_ANGLES = [
    TWIST_MIN + i * (TWIST_MAX - TWIST_MIN) / (NUM_TWIST_STEPS - 1)
    for i in range(NUM_TWIST_STEPS)
]
SOLIDITIES = [
    SOLIDITY_MIN + i * (SOLIDITY_MAX - SOLIDITY_MIN) / (NUM_SOLIDITY_STEPS - 1)
    for i in range(NUM_SOLIDITY_STEPS)
]

# Output folder for generated .bld files
OUTPUT_DIR = "generated_blade_profiles_400"

def generate_bld_content(object_name: str, twist_deg: float, solidity: float) -> str:
    """Generates exact QBlade .bld file text structure for a given geometry."""
    
    # Calculate chord length: c = (sigma * R) / N
    chord = (solidity * ROTOR_RADIUS) / NUM_BLADES
    
    now = datetime.now()
    timestamp_str = now.strftime("%H:%M:%S")
    date_str = now.strftime("%d.%m.%Y")
    
    header = (
        "----------------------------------------QBlade Blade Definition File------------------------------------------------\n"
        "Generated with : QBlade CE Python Generator\n"
        "Archive Format: 310043\n"
        f"Time : {timestamp_str}\n"
        f"Date : {date_str}\n\n"
        "----------------------------------------Object Name-----------------------------------------------------------------\n"
        f"{object_name:<50} OBJECTNAME         - the name of the blade object\n\n"
        "----------------------------------------Parameters------------------------------------------------------------------\n"
        "VAWT                                               ROTORTYPE          - the rotor type\n"
        "false                                              INVERTEDFOILS      - invert the airfoils? (only VAWT) [bool]\n"
        f"{NUM_BLADES:<50} NUMBLADES          - number of blades\n\n"
        "----------------------------------------Blade Data------------------------------------------------------------------\n"
        "HEIGHT_[m]          CHORD_[m]           RADIUS_[m]          OFFSET_Y_[m]        TWIST_[deg]         CIRCANGLE_[deg]     P_AXIS_Y_[-]        POLAR_FILE          \n"
    )
    
    rows = []
    for i in range(NUM_STATIONS):
        height = i * (ROTOR_HEIGHT / (NUM_STATIONS - 1))
        circ_angle = (height / ROTOR_HEIGHT) * twist_deg if ROTOR_HEIGHT > 0 else 0.0
        
        row = (
            f"{height:<20.5f}"
            f"{chord:<20.5f}"
            f"{ROTOR_RADIUS:<20.5f}"
            f"{0.00000:<20.5f}"
            f"{0.00000:<20.5f}"
            f"{circ_angle:<20.2f}"
            f"{PITCH_AXIS:<20.5f}"
            f"{POLAR_FILE}"
        )
        rows.append(row)
        
    return header + "\n".join(rows) + "\n"

def main():
    os.makedirs(OUTPUT_DIR, exist_ok=True)
    total_files = len(TWIST_ANGLES) * len(SOLIDITIES)
    print(f"Generating {total_files} QBlade .bld files in '{OUTPUT_DIR}'...\n")
    
    count = 0
    for twist in TWIST_ANGLES:
        for sol in SOLIDITIES:
            sol_str = f"{int(round(sol * 1000)):03d}"
            twist_str = f"{int(round(twist))}"
            
            object_name = f"Helical_Twist{twist_str}_Sol{sol_str}"
            filename = f"{object_name}.bld"
            filepath = os.path.join(OUTPUT_DIR, filename)
            
            file_content = generate_bld_content(object_name, twist, sol)
            with open(filepath, "w") as f:
                f.write(file_content)
                
            calculated_chord = (sol * ROTOR_RADIUS) / NUM_BLADES
            print(f"[{count+1:03d}/{total_files}] Created: {filename:<32} | Chord: {calculated_chord*1000:.1f} mm | Twist: {twist:5.1f}° | Solidity: {sol:.4f}")
            count += 1
            
    print(f"\nExecution Complete! Successfully generated {count} .bld files.")

if __name__ == "__main__":
    main()