classdef AddRoi < handle
    properties(Constant)  %Properties for each ROI, the number is choosen to coicides with the souffix of images in the path
        % for ROI_OUT_SCREEN,ROI_OUT_DISPLAYEBLE, ROI_OUT_ROI there is no
        % path
        ROI_FIRST           = 1;
        ROI_RIGHT_EYE       = 1;
        ROI_LEFT_EYE        = 2;
        ROI_RIGHT_BROW      = 3;
        ROI_MOUTH           = 4;
        ROI_CHIN            = 5;
        ROI_NOSE            = 6;
        ROI_LEFT_BROW       = 7;
        ROI_CORRUGATOR      = 8;
        ROI_FRONT           = 9;
        ROI_LAST            = 9;
        ROI_OUT             = 10;
        ROI_OUT_OF_ROI      = 11;
        ROI_OUT_DISPLAYEBLE = 12;
        ROI_OUT_SCREEN      = 13;
        ROI_TOT             = 13;
    end
    
    properties(Constant)  %Properties for dimentions of the screen and the video of presentation screen, used in experiments
        SCREEN_WIDTH        = 1024;
        SCREEN_HIGHT        = 768;
        DISPLAYEBLE_WIDTH   = 768; %rozmery stim obrazu
        DISPLAYEBLE_HIGHT   = 576;
    end
    
    properties            %Properties for structures and parameters of the screen and video
        eventFix            = [];
        aviVideo            = [];
        displayable_x1      = 0;
        displayable_x2      = 0;
        displayable_y1      = 0;
        displayable_y2      = 0;
        
    end
        
    methods
        
        %Prepare EventFix_Dynemo.mat for treatment
        function this = AddRoi(varargin)
            %Fix coordinations of screen and video
            this.displayable_x1     = (AddRoi.SCREEN_WIDTH  - AddRoi.DISPLAYEBLE_WIDTH)/2;
            this.displayable_x2     =  this.displayable_x1  + AddRoi.DISPLAYEBLE_WIDTH;
            this.displayable_y1     = (AddRoi.SCREEN_HIGHT  - AddRoi.DISPLAYEBLE_HIGHT)/2;
            this.displayable_y2     =  this.displayable_y1  + AddRoi.DISPLAYEBLE_HIGHT;
            %Load EventFix_Dynemo.mat
            allData                 = load(varargin{1});
            %Remouve static part: EFE1 and EFE2
            for ii=2:length(varargin)
                allData.EventFix    = rmfield(allData.EventFix, varargin{ii});
            end
            this.eventFix           = allData.EventFix; %Make temporary structure
        end
        
        %Call function ScanFixation for each condition, place ROIs and save
        %it in EventFix_Dynemo_Dest.mat
        function Process(this, roiDir, ROIS, fixAllDataFileDst)
            %modes here is our conditions. In the beginning they are 4, but
            %we remove static part, so we will work with dinamic part -
            %EFED1 and EFED2
            modes   = fieldnames(this.eventFix);
            for ii=1:length(modes)
                this.eventFix.(modes{ii})   = this.ScanFixations(roiDir, ROIS, this.eventFix.(modes{ii}));
            end
            EventFix = this.eventFix;
            save(fixAllDataFileDst, 'EventFix');
        end
        
    end
    
    methods(Access=private)
        %Load path with masks, EventFix_Dynemo and make a new srtucture ROIS {1x9 cell}
        function eventFixRet = ScanFixations(this, roiDir, ROIS, eventFix)
            eventFixRet      = eventFix;
            
            %Returns a cell array of strings containing the structure field subjects associated with the structure eventFix.
            subjects = fieldnames(eventFixRet);
           
            %Pass over all subjects
            for iSubj=1:length(subjects)
                images = eventFixRet.(subjects{iSubj});
                %For each video in every subject
                for iImage=1:length(images)
                    image = images(iImage);
                    
                    %Print on the screen curent numer of subject(total
                    %number of subjects in this mode);
                    %curent video in this subject(total number of videos in
                    %this subject); name of the subject; true name of the
                    %video
                    fprintf('IndSybject = %d(%d); IndImage = %d(%d); Subject = %s; True image name = %s\n', iSubj, length(subjects), iImage, length(images), subjects{iSubj}, image.TrueName);
                    %Remove distractors videos
                    if(strcmpi(image.Nature, 'distracteur'))
                        continue;
                    else
                        %Take the index of true name video
                        imageInd    = image.TrueName(7:end);
                        imageInd    = str2num(imageInd);
                        
                        %Search videos, whos names start with original name
                        %and have suffix _mask
                        dirMaskName = [roiDir '\' image.TrueName '_mask'];
                        if(exist(dirMaskName, 'dir') ~= 7)
                            continue;
                        end
                        
                        %Make a structure in the curent subject, called
                        %Roi with the same size like Tab
                        eventFixRet.(subjects{iSubj})(iImage).Roi   = cell(1, size(image.Tab, 2));
                        %For each video take the n° of the frame, where start
                        %the fixation fix and n° of the frame, where finish
                        %the fixation fix, make a structure: Roi 
                        
                        fprintf('fixations = %d ', size(image.Tab, 2));
                        
                        for iFix=1:size(image.Tab, 2)
%                             firstFrame      = image.Frame(1, iFix);
%                             lastFrame       = image.Frame(3, iFix);
                            jFIX=1;
                            duration=image.Tab(4, iFix);
                            eventFixRet.(subjects{iSubj})(iImage).Roi{iFix}  = zeros(AddRoi.ROI_TOT, jFIX);%duration %Put zeros in the matrice
                            
                            fixX            = round(image.Tab(2, iFix));
                            fixY            = round(image.Tab(3, iFix));
                            fixX            = fixX + this.displayable_x1 - 1;
                            fixY            = fixY + this.displayable_y1 - 1;
                            
                            %Conditions for fixations: to be in the screen
                            %and in the video, if no put -2 or -1
                            if((fixX < 0) || (fixY < 0) || (fixX >= AddRoi.SCREEN_WIDTH) || (fixY >= AddRoi.SCREEN_HIGHT))
                                eventFixRet.(subjects{iSubj})(iImage).Roi{iFix}(AddRoi.ROI_OUT_SCREEN, :)       = 1;
                                eventFixRet.(subjects{iSubj})(iImage).Roi{iFix}(AddRoi.ROI_OUT, :)              = 1;
                            elseif((fixX < this.displayable_x1) || (fixY < this.displayable_y1) || (fixX >= this.displayable_x2) || (fixY >= this.displayable_y2))
                                eventFixRet.(subjects{iSubj})(iImage).Roi{iFix}(AddRoi.ROI_OUT_DISPLAYEBLE, :)	= 1;
                                eventFixRet.(subjects{iSubj})(iImage).Roi{iFix}(AddRoi.ROI_OUT, :)              = 1;
                            else
                                fixX            = round(image.Tab(2, iFix));
                                fixY            = round(image.Tab(3, iFix));

                                fprintf('%d(%d) ', iFix, duration);
                                %od prvního framu ke poslednímu 
                                   
                                    %Pass from the first Roi to the last,
                                    %search if there is binary file and if
                                    %the fixation enter in the ROI, place 1 in
                                    %the matrice
                                  %  iFrm 	= frm - firstFrame + 1;
                                  
                                    for iRoi=AddRoi.ROI_FIRST:AddRoi.ROI_LAST                                       
                                        maskFile     = sprintf('%s\\%s\\video_%d_binary_mask_%03d_000062.png.mat', dirMaskName, ROIS{iRoi}, imageInd, iRoi);
                                        if(exist(maskFile, 'file') == 2)
                                            load(maskFile);
                                            if(pngParams.bmp(fixY, fixX))
                                                eventFixRet.(subjects{iSubj})(iImage).Roi{iFix}(iRoi, jFIX)             = 1;
                                            end
                                        end
                                    end
                                 
                                    nbRoi   = sum(eventFixRet.(subjects{iSubj})(iImage).Roi{iFix}(1:AddRoi.ROI_LAST, jFIX) > 0);
                                    if(nbRoi > 1)
                                        colFrame                                                                        = eventFixRet.(subjects{iSubj})(iImage).Roi{iFix}(1:AddRoi.ROI_LAST, jFIX);
                                        colFrame(colFrame == 1)                                                         = 1/nbRoi;
                                        eventFixRet.(subjects{iSubj})(iImage).Roi{iFix}(1:AddRoi.ROI_LAST, jFIX)        = colFrame;
                                    elseif(nbRoi < 1)
                                        eventFixRet.(subjects{iSubj})(iImage).Roi{iFix}(AddRoi.ROI_OUT, jFIX)           = 1;
                                        eventFixRet.(subjects{iSubj})(iImage).Roi{iFix}(AddRoi.ROI_OUT_OF_ROI, jFIX)	= 1;
                                    end

                            end
                              
                              eventFixRet.(subjects{iSubj})(iImage).Roi{iFix}=repmat(eventFixRet.(subjects{iSubj})(iImage).Roi{iFix},1,duration);
                            end
                        end
                        fprintf('\n');
                    end
                end
            end
        end
    
    
    methods(Static)
        %Make binarisation of Roi png files and save the resolt in mat
        %file. To be executed, start ExeStep1PngToBmp.m
        function Png2Bin(srcDir)
            files = dir(srcDir);
            for ii=3:length(files)
                file    = [srcDir '\' files(ii).name];
                if(files(ii).isdir)
                    AddRoi.Png2Bin(file);
                else
                    [~, ~, ext] = fileparts(file);
                    if(strcmpi(ext, '.png'))
                        fprintf('Processing %s\n', file);
                        pngRgb          = imread(file);
                        pngParams.bmp   = im2bw(pngRgb);
                        save([file '.mat'], 'pngParams');
                    end
                end
            end
        end
    end
end
 


