#scope_file
rotation : float = 0.0;
tilt     : float = 0.0;
zoom     : float = 3.0;

brush_radius   : int = 5;

roughness : u8 = 0;
metallic  : u8 = 0;
emittance : u8 = 0;

hovered_trixel_x : int = -1;
hovered_trixel_y : int = -1;
hovered_trixel_z : int = -1;


TRILE_ROTATION_SPEED :: 2.0;

Trile_Editor_Tab :: enum {
    TOOLSET;
    METADATA;
    MATERIAL;  
};

Trile_Editor_Tool :: enum {
    PAINT;
    ADD;
    REMOVE;
}

Trile_Editor_Tool_Mode :: enum {
    POINT;
    BRUSH;
    AREA;
}

current_tab  : Trile_Editor_Tab       = .TOOLSET;
current_tool : Trile_Editor_Tool      = .PAINT;
current_mode : Trile_Editor_Tool_Mode = .AREA;

colorMuls : [16][16][16]Vector3;
    
#scope_export

ntrile :: (name: string) {
    set_trile_gfx(editor_current_trile.name, generate_trile_gfx_matias(editor_current_trile));
    newt : Trile;
    newt.name = sprint("%", name);
    set_trile(newt.name, newt);
    editor_current_trile = get_trile(newt.name);
} @Command

cpytrile :: (trile: string, destination: string) {
    set_trile_gfx(editor_current_trile.name, generate_trile_gfx_matias(editor_current_trile));
    newt : Trile;
    newt.name = sprint("%", destination);
    newt.trixels = get_trile(trile).trixels;
    set_trile(newt.name, newt);
    editor_current_trile = get_trile(newt.name);
} @Command

ltrile :: (name: string) {
    set_trile_gfx(editor_current_trile.name, generate_trile_gfx_matias(editor_current_trile));
    nt := get_trile(name);
    if !nt {
        console_add_output_line("Failed to load a trile with that name...");
        return;    
    }
    editor_current_trile = nt;
} @Command

#scope_file

apply_tool_to_trixel :: (x: s64, y: s64, z: s64) {
    if current_tool == .PAINT {
        editor_current_trile.trixels[x][y][z].material.color = current_color;
        editor_current_trile.trixels[x][y][z].material.metallic = metallic;
        editor_current_trile.trixels[x][y][z].material.roughness = roughness;
        editor_current_trile.trixels[x][y][z].material.emittance = emittance;
    }
    if current_tool == .ADD {
        editor_current_trile.trixels[x][y][z].empty = false;
    }
    if current_tool == .REMOVE {
        editor_current_trile.trixels[x][y][z].empty = true;
    }
}

area_start_x : int;
area_start_y : int;
area_start_z : int;
area_active  : bool;

handle_tool_click :: () {
    if hovered_trixel_x < 0 && hovered_trixel_y < 0 && hovered_trixel_z < 0 then return;
    if current_mode == .POINT {
        apply_tool_to_trixel(hovered_trixel_x, hovered_trixel_y, hovered_trixel_z);
    }
    if current_mode == .BRUSH {
        is_in_radius :: (point : Vector3, radius: float) -> bool {
            center : Vector3 = .{xx hovered_trixel_x, xx hovered_trixel_y, xx hovered_trixel_z};
            return length(point - center) <= radius;
        }
    
        for x: 0..15 {
            for y: 0..15 {
                for z: 0..15 {
                    if is_in_radius(.{xx x, xx y, xx z}, xx brush_radius) {
                        apply_tool_to_trixel(x,y,z);
                    }
                }
            }
        }
    }
    if current_mode == .AREA {
        if area_active {
            // Apply tool to all trixels in the area.
            for x: min(area_start_x, hovered_trixel_x)..max(hovered_trixel_x, area_start_x) {
                for y: min(area_start_y, hovered_trixel_y)..max(hovered_trixel_y, area_start_y) {
                    for z: min(area_start_z, hovered_trixel_z)..max(hovered_trixel_z, area_start_z) {
                        apply_tool_to_trixel(x,y,z);
                    }
                }
            }
            area_active = false;
        } else {
            area_active = true;
            area_start_x = hovered_trixel_x;
            area_start_y = hovered_trixel_y;
            area_start_z = hovered_trixel_z;
        }
    }
    
}

#scope_export

current_color : Vector3 = .{1.0, 0.0, 0.0};

reset_trile :: () {
    newt : Trile;
    set_trile("test", newt);
    editor_current_trile = get_trile("test");
} @Command

tick_trile_editor :: () {
    if console_open_ignore_input then return;

    if !editor_current_trile then editor_current_trile = get_trile("test");

    if input_button_states[Key_Code.MOUSE_BUTTON_LEFT] & .START {
        handle_tool_click();
    }
    
    mindist : float = 999999;
    hovered_trixel_x = -1;
    hovered_trixel_y = -1;
    hovered_trixel_z = -1;

    for x: 0..15 {
        for y: 0..15 {
            for z: 0..15 {
                t := editor_current_trile.trixels[x][y][z];
                if t.empty then continue;

                cube : Collision_Cube;
                cube.position = Vector3.{cast(float) x, cast(float) y, cast(float) z} * TRIXEL_SIZE;
                cube.size     = Vector3.{1,1,1} * TRIXEL_SIZE;

                ray := get_mouse_ray(*get_trile_editor_camera());
                collision := does_ray_hit_cube(ray, cube);
                if collision.hit && collision.distance < mindist {
                    mindist = collision.distance;
                    hovered_trixel_x = x;
                    hovered_trixel_y = y;
                    hovered_trixel_z = z;
                }
            }
        }
    }

    for x: 0..15 {
        for y: 0..15 {
            for z: 0..15 {
                if x == hovered_trixel_x && y == hovered_trixel_y && z == hovered_trixel_z {
                    colorMuls[x][y][z] = .{0.6, 0.0, 0.0};
                } else {
                    colorMuls[x][y][z] = .{1.0, 1.0, 1.0};
                }
            }
        }
    }

    if !input_button_states[Key_Code.CTRL] & .DOWN {
        if input_button_states[#char "D"] & .DOWN {
            rotation += TRILE_ROTATION_SPEED * cast(float) delta_time;
        }
        if input_button_states[#char "A"] & .DOWN {
            rotation -= TRILE_ROTATION_SPEED * cast(float) delta_time;
        }
        if input_button_states[#char "W"] & .DOWN {
            tilt += TRILE_ROTATION_SPEED * cast(float) delta_time;
        }
        if input_button_states[#char "S"] & .DOWN {
            tilt -= TRILE_ROTATION_SPEED * cast(float) delta_time;
        }
    }

    trile_editor_shortcuts();
    
    tilt = clamp(tilt, -(PI/2.0) + 0.01, PI/2.0 - 0.01);
    zoom = clamp(zoom + mouse_delta_z * -0.2, 1.0, 3.0);

    cam := get_trile_editor_camera();
    ray := get_mouse_ray(*cam);
}

get_trile_editor_camera :: () -> Camera {
    camera: Camera;
    camera.near = 0.1;
    camera.far = 5000;

    cameraDir : Vector3    = .{1, 0, 0};
    qrotation : Quaternion = .{cos(rotation/2.0),0,sin(rotation/2.0),0};
    qtilt     : Quaternion = .{cos(tilt/2.0),sin(tilt/2.0), 0, 0};

    rotate(*cameraDir, qrotation * qtilt);
    camera.position = .{0.5, 0.5, 0.5};

    camera.position += cameraDir * zoom;
    camera.target = .{0.5, 0.5, 0.5};
    
    return camera;
}

global_palette_scroll : float = 0.0;
trile_palette_scroll  : float = 0.0;

draw_tool_tab :: (theme: *GR.Overall_Theme, area: GR.Rect) {
    r := area;
    r.h = ui_h(4, 0);
    if GR.button(r, "Paint (P)", *t_button_selectable(theme, current_tool == .PAINT)) {
        current_tool = .PAINT;
    }
    r.y += r.h;
    if GR.button(r, "Add (+)", *t_button_selectable(theme, current_tool == .ADD)) {
        current_tool = .ADD;
    }
    r.y += r.h;
    if GR.button(r, "Remove (-)", *t_button_selectable(theme, current_tool == .REMOVE)) {
        current_tool = .REMOVE;
    }
    r.y += r.h * 3;
    if GR.button(r, "Point (c-P)", *t_button_selectable(theme, current_mode == .POINT)) {
        current_mode = .POINT;
    }
    r.y += r.h;
    if GR.button(r, "Area (c-A)", *t_button_selectable(theme, current_mode == .AREA)) {
        current_mode = .AREA;
    }
    r.y += r.h;
    if GR.button(r, "Brush (c-B)", *t_button_selectable(theme, current_mode == .BRUSH)) {
        current_mode = .BRUSH;
    }

    r.y += r.h;
    GR.slider(r, *brush_radius, 0, 12, 1, *theme.slider_theme);
    r.y += r.h * 2;
    if GR.button(r, "Save and gen", *theme.button_theme) {
        set_trile_gfx(editor_current_trile.name, generate_trile_gfx_matias(editor_current_trile));
    };
}

draw_material_tab :: (theme: *GR.Overall_Theme, area: GR.Rect) {
    r := area;
    r.h = ui_h(42, 0);
    GR.color_picker(r, *current_color, *theme.color_picker_theme);
    r.y += r.h;
    r.h = ui_h(100,0) - r.y;
    r.h -= ui_h(18,0);
    r.h /= 2;
    region, inside := GR.begin_scrollable_region(r, *theme.scrollable_region_theme);
    s := inside;
    GR.end_scrollable_region(region, s.x + s.w, s.y + s.h, *global_palette_scroll);
    r.y += r.h;
    region, inside = GR.begin_scrollable_region(r, *theme.scrollable_region_theme);
    s = inside;
    GR.end_scrollable_region(region, s.x + s.w, s.y + s.h, *trile_palette_scroll);
    r.y += r.h;
    r.h = ui_h(3,2);
    GR.label(r, "Roughness", *t_label_left(theme));
    r.y += r.h;
    GR.slider(r, *roughness, 0, 7, 1, *theme.slider_theme);
    r.y += r.h;
    GR.label(r, "Metallic", *t_label_left(theme));
    r.y += r.h;
    GR.slider(r, *metallic, 0, 3, 1, *theme.slider_theme);
    r.y += r.h;
    GR.label(r, "Emittance", *t_label_left(theme));
    r.y += r.h;
    GR.slider(r, *emittance, 0, 2, 1, *theme.slider_theme);
    
}


draw_trile_editor :: () {
    create_set_cam_rendering_task(get_trile_editor_camera(), 0.0);
    w :=  New(World,, temp);
    create_sky_rendering_task(*w.conf);
    create_trixel_rendering_task(editor_current_trile, *colorMuls);
}

trile_editor_shortcuts :: () {
    if console_open_ignore_input then return;

    if input_button_states[Key_Code.CTRL] & .DOWN {
        if input_button_states[#char "A"] & .START {
            current_mode = .AREA;
        }
        if input_button_states[#char "P"] & .START {
            current_mode = .POINT;
        }
        if input_button_states[#char "B"] & .START {
            current_mode = .BRUSH;
        }
    } else {
        if input_button_states[#char "T"] & .START {
            current_tab = .TOOLSET;
        }
        if input_button_states[#char "M"] & .START {
            current_tab = .MATERIAL;
        }
        if input_button_states[#char "I"] & .START {
            current_tab = .METADATA;
        }
        if input_button_states[#char "P"] & .START {
            current_tool = .PAINT;
        }
        // Hack: These will only work on nordic keyboards as expected...
        if input_button_states[#char "-"] & .START {
            current_tool = .ADD;
        }
        if input_button_states[#char "/"] & .START {
            current_tool = .REMOVE;
        }
    }
}

draw_trile_editor_ui :: (theme: *GR.Overall_Theme) {
    r := GR.get_rect(0, ui_h(5,0), ui_w(20, 20), ui_h(95, 0));
	ui_add_mouse_occluder(r);
    draw_bg_rectangle(r, theme);
    tab_r := r;
    tab_r.h = ui_h(3,0);
    tab_r.w = ui_w(20, 20) / 3;

    if GR.button(tab_r, "Tool (T)", *t_button_tab(theme, current_tab == .TOOLSET)) {
        current_tab = .TOOLSET;
    }
    tab_r.x += tab_r.w;
    if GR.button(tab_r, "Material (M)", *t_button_tab(theme, current_tab == .MATERIAL)) {
        current_tab = .MATERIAL;
    }
    tab_r.x += tab_r.w;
    if GR.button(tab_r, "Meta (I)", *t_button_tab(theme, current_tab == .METADATA)) {
        current_tab = .METADATA;
    }

    r.y += tab_r.h;

    if current_tab == {
        case .MATERIAL;
            draw_material_tab(theme, r);
        case .TOOLSET;
            draw_tool_tab(theme, r);
    }

    draw_picker(theme);
}
