% funkce pro inicializaci aplikace
function Gui

% definice jednotlivých ovládacích prvků
handles.fig = figure('name', '-IELF method-',...
               'numbertitle', 'off',...
               'menubar','none',...
               'resize','on',...
               'units', 'normal',...
               'position', [0.15 0.1 0.7 0.8]);

set(handles.fig, 'units', 'pixels');

handles.panel_input_files = uipanel('title', 'INPUT FILES ',...
                      'units', 'pixels');

handles.panel_frequency_bands = uipanel('title', 'FREQUENCY BANDS ',...
                      'units', 'pixels');

handles.file_1 = uicontrol('style', 'edit',...
                     'HorizontalAlignment', 'left',...
                     'fontsize', 12);

handles.file_2 = uicontrol('style', 'edit',...
                     'HorizontalAlignment', 'left',...
                     'fontsize', 12);

handles.search_button_1 = uicontrol('style', 'pushbutton',...
                              'string', '...');

handles.search_button_2 = uicontrol('style', 'pushbutton',...
                              'string', '...');

handles.band_list = uicontrol('style','list',...
                         'fontsize', 12,...
                          'min',0,'max',2);

handles.lower_limit = uicontrol('style', 'edit',...
                          'HorizontalAlignment', 'left',...
                          'fontsize', 12);

handles.upper_limit = uicontrol('style', 'edit',...
                          'HorizontalAlignment', 'left',...
                          'fontsize', 12);

handles.add_button = uicontrol('style', 'pushbutton',...
                         'string', 'Add');

handles.delete_button = uicontrol('style', 'pushbutton',...
                            'string', 'Delete');

handles.clearall_button = uicontrol('style', 'pushbutton',...
                            'string', 'Clear All');

handles.go_button = uicontrol('style', 'pushbutton',...
                        'string', 'Calculate',...
                        'enable', 'off',...
                        'fontsize',  20);

handles.panel_in = uipanel('title', 'INPUT GRAPHS ',...
                     'units', 'pixels');

handles.panel_out = uipanel('title', 'COMMON FREQUENCY BAND AFTER INTERPOLATION ',...
                      'units', 'pixels');

handles.panel_log = uipanel('title', 'LOG ',...
                      'units', 'pixels');

handles.clearlog_button = uicontrol('style', 'pushbutton',...
                            'string', 'Clear Log');

handles.log = uicontrol('units', 'pixels',...
                  'style', 'list',...
                  'value', [],...
                  'fontsize', 12,...
                  'min',0,'max',2);

handles.panel_results_ielf = uipanel('title', 'RESULTS IELF ',...
                          'units', 'pixels');

handles.results_ielf = uicontrol('style','list',...
                      'units', 'pixels',...
                      'fontsize', 12,...
                      'value', [],...
                      'min',0,'max',2);

handles.panel_results_ielfmod = uipanel('title', 'RESULTS IELFmod ',...
                          'units', 'pixels');

handles.results_ielfmod = uicontrol('style','list',...
                      'units', 'pixels',...
                      'fontsize', 12,...
                      'value', [],...
                      'min',0,'max',2);

handles.reset_button = uicontrol('style', 'pushbutton',...
                            'string', 'Reset GUI');

% blok pro úpravu pozic a velikostí podle velikosti okna
pos = get(handles.fig, 'position');

x_size = pos(3);
y_size = pos(4);
y_half = y_size/2;

set(handles.panel_input_files, 'position', [5 y_size-63 495 63]);
set(handles.file_1, 'position', [9 y_size-33 448 20]);
set(handles.file_2, 'position', [9 y_size-58 448 20]);
set(handles.search_button_1, 'position', [462 y_size-32 30 18]);
set(handles.search_button_2, 'position', [462 y_size-57 30 18]);

set(handles.panel_frequency_bands, 'position', [5 y_size-206 495 143]);
set(handles.lower_limit, 'position', [9 y_size-96 160 20]);
set(handles.upper_limit, 'position', [9 y_size-121 160 20]);
set(handles.add_button, 'position', [174 y_size-121 45 45]);
set(handles.delete_button, 'position', [9 y_size-147 210 23]);
set(handles.clearall_button, 'position', [9 y_size-170 210 23]);
set(handles.band_list, 'position', [224 y_size-204 273 128]);

set(handles.go_button, 'position', [5 y_size-241 495 35]);

set(handles.panel_results_ielf, 'position', [5 y_half-137 245 140]);
set(handles.results_ielf, 'position', [7 y_half-135 240 126]);
set(handles.panel_results_ielfmod, 'position', [255 y_half-137 245 140]);
set(handles.results_ielfmod, 'position', [257 y_half-135 240 126]);

set(handles.panel_log, 'position', [5 5 495 120]);
set(handles.log, 'position', [7 7 490 106]);
set(handles.clearlog_button, 'position', [290 120 210 23]);

dataStruct.panel_size = [x_size-505 y_half-2];

set(handles.panel_in, 'position', [503 y_half+2 dataStruct.panel_size(1) dataStruct.panel_size(2)]);
set(handles.panel_out, 'position', [503 5 dataStruct.panel_size(1) dataStruct.panel_size(2)]);

set(handles.reset_button, 'position', [305 y_size-263 195 23]);

% přiřazení callbacků
set(handles.search_button_1, 'callback', {@sb1_call, handles});
set(handles.search_button_2, 'callback', {@sb2_call, handles});

set(handles.file_1, 'callback', {@file_1_call, handles});
set(handles.file_2, 'callback', {@file_2_call, handles});

set(handles.add_button, 'callback', {@add_button_call, handles});
set(handles.delete_button, 'callback', {@delete_button_call, handles});
set(handles.clearall_button, 'callback', {@clearall_button_call, handles});

set(handles.go_button, 'callback', {@go_call, handles});

set(handles.clearlog_button, 'callback', {@clearlog_button_call, handles});

set(handles.fig, 'ResizeFcn',{@scaling, handles});

set(handles.reset_button, 'callback', {@reset_call, handles});

% vytvoření potřebných proměnných (flagů)
dataStruct.files_entered = 0;
dataStruct.last_entered = 0;
dataStruct.displayed = 0;
dataStruct.ax_2_present = 0;

dataStruct.file_path_1 = [];
dataStruct.file_path_2 = [];

dataStruct.value = 1;

clc

t = timer();
t.Period = 10;
t.ExecutionMode = 'fixedRate';
t.StartDelay = 1;
handles.timer = t;
set(handles.timer, 'TimerFcn', {@timer_call, handles});

% start(handles.timer);

% guidata(handles.fig, handles)
guidata(handles.fig, dataStruct)

% function handles = timer_call(hObject, eventdata, handles)
% keyboard
% dataStruct = guidata(handles.fig);
% dataStruct.value = dataStruct.value + 1;
% % val = get(handles.log, 'string');
% % val = str2num(val);
% % val = val + 1;
% % set(handles.log, 'string', val);
% 
% guidata(handles.fig, dataStruct)



% funkce pro obsluhu tlačítka search_button_1 (...)
function handles = sb1_call(hObject, ~, handles)

% načtení sturktury s
dataStruct = guidata(hObject);

% volání funkce pro zobrazení dialogového okna
[FileName,PathName] = uigetfile('*.*','Select file no.1');

if (FileName == 0)
    return;
end

% uložení cesty k souboru do struktury
dataStruct.file_path_1 = strcat(PathName,FileName);
set(handles.file_1,'String',dataStruct.file_path_1);

% kontrola existence souboru
e = exist(dataStruct.file_path_1, 'file');

if (e ~= 2)
    disp('input file error: there''s no such file');
end

% volání funkce pro vykreslení prvního grafu
dataStruct = inputPlot(dataStruct, handles);

% uložení nové podoby struktury s
guidata(hObject, dataStruct);

% funkce pro obsluhu tlačítka search_button_2 (...)
function handles = sb2_call(hObject, ~, handles)

% načtení sturktury s
dataStruct = guidata(hObject);

% volání funkce pro zobrazení dialogového okna
[FileName,PathName] = uigetfile('*.*','Select file no.2');

if (FileName == 0)
    return;
end

% uloženĂ­ cesty k souboru do struktury
dataStruct.file_path_2 = strcat(PathName,FileName);
set(handles.file_2,'String',dataStruct.file_path_2);

% kontrola existence souboru
e = exist(dataStruct.file_path_2, 'file');

if (e ~= 2)
    disp('input file error: there''s no such file');
end

% volání­ funkce pro vykreslení prvního grafu
dataStruct = inputPlot(dataStruct, handles);

% uložení nové podoby struktury s
guidata(hObject, dataStruct);

% funkce pro obsluhu prvního řádku pro zadávání cesty k souboru
function handles = file_1_call(hObject, ~, handles)

% načtení struktury s
dataStruct = guidata(hObject);

% uložená vložené cesty
dataStruct.file_path_1 = get(handles.file_1,'String');
e = exist(dataStruct.file_path_1, 'file');

% kotrola existence souboru
if (e ~= 2)
    if (isempty(dataStruct.file_path_1))
        dataStruct.file_path_1 = [];
    else
        disp('input file error: there''s no such file');
        addToLog('input file error: there''s no such file',handles);
        dataStruct.file_path_1 = [];
    end
end

% volání funkce pro vykreslení prvního grafu
dataStruct = inputPlot(dataStruct, handles);

% uložení nové podoby struktury s
guidata(hObject, dataStruct);

% funkce pro obsluhu druhého řádku pro zadávání cesty k souboru
function handles = file_2_call(hObject, ~, handles)

% načtení struktury s
dataStruct = guidata(hObject);

% uložení vložení cesty
dataStruct.file_path_2 = get(handles.file_2,'String');
e = exist(dataStruct.file_path_2, 'file');

% kotrola existence souboru
if (e ~= 2)
    if (isempty(dataStruct.file_path_2))
        dataStruct.file_path_2 = [];
    else
        disp('input file error: there''s no such file');
        addToLog('input file error: there''s no such file',handles);
        dataStruct.file_path_2 = [];
    end
end

% volání funkce pro vykreslení prvního grafu
dataStruct = inputPlot(dataStruct, handles);

% uložení nové podoby struktury s
guidata(hObject, dataStruct);

% funkce pro obsluhu tlačítka pro přidání nového rozsahu
function handles = add_button_call(~, ~, handles)

% načtení vložených frekvenčních mezí
lower_limit = get(handles.lower_limit, 'string');
upper_limit = get(handles.upper_limit, 'string');

% kontrola zadaných mezí (jsou-li zadané a jejich formát)
empty_1 = isempty(lower_limit);
empty_2 = isempty(upper_limit);

if ((empty_1 == 1) || (empty_2 == 1))
    return;
end

% není-li lower limit číslo, vrátí funkce str2num na indexu (1,2) nulu
empty_1 = isempty(str2num(lower_limit));
empty_2 = isempty(str2num(upper_limit));

size_1 = size(str2num(lower_limit));
size_2 = size(str2num(upper_limit));

empty_3 = size_1(1,2);
empty_4 = size_2(1,2);

if ((empty_1 == 1) || (empty_2 == 1) || (empty_3 > 1) || (empty_4 >1))
    addToLog('freq. band error: entered limit of frequency band is in incorrect format',handles)
    return;
end

% načtení původního obsahu sezmanu
old_str = get(handles.band_list, 'string');

% vytvoření nového řádku
limits{1} = num2str(lower_limit);
limits{2} = num2str(upper_limit);
new_line = strjoin(limits, ' - ');
empty = isempty(old_str);

% přidání nového řádku
if (empty == 0)
    old_str = cellstr(get(handles.band_list, 'string'));
set(handles.band_list,'string', {old_str{:},new_line});
else
    set(handles.band_list,'string', new_line);
end

unsorted = get(handles.band_list, 'string');
lines = size(unsorted,1);

if (size(unsorted,1) == 1)
    set(handles.band_list,'string', unsorted);
else
    sorted = sort(unsorted);
    set(handles.band_list,'string', sorted);
end

% smazání obsahu políček pro vkládání mezí
set(handles.lower_limit,'String','');
set(handles.upper_limit,'String','');

% vložení nové podoby sezmanu do příslušného parametru
set(handles.band_list, 'value', lines);

% funkce pro obsluhu talčítka pro mazání rozsahů (Delete)
function handles = delete_button_call(~, ~, handles)

% načtení puvodního obsahu sezmanu pásem a čísla označeného řádku
L = get(handles.band_list,{'string','value'});
band_count = size(L{1,1},1);

% vymazání zvoleného řádku
if (band_count == 1)
    set(handles.band_list,'string', '');
else
    if ~isempty(L{1})
        L{1}(L{2}(:)) = [];
        set(handles.band_list,'string',L{1},'value',1);
    end
end

% funkce pro smazání všech pásem
function handles = clearall_button_call(~, ~, handles)

set(handles.band_list,'string', '');

% funkce pro obsluhu tlačítka Calculate a spuštění výpočtů
function handles = go_call(hObject, ~, handles)

% načtení struktury s
dataStruct = guidata(hObject);

% vymazání předchozích výsledků výpočtů
set(handles.results_ielf, 'string', []);
set(handles.results_ielfmod, 'string', []);

% převzetí cest k souborům ze struktury s
fp1 = dataStruct.file_path_1;
fp2 = dataStruct.file_path_2;

% načtení sezmanu pásem
bands = get(handles.band_list,'string');

% stanovení počtu pásem
band_count = size(bands,1);

% ůprava formátu na pole čísel
for I = 1:band_count
    if (band_count == 1)
        if (iscell(bands))
            b = bands{1,:};
        else
            b = bands;
        end
    else
        b = bands{I,:};
    end
    c = strsplit(b, ' - ');
    for J = 1:2
        e = cell2mat(c(J));
        f = str2num(e);
        bands_final(I,J) = f;
    end
end

if (band_count == 0)
    bands_final = [];
end

% vymazání předchozí podoby druhé grafu, pokud už byl dříve vytvořen
if (dataStruct.ax_2_present == 1)
    delete(dataStruct.ax_2);
    dataStruct.ax_2_present = 0;
end

dataStruct.ax_2 = axes('parent', handles.panel_out, 'units', 'pixels');
set(dataStruct.ax_2, 'position', [31 36 dataStruct.panel_size(1)-40 dataStruct.panel_size(2)-55]);
dataStruct.ax_2_present = 1;

% volání funkce pro provedení výpočtů
[dataStruct.results_ielf, dataStruct.results_ielf_mod, dataStruct.results_corr] = mainFunc(fp1, fp2, bands_final, handles);

% výpis výsledků IELF
for I = 1:band_count+1
    if (I == 1)
        value = dataStruct.results_ielf(I);

        new_line = sprintf('total:   %0.4f',value);

        old_str = get(handles.results_ielf, 'string');
        empty = isempty(old_str);
        if (empty == 0)
            old_str = cellstr(get(handles.results_ielf, 'string'));
            set(handles.results_ielf,'string', {old_str{:},new_line});
        else
        set(handles.results_ielf,'string', new_line);
        end
    else
        value = dataStruct.results_ielf(I);

        new_line = sprintf('frequency band no.%d:   %0.4f',I-1,value);

        old_str = get(handles.results_ielf, 'string');
        empty = isempty(old_str);
        if (empty == 0)
            old_str = cellstr(get(handles.results_ielf, 'string'));
            set(handles.results_ielf,'string', {old_str{:},new_line});
        else
        set(handles.results_ielf,'string', new_line);
        end
    end
end

% výpis výsledků IELFmod
for I = 1:band_count+1
    if (I == 1)
        value = dataStruct.results_ielf_mod(I);

        new_line = sprintf('total:   %0.4f',value);

        old_str = get(handles.results_ielfmod, 'string');
        empty = isempty(old_str);
        if (empty == 0)
            old_str = cellstr(get(handles.results_ielfmod, 'string'));
            set(handles.results_ielfmod,'string', {old_str{:},new_line});
        else
        set(handles.results_ielfmod,'string', new_line);
        end
    else
        value = dataStruct.results_ielf_mod(I);

        new_line = sprintf('frequency band no.%d:   %0.4f',I-1,value);

        old_str = get(handles.results_ielfmod, 'string');
        empty = isempty(old_str);
        if (empty == 0)
            old_str = cellstr(get(handles.results_ielfmod, 'string'));
            set(handles.results_ielfmod,'string', {old_str{:},new_line});
        else
        set(handles.results_ielfmod,'string', new_line);
        end
    end
end

% uložení nové podoby struktury s
guidata(hObject, dataStruct);

% funkce pro smazání obsahu LOGu
function handles = clearlog_button_call(~, ~, handles)

clc
set(handles.log,'string', '');

% funkce pro čisté spuštení celé aplikace
function handles = reset_call(~, ~, handles)

close all force
Gui

% funkce volaná při změně velikosti okna
function handles = scaling(hObject, ~, handles)

% načtení struktury s
dataStruct = guidata(hObject);

% načtení aktuální velikosti okna aplikace
pos = get(handles.fig, 'position');

x_pos = pos(1);
y_pos = pos(2);
x_size = pos(3);
y_size = pos(4);
y_half = y_size/2;

% omezení horizontální velikosti okna
if (x_size < 1000)
    set(handles.fig, 'position', [x_pos y_pos 1000 y_size]);
    x_size = 1000;
end

% omezení vertikální velikosti okna
if (y_size < 560)
    set(handles.fig, 'position', [x_pos y_pos x_size 560]);
    y_size = 560;
    y_half = y_size/2;
end

% nastavení velikostí a pozoc jednotlivých prvků
set(handles.panel_input_files, 'position', [5 y_size-63 495 63]);
set(handles.file_1, 'position', [9 y_size-33 448 20]);
set(handles.file_2, 'position', [9 y_size-58 448 20]);
set(handles.search_button_1, 'position', [462 y_size-32 30 18]);
set(handles.search_button_2, 'position', [462 y_size-57 30 18]);

set(handles.panel_frequency_bands, 'position', [5 y_size-206 495 143]);
set(handles.lower_limit, 'position', [9 y_size-96 160 20]);
set(handles.upper_limit, 'position', [9 y_size-121 160 20]);
set(handles.add_button, 'position', [174 y_size-121 45 45]);
set(handles.delete_button, 'position', [9 y_size-147 210 23]);
set(handles.clearall_button, 'position', [9 y_size-170 210 23]);
set(handles.band_list, 'position', [224 y_size-204 273 128]);

set(handles.go_button, 'position', [5 y_size-241 495 35]);

set(handles.panel_results_ielf, 'position', [5 y_half-137 245 140]);
set(handles.results_ielf, 'position', [7 y_half-135 240 126]);
set(handles.panel_results_ielfmod, 'position', [255 y_half-137 245 140]);
set(handles.results_ielfmod, 'position', [257 y_half-135 240 126]);

set(handles.panel_log, 'position', [5 5 495 120]);
set(handles.log, 'position', [7 7 490 106]);
set(handles.clearlog_button, 'position', [290 120 210 23]);

dataStruct.panel_size = [x_size-505 y_half-2];

set(handles.panel_in, 'position', [503 y_half+2 dataStruct.panel_size(1) dataStruct.panel_size(2)]);
set(handles.panel_out, 'position', [503 5 dataStruct.panel_size(1) dataStruct.panel_size(2)]);

set(handles.reset_button, 'position', [305 y_size-263 195 23]);

if (isfield(dataStruct, 'ax_1'))
    set(dataStruct.ax_1, 'position', [31 36 dataStruct.panel_size(1)-40 dataStruct.panel_size(2)-55]);
end

if (isfield(dataStruct, 'ax_2'))
    set(dataStruct.ax_2, 'position', [31 36 dataStruct.panel_size(1)-40 dataStruct.panel_size(2)-55]);
end

% uložení nové podoby struktury s
guidata(hObject, dataStruct);