function GUI_stabilizace (size_x,size_y)
% GUI aplikace pro scanner skript
if nargin < 1
    size_x = 1400;
    size_y = 600;
end
%% GUI
fig_name = 'Stabilizace videa využívající optimazační metody';
dstbtw = 0.02;
edge = 0.02;                % edge of GUI
%%
instance = findobj('Name',fig_name);
close(instance(:));
instance = findall(0,'Tag','TMWWaitbar');
close(instance(:));
%% SESTAVENÍ NÁPOVĚD
hint = {...
    'Doporučená hodnota: 20-80';
    'Procento šířky a délky, použité při populaci jedinců, doporuč. hodnota: 5-10';
    'Maximální úhel rotace videa';
    'Maximální počet itrací výpočtu';
    'Kritérium kvality, doporuč. hodnota: 0.995-0.9975';
    'Počet replikací z generace na generaci, musí být menší než velikost populace.';
    'Pravděpodobnost mutace, hodnota 0-1';
    'Maximum počet mutací jedné generovanépopulace jedinců, doporuč. hodnota: 5-20';
    'Rozdíl mezi jednotlivými iteracemi, doporuč. hodnota: 0.0005-0.0009';    % CRS edit 6
    'Hraniční hodnota Kosinova kritéria, při které se má stabilizovat';    % CRS edit 6
    };
ga_name = 'Genetický algoritmus (GA)';
names = {...
    'Počet replikací:';
    'Pravděp. mutace:';
    'Maximum mutací:';
    'Delta nastav:';
    'Hranice stabilizace:';
    };
%%
fig = figure('Visible','off','Position',[50,50,size_x,size_y],...
    'Name',fig_name);

h = guihandles(fig);
h.hint = hint;
h.names = names;
h.ga_name = ga_name;


width = 0.2;
heigh = 0.1;
h.butt_start = uicontrol(fig,'Style','pushbutton','String','Start',...
    'Enable','on',...
    'Units','normalized',...
    'FontUnits','normalized',...
    'Fontsize',0.5,...
    'Position',...
    [edge,...
    edge,...
    width,...
    heigh],...
    'Callback',@butt_start_Callback);


h.butt_prehrat = uicontrol(fig,'Style','pushbutton','String','Přehrát stab. video',...
    'Enable','off',...
    'Units','normalized',...
    'FontUnits','normalized',...
    'Fontsize',0.5,...
    'Position',...
    [h.butt_start.Position(1,1) + h.butt_start.Position(1,3) + dstbtw,...
    edge,...
    (1 - h.butt_start.Position(1,1) - h.butt_start.Position(1,3) - 2* dstbtw - edge)/2,...
    heigh],...
    'Callback',@butt_prehrat_Callback);

h.butt_stats = uicontrol(fig,'Style','pushbutton','String','Statistiky',...
    'Enable','off',...
    'Units','normalized',...
    'FontUnits','normalized',...
    'Fontsize',0.5,...
    'Position',...
    [h.butt_prehrat.Position(1,1) + h.butt_prehrat.Position(1,3) + dstbtw,...
    edge,...
    h.butt_prehrat.Position(1,3),...
    heigh],...
    'Callback',@butt_stats_Callback);

h.butt_video = uicontrol(fig,'Style','pushbutton','String','Výběr videa',...
    'Enable','on',...
    'Units','normalized',...
    'FontUnits','normalized',...
    'Fontsize',0.5,...
    'Position',...
    [edge,...
    h.butt_start.Position(1,2) + h.butt_start.Position(1,4) + dstbtw,...
    width,...
    heigh],...
    'Callback',@butt_butt_video_Callback);

h.edit_file = uicontrol(fig,'Style','Edit','String','video.avi',...
    'Units','normalized',...
    'FontUnits','normalized',...
    'Fontsize',0.5,...
    'Position',...
    [h.butt_video.Position(1,1) + h.butt_video.Position(1,3) + dstbtw,...
    h.butt_video.Position(1,2),...
    1 - dstbtw - h.butt_video.Position(1,1) - h.butt_video.Position(1,3) - edge,...
    h.butt_video.Position(1,4)]);

w = 0.2;
heigh = 0.15;
h.bg = uibuttongroup('Title','Výběr optimalizační metody',...
    'Position',...
    [edge,...
    1-edge-heigh,...
    w,...
    heigh...
    ],...
    'SelectionChangedFcn',@bgselection);

% Create two radio button
r1 = uicontrol(h.bg,'Style',...
    'radiobutton',...
    'Units','normalized',...
    'String',ga_name,...
    'Position',...
    [0.1...
    edge...
    0.95...
    0.5],...
    'HandleVisibility','off');

uicontrol(h.bg,'Style','radiobutton',...
    'String','Kontrolované náhodné prohledávání (CRS)',...
    'Units','normalized',...
    'Position',...
    [r1.Position(1,1),...
    edge + r1.Position(1,4) + dstbtw,...
    r1.Position(1,3),...
    r1.Position(1,4)],...
    'HandleVisibility','off');

heigh = 1 - h.edit_file.Position(1,2) - h.edit_file.Position(1,4)- edge - dstbtw;
h.set = uipanel('Title','Nastavení algoritmů',...
    'Position',...
    [h.bg.Position(1,1) + h.bg.Position(1,3) + dstbtw,...
    1-edge-heigh,...
    1 - h.bg.Position(1,1) -  h.bg.Position(1,3) - dstbtw - edge,...
    heigh...
    ]);%,...

width = 0.23;
heigh = 1/(10 + 9*dstbtw + 2*edge);
h.text_8 = uicontrol('Parent',h.set,'Style','Text','String',h.names{3},...
    'Units','normalized',...
    'HorizontalAlignment','left',...
    'FontUnits','normalized',...
    'Fontsize',0.5,...
    'Position',...
    [edge,...
    edge,...
    width,...
    heigh]);
h.edit_8 = uicontrol('Parent',h.set,'Style','Edit','String','20',...
    'Units','normalized',...
    'FontUnits','normalized',...
    'Fontsize',0.5,...
    'Position',...
    [h.text_8.Position(1,1) + h.text_8.Position(1,3),...
    edge,...
    0.1,...
    heigh]);
h.text_8h = uicontrol('Parent',h.set,'Style','Text','String',h.hint{8},...
    'Units','normalized',...
    'HorizontalAlignment','left',...
    'HorizontalAlignment','left',...
    'FontUnits','normalized',...
    'Fontsize',0.4,...
    'Position',...
    [h.edit_8.Position(1,1) + h.edit_8.Position(1,3) + dstbtw,...
    edge,...
    1 - h.edit_8.Position(1,1) - h.edit_8.Position(1,3) - dstbtw - edge,...
    heigh]);

% Max mutací
h.text_7 = uicontrol('Parent',h.set,'Style','Text','String',h.names{2},...
    'Units','normalized',...
    'HorizontalAlignment','left',...
    'FontUnits','normalized',...
    'Fontsize',0.5,...
    'Position',...
    [edge,...
    h.text_8.Position(1,2) + h.text_8.Position(1,4) + dstbtw,...
    width,...
    heigh]);
h.edit_7 = uicontrol('Parent',h.set,'Style','Edit','String','0.5',...
    'Units','normalized',...
    'FontUnits','normalized',...
    'Fontsize',0.5,...
    'Position',...
    [h.text_8.Position(1,1) + h.text_8.Position(1,3),...
    h.text_8.Position(1,2) + h.text_8.Position(1,4) + dstbtw,...
    0.1,...
    heigh]);
h.text_7h = uicontrol('Parent',h.set,'Style','Text','String',h.hint{7},...
    'Units','normalized',...
    'HorizontalAlignment','left',...
    'FontUnits','normalized',...
    'Fontsize',0.4,...
    'Position',...
    [h.edit_7.Position(1,1) + h.edit_7.Position(1,3) + dstbtw,...
    h.edit_7.Position(1,2),...
    1 - h.edit_7.Position(1,1) - h.edit_7.Position(1,3) - dstbtw - edge,...
    heigh]);

h.text_6 = uicontrol('Parent',h.set,'Style','Text','String',h.names{1},...
    'Units','normalized',...
    'HorizontalAlignment','left',...
    'FontUnits','normalized',...
    'Fontsize',0.5,...
    'Position',...
    [edge,...
    h.text_7.Position(1,2) + h.text_7.Position(1,4) + dstbtw,...
    width,...
    heigh]);
h.edit_6 = uicontrol('Parent',h.set,'Style','Edit','String','20',...
    'Units','normalized',...
    'FontUnits','normalized',...
    'Fontsize',0.5,...
    'Position',...
    [h.text_7.Position(1,1) + h.text_7.Position(1,3),...
    h.text_7.Position(1,2) + h.text_7.Position(1,4) + dstbtw,...
    0.1,...
    heigh]);
h.text_6h = uicontrol('Parent',h.set,'Style','Text','String',h.hint{6},...
    'Units','normalized',...
    'HorizontalAlignment','left',...
    'FontUnits','normalized',...
    'Fontsize',0.4,...
    'Position',...
    [h.edit_6.Position(1,1) + h.edit_6.Position(1,3) + dstbtw,...
    h.edit_6.Position(1,2),...
    1 - h.edit_6.Position(1,1) - h.edit_6.Position(1,3) - dstbtw - edge,...
    heigh]);

% Kritérium kvality
h.text_5 = uicontrol('Parent',h.set,'Style','Text','String','Kr. kvality:',...
    'Units','normalized',...
    'HorizontalAlignment','left',...
    'FontUnits','normalized',...
    'Fontsize',0.5,...
    'Position',...
    [edge,...
    h.text_6.Position(1,2) + h.text_6.Position(1,4) + dstbtw,...
    width,...
    heigh]);
h.edit_5 = uicontrol('Parent',h.set,'Style','Edit','String','0.995',...
    'Units','normalized',...
    'FontUnits','normalized',...
    'Fontsize',0.5,...
    'Position',...
    [h.text_6.Position(1,1) + h.text_6.Position(1,3),...
    h.text_6.Position(1,2) + h.text_6.Position(1,4) + dstbtw,...
    0.1,...
    heigh]);
h.text_5h = uicontrol('Parent',h.set,'Style','Text','String',h.hint{5},...
    'Units','normalized',...
    'HorizontalAlignment','left',...
    'FontUnits','normalized',...
    'Fontsize',0.4,...
    'Position',...
    [h.edit_5.Position(1,1) + h.edit_5.Position(1,3) + dstbtw,...
    h.edit_5.Position(1,2),...
    1 - h.edit_5.Position(1,1) - h.edit_5.Position(1,3) - dstbtw - edge,...
    heigh]);

% Maxit
h.text_4 = uicontrol('Parent',h.set,'Style','Text','String','Max iterací:',...
    'Units','normalized',...
    'HorizontalAlignment','left',...
    'FontUnits','normalized',...
    'Fontsize',0.5,...
    'Position',...
    [edge,...
    h.text_5.Position(1,2) + h.text_5.Position(1,4) + dstbtw,...
    width,...
    heigh]);
h.edit_4 = uicontrol('Parent',h.set,'Style','Edit','String','100',...
    'Units','normalized',...
    'FontUnits','normalized',...
    'Fontsize',0.5,...
    'Position',...
    [h.text_5.Position(1,1) + h.text_5.Position(1,3),...
    h.text_5.Position(1,2) + h.text_5.Position(1,4) + dstbtw,...
    0.1,...
    heigh]);
h.text_4h = uicontrol('Parent',h.set,'Style','Text','String',h.hint{4},...
    'Units','normalized',...
    'HorizontalAlignment','left',...
    'FontUnits','normalized',...
    'Fontsize',0.4,...
    'Position',...
    [h.edit_4.Position(1,1) + h.edit_4.Position(1,3) + dstbtw,...
    h.edit_4.Position(1,2),...
    1 - h.edit_4.Position(1,1) - h.edit_4.Position(1,3) - dstbtw - edge,...
    heigh]);

% Úhel rotace
h.text_3 = uicontrol('Parent',h.set,'Style','Text','String','Úhel rotace:',...
    'Units','normalized',...
    'HorizontalAlignment','left',...
    'FontUnits','normalized',...
    'Fontsize',0.5,...
    'Position',...
    [edge,...
    h.text_4.Position(1,2) + h.text_4.Position(1,4) + dstbtw,...
    width,...
    heigh]);
h.edit_3 = uicontrol('Parent',h.set,'Style','Edit','String','4',...
    'Units','normalized',...
    'FontUnits','normalized',...
    'Fontsize',0.5,...
    'Position',...
    [h.text_4.Position(1,1) + h.text_4.Position(1,3),...
    h.text_4.Position(1,2) + h.text_4.Position(1,4) + dstbtw,...
    0.1,...
    heigh]);
h.text_3h = uicontrol('Parent',h.set,'Style','Text','String',h.hint{3},...
    'Units','normalized',...
    'HorizontalAlignment','left',...
    'FontUnits','normalized',...
    'Fontsize',0.4,...
    'Position',...
    [h.edit_3.Position(1,1) + h.edit_3.Position(1,3) + dstbtw,...
    h.edit_3.Position(1,2),...
    1 - h.edit_3.Position(1,1) - h.edit_3.Position(1,3) - dstbtw - edge,...
    heigh]);

% Procento obrazu
h.text_2 = uicontrol('Parent',h.set,'Style','Text','String','Procento obrazu:',...
    'Units','normalized',...
    'HorizontalAlignment','left',...
    'FontUnits','normalized',...
    'Fontsize',0.5,...
    'Position',...
    [edge,...
    h.text_3.Position(1,2) + h.text_3.Position(1,4) + dstbtw,...
    width,...
    heigh]);
h.edit_2 = uicontrol('Parent',h.set,'Style','Edit','String','10',...
    'Units','normalized',...
    'FontUnits','normalized',...
    'Fontsize',0.5,...
    'Position',...
    [h.text_3.Position(1,1) + h.text_3.Position(1,3),...
    h.text_3.Position(1,2) + h.text_3.Position(1,4) + dstbtw,...
    0.1,...
    heigh]);
h.text_2h = uicontrol('Parent',h.set,'Style','Text','String',h.hint{2},...
    'Units','normalized',...
    'HorizontalAlignment','left',...
    'FontUnits','normalized',...
    'Fontsize',0.4,...
    'Position',...
    [h.edit_2.Position(1,1) + h.edit_2.Position(1,3) + dstbtw,...
    h.edit_2.Position(1,2),...
    1 - h.edit_2.Position(1,1) - h.edit_2.Position(1,3) - dstbtw - edge,...
    heigh]);

% Počet jedinců
h.text_1 = uicontrol('Parent',h.set,'Style','Text','String','Velikost populace:',...
    'Units','normalized',...
    'HorizontalAlignment','left',...
    'FontUnits','normalized',...
    'Fontsize',0.5,...
    'Position',...
    [edge,...
    h.text_2.Position(1,2) + h.text_2.Position(1,4) + dstbtw,...
    width,...
    heigh]);
h.edit_1 = uicontrol('Parent',h.set,'Style','Edit','String','50',...
    'Units','normalized',...
    'FontUnits','normalized',...
    'Fontsize',0.5,...
    'Position',...
    [h.text_2.Position(1,1) + h.text_2.Position(1,3),...
    h.text_2.Position(1,2) + h.text_2.Position(1,4) + dstbtw,...
    0.1,...
    heigh]);
h.text_1h = uicontrol('Parent',h.set,'Style','Text','String',h.hint{1},...
    'Units','normalized',...
    'HorizontalAlignment','left',...
    'FontUnits','normalized',...
    'Fontsize',0.4,...
    'Position',...
    [h.edit_1.Position(1,1) + h.edit_1.Position(1,3) + dstbtw,...
    h.edit_1.Position(1,2),...
    1 - h.edit_1.Position(1,1) - h.edit_1.Position(1,3) - dstbtw - edge,...
    heigh]);

guidata(fig, h);
fig.Visible = 'on';
%% CALLBACKS
    function handles = butt_start_Callback(fig,~)
        handles = guidata(fig);
        inst = findall(0,'Tag','TMWWaitbar');
        close(inst(:));
        if(str2double(handles.edit_5.String) > 1 || str2double(handles.edit_5.String) < 0)
            error('Kritérium kvality musí být v rozmezí 0 až 1!');
        end
        handles.butt_stats.Enable = 'off';
        handles.butt_prehrat.Enable = 'off';
        if(strcmp(handles.bg.SelectedObject.String,handles.ga_name))  % genetický
            if(str2double(handles.edit_1.String) < str2double(handles.edit_6.String))
                error('Počet replikací musí být menší než velikost populace');
            end
            if(str2double(handles.edit_7.String) > 1 || str2double(handles.edit_7.String) < 0)
                error('Pravděpodobnost mutace musí být v rozmezí 0 až 1!');
            end
            [handles.output_name, handles.statistiky, handles.kvalita,handles.elapset_time] = ...
                Genetic(...
                handles.edit_file.String,...
                str2double(handles.edit_1.String),... % pocetjedincu,...
                str2double(handles.edit_6.String),... % pocetreplikaci,...
                str2double(handles.edit_7.String),... % pstmutace,...
                str2double(handles.edit_2.String),... % procento_obrazu,...
                str2double(handles.edit_3.String),... % uhel_rotace,...
                str2double(handles.edit_4.String),... % maxit,...
                str2double(handles.edit_8.String),... % maxmutaci,...
                str2double(handles.edit_5.String));   % kriterium_kvality);
        else
            [handles.output_name, handles.statistiky, handles.elapset_time] = ...
                stabil_CRS(...
                handles.edit_file.String,... % filename,...
                str2double(handles.edit_1.String),... % pocetjedincu,...
                str2double(handles.edit_2.String),... % procento_obrazu,...
                str2double(handles.edit_3.String),... % uhel_rotace,...
                str2double(handles.edit_4.String),... % maxit,...
                str2double(handles.edit_6.String),... % delta_nastav,...
                str2double(handles.edit_7.String),... % hranice_stabilizace,...
                str2double(handles.edit_5.String));   % kriterium_kvality);
        end
        videoreader = VideoReader(handles.output_name);
        snimky = ceil(videoreader.Duration * videoreader.FrameRate);
        fprintf('Výpočet statistik MI pro nestabilizované video.\n');
        handles.statistiky_raw = zeros(3,snimky);
        videoreader = VideoReader(handles.edit_file.String);
        srovnani = readFrame(videoreader);
        k = 2;
        while hasFrame(videoreader)
            [handles.statistiky_raw(2,k), handles.statistiky_raw(3,k)] =...
                mutualInfo(srovnani,readFrame(videoreader));
            k = k + 1;
        end
        handles.butt_stats.Enable = 'on';
        handles.butt_prehrat.Enable = 'on';
        guidata(fig, handles);
        handles = guidata(fig);
    end

    function handles = butt_butt_video_Callback(fig,~)
        handles = guidata(fig);
        [FileName, PathName] = uigetfile({'*.avi'},'Vyberte soubor s videem');
        addpath(PathName);
        handles.edit_file.String = [PathName,FileName];
        handles.PathName = PathName;
        handles.FileName = FileName;
        guidata(fig, handles);
        handles = guidata(fig);
    end

    function handles = bgselection(fig,~)
        handles = guidata(fig);
        if(strcmp(handles.bg.SelectedObject.String,handles.ga_name))
            handles.text_6.String = handles.names{1};
            handles.text_7.String = handles.names{2};
            handles.text_6h.String = handles.hint{6};
            handles.text_7h.String = handles.hint{7};
            handles.text_7.Visible = 'on';
            handles.text_7h.Visible = 'on';
            handles.edit_7.Visible = 'on';
            handles.text_8.Visible = 'on';
            handles.text_8h.Visible = 'on';
            handles.edit_8.Visible = 'on';
        else
            handles.text_6.String = handles.names{4};
            handles.text_6h.String = handles.hint{9};
            handles.edit_6.String = '0.0005';
            handles.text_7.String = handles.names{5};
            handles.text_7h.String = handles.hint{10};
            handles.edit_7.String = '1';
            handles.text_8.Visible = 'off';
            handles.text_8h.Visible = 'off';
            handles.edit_8.Visible = 'off';
        end
        guidata(fig, handles);
        handles = guidata(fig);
    end

    function handles = butt_prehrat_Callback(fig,~)
        handles = guidata(fig);
        v = VideoReader(handles.output_name);
        player = vision.VideoPlayer;        
        while hasFrame(v)
            step(player,readFrame(v));
        end
        guidata(fig, handles);
        handles = guidata(fig);
    end

    function handles = butt_stats_Callback(fig,~)
        handles = guidata(fig);
        figure;
        hold on;
        plot(handles.statistiky(2,:));
        plot(handles.statistiky_raw(2,:));        
        xlabel('Snímky');
        ylabel('MI');
        legend({'Stabilizované video','Originální video'});
        str = sprintf('Statistiky MI. Doba stabilizace %.2f sekund',handles.elapset_time);
        title(str);
        hold off;
        guidata(fig, handles);
        handles = guidata(fig);
    end
end