clear; clc; close all;

model = 'mcu_test_r2023';
block = [model '/MCU_UPP'];

load_system(model);  % если модель ещё не загружена

update_mask_from_config(block);

disp('Маска обновлена по конфигу.');
function update_mask_from_config(blockPath)
    config = load_periph_config();
    mask = Simulink.Mask.get(blockPath);

    tabName = 'configTab';  % Имя вкладки (Prompt)

    allControls = mask.getDialogControls();
    tabCtrl = find_tab_by_name(allControls, tabName);

    if isempty(tabCtrl)
        error('Вкладка с названием "%s" не найдена в маске', tabName);
    end

    % Удаляем все контролы внутри вкладки
    children = tabCtrl.DialogControls;
    while ~isempty(children)
        mask.removeParameter(children(1).Name);
        children = tabCtrl.DialogControls; % обновляем список после удаления
    end

    periphs = fieldnames(config);
    for i = 1:numel(periphs)
        periph = periphs{i};
        defines = config.(periph).Defines;
        defNames = fieldnames(defines);

        for j = 1:numel(defNames)
            defPrompt = defNames{j};
            def = defines.(defPrompt);

            % Обрабатываем только checkbox и edit
            switch lower(def.Type)
                case 'checkbox'
                    paramType = 'checkbox';
                case 'edit'
                    paramType = 'edit';
                otherwise
                    continue;
            end

            paramName = matlab.lang.makeValidName([periph '_' defPrompt]);

            val = def.Default;
            if islogical(val)
                if val
                    valStr = 'on';
                else
                    valStr = 'off';
                end
            elseif isnumeric(val)
                valStr = num2str(val);
            elseif ischar(val)
                valStr = val;
            else
                error('Unsupported default value type for %s.%s', periph, defPrompt);
            end


            % Добавляем параметр в маску (без TabName)
            mask.addParameter(...
                'Type', paramType, ...
                'Prompt', defPrompt, ...
                'Name', paramName, ...
                'Value', valStr, ...
                'Container', tabName);
        end
    end
end






function config = load_periph_config()
    jsonText = fileread('periph_config.json');
    config = jsondecode(jsonText);
end


function clear_params_from_tab(blockPath, tabName)
    mask = Simulink.Mask.get(blockPath);
    controls = mask.getDialogControls;
    tabs = controls(strcmp({controls.Type}, 'tab'));
    
    tabName = '';
    for i = 1:numel(tabs)
        if strcmp(tabs(i).Prompt, tabName)
            tabName = tabs(i).Name; % внутреннее имя вкладки
            break;
        end
    end

    if isempty(tabName)
        error('Вкладка с названием "%s" не найдена.', tabName);
    end

    % Удаляем параметры с TabName == tabName
    i = 1;
    while i <= numel(mask.Parameters)
        if strcmp(mask.Parameters(i).TabName, tabName)
            mask.removeParameter(i);
        else
            i = i + 1;
        end
    end
end


%% поиск вкладки
function tab = find_tab_by_name(controls, targetName)
    tab = [];

    for i = 1:numel(controls)
        ctrl = controls(i);

        % Проверяем, вкладка ли это и совпадает ли имя
        if isa(ctrl, 'Simulink.dialog.Tab') && strcmp(ctrl.Name, targetName)
            tab = ctrl;
            return;
        end

        % Если это контейнер — обходим его детей
        children = get_children(ctrl);
        if ~isempty(children)
            tab = find_tab_by_name(children, targetName);
            if ~isempty(tab)
                return;
            end
        end
    end
end


function children = get_children(ctrl)
    if isprop(ctrl, 'DialogControls')
        children = ctrl.DialogControls;
    elseif isprop(ctrl, 'Controls')
        children = ctrl.Controls;
    elseif isprop(ctrl, 'Children')
        children = ctrl.Children;
    else
        children = [];
    end
end

