bl_info = {
    "name": "F1 Track Data Editor",
    "author": "AlonsoBeast",
    "version": (1, 0),
    "blender": (3, 3, 0),
    "location": "View3D > Sidebar > F1 Track Builder Toolkit",
    "description": "Make prepare data to import in database file",
    "category": "3D View",
}

import bpy
import xml.etree.ElementTree as ET
from bpy_extras.io_utils import ExportHelper

# XML Data Reference Example
XML_DATA = '''
<root>
  <track>
    <additional_ground_clearance>0</additional_ground_clearance>
    <id>115</id>
    <license_package>0</license_package>
    <location_id>0</location_id>
    <name_string_id>baku</name_string_id>
    <nationality_id>75</nationality_id>
  </track>
  <track_car_handling>
    <AIDevTools>true</AIDevTools>
    <ID>32</ID>
    <Level>2</Level>
    <license_package>0</license_package>
    <Track>baku</Track>
  </track_car_handling>
  <track_fuel_distance>
    <fuel_usage_per_lap>2.11</fuel_usage_per_lap>
    <ID>31</ID>
    <l100percent>156.75</l100percent>
    <l10min>20</l10min>
    <l10percent>20</l10percent>
    <l12laps>20</l12laps>
    <l1lap>20</l1lap>
    <l20percent>19.01</l20percent>
    <l25percent>43.62</l25percent>
    <l30percent>45</l30percent>
    <l3laps>10.56</l3laps>
    <l40percent>56</l40percent>
    <l50percent>79.85</l50percent>
    <l5laps>14.79</l5laps>
    <l6laps>20</l6laps>
    <l75percent>106</l75percent>
    <l7laps>20</l7laps>
    <license_package>0</license_package>
    <track>baku</track>
  </track_fuel_distance>
  <track_model>
    <calender_glyph>24</calender_glyph>
    <calendar_glyph>24</calendar_glyph>
    <distance_to_first_corner>0</distance_to_first_corner>
    <downforce_level>2</downforce_level>
    <drs_double_detection>false</drs_double_detection>
    <easy_dry_lap_time_adjustment>0</easy_dry_lap_time_adjustment>
    <easy_wet_lap_time_adjustment>0</easy_wet_lap_time_adjustment>
    <every_track_achievement>false</every_track_achievement>
    <fe_index>0</fe_index>
    <file_string>baku</file_string>
    <final_lap_time_limit>110</final_lap_time_limit>
    <folder_string>circuits</folder_string>
    <fuel_tank_size>170</fuel_tank_size>
    <full_throttle_ratio>74</full_throttle_ratio>
    <gear_changes>48</gear_changes>
    <fullcareer_order>0</fullcareer_order>
    <mediumcareer_order>0</mediumcareer_order>
    <briefcareer_order>0</briefcareer_order>
    <seasonchallenge_order>0</seasonchallenge_order>
    <gp_mode_round_number>28</gp_mode_round_number>
    <hard_dry_lap_time_adjustment>0</hard_dry_lap_time_adjustment>
    <hard_wet_lap_time_adjustment>0</hard_wet_lap_time_adjustment>
    <id>224</id>
    <is_night_race>false</is_night_race>
    <lap_distance>2.71</lap_distance>
    <leaderboard_id>24</leaderboard_id>
    <length>0</length>
    <license_package>0</license_package>
    <local_audio_ambience>test</local_audio_ambience>
    <location>lng_track_location_baku</location>
    <long_event_name>lng_track_fixture_baku</long_event_name>
    <long_track_name>lng_track_long_name_baku</long_track_name>
    <main_career_round_number>0</main_career_round_number>
    <max_safety_car>3</max_safety_car>
    <medium_event_name>lng_track_loading_baku</medium_event_name>
    <minimap_dist_above>110</minimap_dist_above>
    <minimap_dist_behind>116</minimap_dist_behind>
    <minimap_file_string />
    <minimap_s1_icon_pos_x>-10</minimap_s1_icon_pos_x>
    <minimap_s1_icon_pos_y>1280</minimap_s1_icon_pos_y>
    <minimap_s2_icon_pos_x>-270</minimap_s2_icon_pos_x>
    <minimap_s2_icon_pos_y>260</minimap_s2_icon_pos_y>
    <minimap_s3_icon_pos_x>280</minimap_s3_icon_pos_x>
    <minimap_s3_icon_pos_y>17</minimap_s3_icon_pos_y>
    <minimap_sf_icon_pos_x>420</minimap_sf_icon_pos_x>
    <minimap_sf_icon_pos_y>1120</minimap_sf_icon_pos_y>
    <minimap_zoom>200</minimap_zoom>
    <name>lng_track_name_baku</name>
    <name_string_id>baku</name_string_id>
    <num_laps>51</num_laps>
    <number_of_turns>14</number_of_turns>
    <option_tyre>1</option_tyre>
    <p1_grip>0</p1_grip>
    <p2_grip>0.07912844</p2_grip>
    <p3_grip>0.1582569</p3_grip>
    <pit_lane_mirrored>true</pit_lane_mirrored>
    <pit_speed_limit_pq>16.667</pit_speed_limit_pq>
    <pit_speed_limit_race>27.778</pit_speed_limit_race>
    <pitstop_dry_race_time_cost>13.933</pitstop_dry_race_time_cost>
    <pitstop_wet_race_time_cost>14.72</pitstop_wet_race_time_cost>
    <prime_tyre>3</prime_tyre>
    <q1_grip>0.2110092</q1_grip>
    <q2_grip>0.2599388</q2_grip>
    <q3_grip>0.3088685</q3_grip>
    <race_fixture_name>lng_track_fixture_baku</race_fixture_name>
    <race_grip>0.3577982</race_grip>
    <route_string>route_0</route_string>
    <safety_car_chance>0.75</safety_car_chance>
    <seasonchallenge_weather>0</seasonchallenge_weather>
    <short_career_round_number>0</short_career_round_number>
    <short_career_weather>1</short_career_weather>
    <short_event_name>lng_track_loading_country_caps_baku</short_event_name>
    <short_pit_lane>false</short_pit_lane>
    <short_track_name>lng_track_location_baku</short_track_name>
    <show_in_track_select_menu>true</show_in_track_select_menu>
    <skipfe_track>false</skipfe_track>
    <stat_average_lap_time>79</stat_average_lap_time>
    <stat_brake_wear_level>2</stat_brake_wear_level>
    <stat_downforce_level>2</stat_downforce_level>
    <supports_time_of_day>false</supports_time_of_day>
    <swap_for_dummy>false</swap_for_dummy>
    <top_speed>199</top_speed>
    <track_description>lng_track_desc_baku</track_description>
    <track_id>115</track_id>
    <track_id_dev_string>baku</track_id_dev_string>
    <track_lights_on>false</track_lights_on>
    <tt_grip>0.3088685</tt_grip>
    <tyre_wear_level>2</tyre_wear_level>
    <upgrade_high_downforce>false</upgrade_high_downforce>
    <season>2014</season>
    <difficulty>3</difficulty>
  </track_model> 
  <track_difficulties>
    <easy>0.3</easy>
    <expert>1</expert>
    <hard>0.85</hard>
    <ID>26</ID>
    <license_package>0</license_package>
    <medium>0.533333</medium>
    <track>114</track>
  </track_difficulties>
</root>
'''

def load_xml_data():
    tree = ET.ElementTree(ET.fromstring(XML_DATA))
    return tree.getroot()

def update_scene_properties(context):
    root = load_xml_data()

    context.scene.track_id = root.find('.//track/id').text
    context.scene.name_string_id = root.find('.//track/name_string_id').text
    context.scene.nationality_id = root.find('.//track/nationality_id').text
    context.scene.carhandling_id = root.find('.//track_car_handling/ID').text
    context.scene.carhandling_track = root.find('.//track_car_handling/Track').text  
    context.scene.fuel_id = root.find('.//track_fuel_distance/ID').text
    context.scene.model_id = root.find('.//track_model/id').text
    context.scene.model_leaderboard_id = root.find('.//track_model/leaderboard_id').text
    context.scene.model_calender_glyph = root.find('.//track_model/calender_glyph').text
    context.scene.model_calendar_glyph = root.find('.//track_model/calendar_glyph').text
    context.scene.difficulty_id = root.find('.//track_difficulties/ID').text
    context.scene.difficulty_track = root.find('.//track_difficulties/track').text
    context.scene.selected_season = root.find('.//track_model/season').text
    context.scene.track_name = root.find('.//track_car_handling/Track').text  

class F1TrackBuilderPanel(bpy.types.Panel):
    bl_label = "F1 Track Data Editor"
    bl_idname = "VIEW3D_PT_f1_track_builder"
    bl_space_type = 'VIEW_3D'
    bl_region_type = 'UI'
    bl_category = 'F1 Track DataEditor'

    def draw(self, context):
        layout = self.layout
        layout.label(text="Track Name (lowercase only):")
        row = layout.row(align=True)
        row.prop(context.scene, 'track_name', text="", icon='TEXT')

        row = layout.row()
        row.operator("f1trackbuilder.rename_track", text="Rename Track")

        layout.label(text="I signed a unique ID.")
        layout.label(text="Compare the ID with others tracks in Database Editor.")
        layout.label(text="Click Load Data Reference to show an example strings.")

        row = layout.row(align=True)
        row.prop(context.scene, 'track_id', text="Track ID Unique")
        row = layout.row(align=True)
        row.prop(context.scene, 'fuel_id', text="Fuel ID Unique")
        row = layout.row(align=True)
        row.prop(context.scene, 'model_id', text="Model ID Unique")
        row = layout.row(align=True)
        row.prop(context.scene, 'model_leaderboard_id', text="Model Leaderboard ID Unique")
        row = layout.row(align=True)
        row.prop(context.scene, 'model_calender_glyph', text="F1 2013 Calender Order - Unique")
        row = layout.row(align=True)
        row.prop(context.scene, 'model_calendar_glyph', text="Calendar Order Unique")
        row = layout.row(align=True)
        row.prop(context.scene, 'difficulty_id', text="Difficulty ID Unique")
        row = layout.row(align=True)
        row.prop(context.scene, 'difficulty_track', text="F1 2013 Difficulty Track Unique")
        row = layout.row(align=True)
        row.prop(context.scene, 'selected_season', text="Select Game (Any Number)")

        layout.operator("f1trackbuilder.update_props", text="Load Data Reference")
        layout.operator("f1trackbuilder.export_xml", text="Export Data Track XML")

class RenameTrackOperator(bpy.types.Operator):
    bl_idname = "f1trackbuilder.rename_track"
    bl_label = "Rename Track"

    def execute(self, context):
        old_name = "baku"  
        new_name = context.scene.track_name
        
        if not new_name.islower():
            self.report({'ERROR'}, "Track name must be in lowercase only!")
            return {'CANCELLED'}

        self.report({'INFO'}, f"Will replace '{old_name}' with '{new_name}' in the XML.")
        context.scene.track_name = new_name 

        return {'FINISHED'}

class UpdateScenePropertiesOperator(bpy.types.Operator):
    bl_idname = "f1trackbuilder.update_props"
    bl_label = "Update Scene Properties"

    def execute(self, context):
        update_scene_properties(context)
        self.report({'INFO'}, "Data was updated")
        return {'FINISHED'}

class ExportXML(bpy.types.Operator, ExportHelper):
    bl_idname = "f1trackbuilder.export_xml"
    bl_label = "Export XML"
    
    filename_ext = ".xml"
    filter_glob: bpy.props.StringProperty(
        default="*.xml",
        options={'HIDDEN'},
        maxlen=255,
    )

    def execute(self, context):
        # Загрузка XML из строки
        root = ET.fromstring(XML_DATA)

        # Замена имени трека и других идентификаторов
        for elem in root.iter():
            if elem.text:
                # Замена имени трека
                elem.text = elem.text.replace("baku", context.scene.track_name).replace("Baku", context.scene.track_name.capitalize())
                
                # Замена идентификаторов
                if elem.tag == "track":
                    id_elem = elem.find("id")
                    if id_elem is not None:
                        id_elem.text = context.scene.track_id
                    name_string_id_elem = elem.find("name_string_id")
                    if name_string_id_elem is not None:
                        name_string_id_elem.text = context.scene.name_string_id
                    nationality_id_elem = elem.find("nationality_id")
                    if nationality_id_elem is not None:
                        nationality_id_elem.text = context.scene.nationality_id
                elif elem.tag == "track_car_handling":
                    car_handling_id_elem = elem.find("ID")
                    if car_handling_id_elem is not None:
                        car_handling_id_elem.text = context.scene.carhandling_id
                    track_elem = elem.find("Track")
                    if track_elem is not None:
                        track_elem.text = context.scene.carhandling_track
                elif elem.tag == "track_fuel_distance":
                    id_elem = elem.find("ID")
                    if id_elem is not None:
                        id_elem.text = context.scene.fuel_id
                elif elem.tag == "track_model":
                    id_elem = elem.find("id")
                    if id_elem is not None:
                        id_elem.text = context.scene.model_id
                    leaderboard_id_elem = elem.find("leaderboard_id")
                    if leaderboard_id_elem is not None:
                        leaderboard_id_elem.text = context.scene.model_leaderboard_id
                elif elem.tag == "track_difficulties":
                    id_elem = elem.find("ID")
                    if id_elem is not None:
                        id_elem.text = context.scene.difficulty_id
                    track_elem = elem.find("track")
                    if track_elem is not None:
                        track_elem.text = context.scene.difficulty_track

                # Замена значений из track_model
                if elem.tag == "track_model":
                    season_elem = elem.find("season")
                    if season_elem is not None:
                        season_elem.text = context.scene.selected_season

        # Экспорт измененного XML
        tree = ET.ElementTree(root)
        tree.write(self.filepath, encoding='utf-8', xml_declaration=True)

        self.report({'INFO'}, f"Save as {self.filepath}")
        return {'FINISHED'}

def register():
    bpy.utils.register_class(F1TrackBuilderPanel)
    bpy.utils.register_class(UpdateScenePropertiesOperator)
    bpy.utils.register_class(ExportXML)
    bpy.utils.register_class(RenameTrackOperator)

    bpy.types.Scene.track_id = bpy.props.StringProperty(name="Track ID Unique")
    bpy.types.Scene.name_string_id = bpy.props.StringProperty(name="Name String ID")
    bpy.types.Scene.nationality_id = bpy.props.StringProperty(name="Nationality ID")
    bpy.types.Scene.carhandling_id = bpy.props.StringProperty(name="Car Handling ID")
    bpy.types.Scene.carhandling_track = bpy.props.StringProperty(name="Car Handling Track")  
    bpy.types.Scene.fuel_id = bpy.props.StringProperty(name="Fuel ID Unique")
    bpy.types.Scene.model_id = bpy.props.StringProperty(name="Model ID Unique")
    bpy.types.Scene.model_leaderboard_id = bpy.props.StringProperty(name="Model Leaderboard ID Unique")
    bpy.types.Scene.model_calender_glyph = bpy.props.StringProperty(name="F1 2013 Calender Order - Unique")
    bpy.types.Scene.model_calendar_glyph = bpy.props.StringProperty(name="Calendar Order Unique")
    bpy.types.Scene.difficulty_id = bpy.props.StringProperty(name="Difficulty ID Unique")
    bpy.types.Scene.difficulty_track = bpy.props.StringProperty(name="Difficulty Track Unique")
    bpy.types.Scene.selected_season = bpy.props.StringProperty(name="Select Game (Any Number)")
    
    bpy.types.Scene.track_name = bpy.props.StringProperty(
        name="Track Name",
        description="Enter the new track name (lowercase only)",
        default="baku"  
    )

def unregister():
    bpy.utils.unregister_class(F1TrackBuilderPanel)
    bpy.utils.unregister_class(UpdateScenePropertiesOperator)
    bpy.utils.unregister_class(ExportXML)
    bpy.utils.unregister_class(RenameTrackOperator)

    del bpy.types.Scene.track_id
    del bpy.types.Scene.name_string_id
    del bpy.types.Scene.nationality_id
    del bpy.types.Scene.carhandling_id
    del bpy.types.Scene.carhandling_track  
    del bpy.types.Scene.fuel_id
    del bpy.types.Scene.model_id
    del bpy.types.Scene.model_leaderboard_id
    del bpy.types.Scene.model_calender_glyph
    del bpy.types.Scene.model_calendar_glyph
    del bpy.types.Scene.difficulty_id
    del bpy.types.Scene.difficulty_track
    del bpy.types.Scene.selected_season
    del bpy.types.Scene.track_name

if __name__ == "__main__":
    register()