function varargout = goal_def_UI(varargin)
% GOAL_DEF_TEST MATLAB code for goal_def_test.fig
%      GOAL_DEF_TEST, by itself, creates a new GOAL_DEF_TEST or raises the existing
%      singleton*.
%
%      H = GOAL_DEF_TEST returns the handle to a new GOAL_DEF_TEST or the handle to
%      the existing singleton*.
%
%      GOAL_DEF_TEST('CALLBACK',hObject,eventData,handles,...) calls the local
%      function named CALLBACK in GOAL_DEF_TEST.M with the given input arguments.
%
%      GOAL_DEF_TEST('Property','Value',...) creates a new GOAL_DEF_TEST or raises the
%      existing singleton*.  Starting from the left, property value pairs are
%      applied to the GUI before goal_def_test_OpeningFcn gets called.  An
%      unrecognized property name or invalid value makes property application
%      stop.  All inputs are passed to goal_def_test_OpeningFcn via varargin.
%
%      *See GUI Options on GUIDE's Tools menu.  Choose "GUI allows only one
%      instance to run (singleton)".
%
% See also: GUIDE, GUIDATA, GUIHANDLES

% Edit the above text to modify the response to help goal_def_test

% Last Modified by GUIDE v2.5 23-Oct-2020 12:55:21

% Begin initialization code - DO NOT EDIT
gui_Singleton = 1;
gui_State = struct('gui_Name',       mfilename, ...
                   'gui_Singleton',  gui_Singleton, ...
                   'gui_OpeningFcn', @goal_def_test_OpeningFcn, ...
                   'gui_OutputFcn',  @goal_def_test_OutputFcn, ...
                   'gui_LayoutFcn',  [] , ...
                   'gui_Callback',   []);
if nargin && ischar(varargin{1})
    gui_State.gui_Callback = str2func(varargin{1});
end

if nargout
    [varargout{1:nargout}] = gui_mainfcn(gui_State, varargin{:});
else
    gui_mainfcn(gui_State, varargin{:});
end
% End initialization code - DO NOT EDIT
end

% --- Executes just before goal_def_test is made visible.
function goal_def_test_OpeningFcn(hObject, eventdata, handles, varargin)
% This function has no output args, see OutputFcn.
% hObject    handle to figure
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)
% varargin   command line arguments to goal_def_test (see VARARGIN)

% Choose default command line output for goal_def_test
handles.output = hObject;

%% GET THE INITIAL GEOMETRY DATA
disp('varargin')
if numel(varargin) == 0
    load('WiscPlan_preferences.mat')
    [handles.Data.Geo_fileName,handles.Data.Geo_path,FilterIndex] = uigetfile([WiscPlan_preferences.patientDataPath '\matlab_files\*.mat'], 'Select Geometry file');
    load([handles.Data.Geo_path, handles.Data.Geo_fileName]);
    eval('handles.Data.Geometry = Geometry;')
end


%% POPULATE THE TABLE 
% == populate ROI options ==
for i = 1: numel(Geometry.ROIS)
    handles.uitable1.ColumnFormat{2}{i} = Geometry.ROIS{i}.name;
end
% == populate function options ==
handles.uitable1.ColumnFormat{5}{1} = 'min';
handles.uitable1.ColumnFormat{5}{2} = 'max';
handles.uitable1.ColumnFormat{5}{3} = 'min_sq';
handles.uitable1.ColumnFormat{5}{4} = 'max_sq';
handles.uitable1.ColumnFormat{5}{5} = 'min_step';
handles.uitable1.ColumnFormat{5}{6} = 'max_step';
handles.uitable1.ColumnFormat{5}{7} = 'LeastSquare';
handles.uitable1.ColumnFormat{5}{8} = 'min_perc_Volume';
handles.uitable1.ColumnFormat{5}{9} = 'max_perc_Volume';
handles.uitable1.ColumnFormat{5}{8} = 'min_sq_voxwgt';
handles.uitable1.ColumnFormat{5}{9} = 'max_sq_voxwgt';

% == populate the first entry ==
handles.uitable1.Data = handles.uitable1.Data(1,:);
handles.uitable1.Data{1} = 'Goal 1';
handles.uitable1.Data{2} = 'Target';
handles.uitable1.Data{3} = 'Fixed dose';
handles.uitable1.Data{4} = '60';
handles.uitable1.Data{5} = 'min_sq';
handles.uitable1.Data{6} = 100;
handles.uitable1.Data{7} = 'null';
handles.uitable1.Data{8} = 0;
handles.uitable1.Data{9} = 0;

% populate the drop-down
% handles.popupmenu2.String = {"test 1","test 2"};
set(handles.optSelect_popup, 'String', {"RO max", "RO mean", "RO objective-based", "Classical"});

% Update handles structure
guidata(hObject, handles);

% UIWAIT makes goal_def_test wait for user response (see UIRESUME)
% uiwait(handles.figure1);
end

% --- Outputs from this function are returned to the command line.
function varargout = goal_def_test_OutputFcn(hObject, eventdata, handles) 
% varargout  cell array for returning output args (see VARARGOUT);
% hObject    handle to figure
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)

% Get default command line output from handles structure
varargout{1} = handles.output;
end

% --- Executes on button press in addRow.
function addRow_Callback(hObject, eventdata, handles)
% adds new empty row to table
handles.uitable1.Data{end+1, 1} = ['Goal ' num2str(size(handles.uitable1.Data,1)+1)];
end
% --- Executes on button press in removeRow.
function removeRow_Callback(hObject, eventdata, handles)
% Removes row number selected by Remove_row_N
newTable = handles.uitable1.Data;
rowToDelete = str2double(handles.Remove_row_N.String);
if rowToDelete>size(newTable, 1)
    disp(['No row ' num2str(rowToDelete)])
else
    newTable(rowToDelete,:) = [];
    handles.uitable1.Data = newTable;
end
end
function Remove_row_N_Callback(hObject, eventdata, handles)
% Identifies what is the number for removing a row and checks validty of
% input.
num = str2double(handles.Remove_row_N.String);
if isnan(num)
    disp('You''re a silly goose. Enter a number.')
elseif num<1
    disp('Row number must be greater than 0')
    num = 1;
    handles.Remove_row_N.String = 1;
else
    r = rem(num, 1);
    if r ~= 0
        disp('Enter an integer, duh.')
        num = round(num);
        handles.Remove_row_N.String = round(num);
    end
    disp(num)
end
end

% --- Executes on button press in Save_goal_button.
function Save_goal_button_Callback(hObject, eventdata, handles)
% hObject    handle to Save_goal_button (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)
Save_goal_function(handles);
end
function Save_goal_function(handles)
% this function creates and outputs the OptGoals file

[file,path,indx] = uiputfile([handles.Data.Geo_path, '*.mat'],'Choose where to save OptGoals');
OptGoals.geometryPath = [handles.Data.Geo_path handles.Data.Geo_fileName];

disp('Loading Geometry ...')
load([OptGoals.geometryPath])
% disp('Loading beamlets ...')
% [beamlets, beamlets_joined, numBeamlet, numBeam, beam_i_list] = get_beam_lets(Geometry, Geometry.patient_dir);

OptGoals.data={};
for i = 1 : size(handles.uitable1.Data, 1)
    % -- START DEFINITION OF GOAL --
    % == goal name
    goal_i.name = handles.uitable1.Data{i,1};
    % == ROI name
    goal_i.ROI_name = handles.uitable1.Data{i,2};
    % == ROI index
    for j = 1:size(Geometry.ROIS,2)
        if strcmp(Geometry.ROIS{j}.name, handles.uitable1.Data{i,2})
            goal_i.ROI_idx = Geometry.ROIS{j}.ind;
            break
        end
        if j == size(Geometry.ROIS,2)
            error(['Invalid ROI name selected in goal ' num2str(i)])
        end
    end
    % == image dimensions
    goal_i.imgDim = size(Geometry.data);
    % == goal dose
    if strcmp (handles.uitable1.Data{i,3}, 'Fixed dose')
        goal_i.D_final = str2double(handles.uitable1.Data{i,4}) * ones(size(goal_i.ROI_idx));
    elseif strcmp (handles.uitable1.Data{i,3}, 'Dose map')
%         warning('Works only for NRRD (for now)')
        dose_in = nrrdread(handles.uitable1.Data{i,4});
        colorwash(Geometry.data-1000, dose_in, [-500, 500], [0, 1.0*(max(dose_in(:)))], 1, goal_i.name)
        goal_i.D_final = dose_in(goal_i.ROI_idx);
        % loading of data comes here
        % matrix size checks
    end
    % == goal penalty function
    goal_i.function = handles.uitable1.Data{i,5};
    
    % == goal penalty function
    if strcmp (handles.uitable1.Data{i,5}, 'min_sq_voxwgt')
        handles.uitable1.Data{i,2};
        voxwgt_in = nrrdread(handles.uitable1.Data{i, 7});
%         load(handles.uitable1.Data{i, 7});
%         voxwgt_in = miTLM_3;
        goal_i.wgt_map = voxwgt_in(goal_i.ROI_idx);
        goal_i.wgt_map = goal_i.wgt_map / mean(goal_i.wgt_map(:)); % normalize
        
    elseif strcmp (handles.uitable1.Data{i,5}, 'max_sq_voxwgt')
        voxwgt_in = nrrdread(handles.uitable1.Data{i, 7});
%         load(handles.uitable1.Data{i, 7});
%         voxwgt_in = miTLM_3;
        goal_i.wgt_map = voxwgt_in(goal_i.ROI_idx);
        goal_i.wgt_map = goal_i.wgt_map / mean(goal_i.wgt_map(:)); % normalize
    else
        if isfield (goal_i, 'wgt_map')
            goal_i = rmfield(goal_i, 'wgt_map');
        end
    end
    
    % == goal weight
    goal_i.opt_weight = handles.uitable1.Data{i,6} / numel(goal_i.ROI_idx); % normalize to volume of target area
    % == optional
    goal_i.optionalParam = handles.uitable1.Data{i,7};
    % == Number of supervoxels
    goal_i.SupVox_num = handles.uitable1.Data{i,9};
    
    % -- END DEFINITION OF GOAL -- 
    % assign target
    OptGoals.data{end+1}=goal_i;

end
disp('-- all OptGoals exported!')

OptGoals.goals = [handles.uitable1.Data];
OptGoals.maxModulation = str2double(handles.maxModulation.String);
OptGoals.BeamSmoothMax = str2double(handles.BeamSmoothMax.String);

OptGoals.optFunc = handles.optSelect_popup.String{handles.optSelect_popup.Value};
switch OptGoals.optFunc
    case "RO max"
        OptGoals.optFuncNum = 1;
    case "RO mean"
        OptGoals.optFuncNum = 2;
    case "RO objective-based"
        OptGoals.optFuncNum = 3;
    case "Classical"
        OptGoals.optFuncNum = 4;
end

OptGoals.sss.Y = handles.sss_Y.String;
OptGoals.sss.X = handles.sss_X.String;
OptGoals.sss.Z = handles.sss_Z.String;
sss_scene_list={[0,0,0]};
Num = sscanf(handles.sss_Y.String, '%g,').';
for i=1:numel(Num)
    sss_scene_list{end+1}=[Num(i),0,0];
end
Num = sscanf(handles.sss_X.String, '%g,').';
for i=1:numel(Num)
    sss_scene_list{end+1}=[0,Num(i),0];
end
Num = sscanf(handles.sss_Z.String, '%g,').';
for i=1:numel(Num)
    sss_scene_list{end+1}=[0,0,Num(i)];
end

OptGoals.sss_scene_list = sss_scene_list;


save( [path, file], 'OptGoals')
end


% --- Executes on button press in Load_goal_button.
function Load_goal_button_Callback(hObject, eventdata, handles)
% hObject    handle to Load_goal_button (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)
[file,path,indx] = uigetfile([handles.Data.Geo_path, '*.mat'],'Choose OptGoals to load');
load( [path, file])
disp('load goal')

handles.uitable1.Data = OptGoals.goals;
handles.maxModulation.String = num2str(OptGoals.maxModulation);

handles.sss_Y.String = OptGoals.sss.Y;
handles.sss_X.String = OptGoals.sss.X;
handles.sss_Z.String = OptGoals.sss.Z;

if isfield(OptGoals, 'BeamSmoothMax')
    handles.BeamSmoothMax.String = num2str(OptGoals.BeamSmoothMax);
end
end


% --- Executes when entered data in editable cell(s) in uitable1.
function uitable1_CellEditCallback(hObject, eventdata, handles)
% hObject    handle to uitable1 (see GCBO)
% eventdata  structure with the following fields (see MATLAB.UI.CONTROL.TABLE)
%	Indices: row and column indices of the cell(s) edited
%	PreviousData: previous data for the cell(s) edited
%	EditData: string(s) entered by the user
%	NewData: EditData or its converted form set on the Data property. Empty if Data was not changed
%	Error: error string when failed to convert EditData to appropriate value for Data
% handles    structure with handles and user data (see GUIDATA)

% --- update DP or fixed dose goals
if eventdata.Indices(2) == 3;
    mode = handles.uitable1.Data{eventdata.Indices(1), eventdata.Indices(2)}
    switch mode
        case 'Dose map'
            [FileName,PathName,FilterIndex] = uigetfile('F:\021_WiscPlan_data\FET_repeat_005_1\matlab_files\*.mat', 'Select dose reference file');
            warning('loading of said profile comes here')
            handles.uitable1.Data{eventdata.Indices(1), 4} = [PathName, FileName];
            
        case 'Fixed dose'
            answer = inputdlg('Enter desired goal dose');
            handles.uitable1.Data{eventdata.Indices(1), 4} = answer{1};
            
        otherwise
            error('This doesnt work')
    end
end

% --- update DP or fixed dose goals
if eventdata.Indices(2) == 5;
    mode = handles.uitable1.Data{eventdata.Indices(1), eventdata.Indices(2)}
    switch mode
        case 'min_sq_voxwgt'
            [FileName,PathName,FilterIndex] = uigetfile('F:\021_WiscPlan_data\FET_repeat_005_1\matlab_files\*.mat', 'Select voxel weight map');
            handles.uitable1.Data{eventdata.Indices(1), 7} = [PathName, FileName];
            
        case 'max_sq_voxwgt'
            [FileName,PathName,FilterIndex] = uigetfile('F:\021_WiscPlan_data\FET_repeat_005_1\matlab_files\*.mat', 'Select voxel weight map');
            handles.uitable1.Data{eventdata.Indices(1), 7} = [PathName, FileName];
            
        otherwise
    end
end

% --- update with number of voxels
if eventdata.Indices(2) == 2;
    for i = 1:size(handles.Data.Geometry.ROIS,2)
        if strcmp(handles.Data.Geometry.ROIS{i}.name, handles.uitable1.Data{eventdata.Indices(1),2})
            ROI_idx_num = numel(handles.Data.Geometry.ROIS{i}.ind);
            break
        end
        if i == size(handles.Data.Geometry.ROIS,2)
            error(['Invalid ROI name selected in goal ' num2str(i)])
        end
    end
    
    handles.uitable1.Data{eventdata.Indices(1), 8} = ROI_idx_num;
    handles.uitable1.Data{eventdata.Indices(1), 9} = 0;
end


end



function maxModulation_Callback(hObject, eventdata, handles)
% hObject    handle to maxModulation (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)

% Hints: get(hObject,'String') returns contents of maxModulation as text
%        str2double(get(hObject,'String')) returns contents of maxModulation as a double
end

% --- Executes during object creation, after setting all properties.
function maxModulation_CreateFcn(hObject, eventdata, handles)
% hObject    handle to maxModulation (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    empty - handles not created until after all CreateFcns called

% Hint: edit controls usually have a white background on Windows.
%       See ISPC and COMPUTER.
if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
    set(hObject,'BackgroundColor','white');
end
end


function sss_Y_Callback(hObject, eventdata, handles)
% hObject    handle to sss_Y (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)

% Hints: get(hObject,'String') returns contents of sss_Y as text
%        str2double(get(hObject,'String')) returns contents of sss_Y as a double
end

% --- Executes during object creation, after setting all properties.
function sss_Y_CreateFcn(hObject, eventdata, handles)
% hObject    handle to sss_Y (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    empty - handles not created until after all CreateFcns called

% Hint: edit controls usually have a white background on Windows.
%       See ISPC and COMPUTER.
if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
    set(hObject,'BackgroundColor','white');
end
end


function sss_X_Callback(hObject, eventdata, handles)
% hObject    handle to sss_X (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)

% Hints: get(hObject,'String') returns contents of sss_X as text
%        str2double(get(hObject,'String')) returns contents of sss_X as a double
end

% --- Executes during object creation, after setting all properties.
function sss_X_CreateFcn(hObject, eventdata, handles)
% hObject    handle to sss_X (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    empty - handles not created until after all CreateFcns called

% Hint: edit controls usually have a white background on Windows.
%       See ISPC and COMPUTER.
if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
    set(hObject,'BackgroundColor','white');
end
end


function sss_Z_Callback(hObject, eventdata, handles)
% hObject    handle to sss_Z (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)

% Hints: get(hObject,'String') returns contents of sss_Z as text
%        str2double(get(hObject,'String')) returns contents of sss_Z as a double
end

% --- Executes during object creation, after setting all properties.
function sss_Z_CreateFcn(hObject, eventdata, handles)
% hObject    handle to sss_Z (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    empty - handles not created until after all CreateFcns called

% Hint: edit controls usually have a white background on Windows.
%       See ISPC and COMPUTER.
if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
    set(hObject,'BackgroundColor','white');
end
end



function BeamSmoothMax_Callback(hObject, eventdata, handles)
% hObject    handle to BeamSmoothMax (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)

% Hints: get(hObject,'String') returns contents of BeamSmoothMax as text
%        str2double(get(hObject,'String')) returns contents of BeamSmoothMax as a double
end


% --- Executes on selection change in optSelect_popup.
function optSelect_popup_Callback(hObject, eventdata, handles)
% hObject    handle to optSelect_popup (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)

% Hints: contents = cellstr(get(hObject,'String')) returns optSelect_popup contents as cell array
%        contents{get(hObject,'Value')} returns selected item from optSelect_popup
end

% --- Executes during object creation, after setting all properties.
function optSelect_popup_CreateFcn(hObject, eventdata, handles)
% hObject    handle to optSelect_popup (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    empty - handles not created until after all CreateFcns called

% Hint: popupmenu controls usually have a white background on Windows.
%       See ISPC and COMPUTER.
if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
    set(hObject,'BackgroundColor','white');
end
end