classdef(Sealed, Hidden) ReportDialog < handle
    %REPORTDIALOG Dialog for selecting Report Sections
    
    %Copyright 2017 The MathWorks, Inc.
    
    % Properties that correspond to components
    properties (Access = private)
        Session
        Figure                          matlab.ui.Figure
        ReportFormatDropDownLabel       matlab.ui.control.Label
        ReportFormatDropDown            matlab.ui.control.DropDown
        OKButton                        matlab.ui.control.Button
        CancelButton                    matlab.ui.control.Button
        TimeSeriesTable                 matlab.ui.control.Table
        ModelTable                      matlab.ui.control.Table
        Listeners                       cell
    end

    
    methods
        % App initialization and construction
        % Create Figure and components
        function this = ReportDialog(session)

            this.Session = session;
            
            % Create Figure
            this.Figure = uifigure('Name',getString(message('econ:econModeler:ReportInstructions')),...
                'Position',[100 100 641 243],...
                'CloseRequestFcn',@this.closeCallback,...
                'Tag','reportDialog',...
                'UserData',@(x,y)this.qeCheckVariables(x,y),...
                'WindowStyle','modal',...
                'Visible','off');

            matlab.graphics.internal.themes.figureUseDesktopTheme(this.Figure);
            
            grid = uigridlayout(this.Figure,[2 1],'RowHeight',{'1x','fit'});
            topRow = uigridlayout(grid,[1 2],'ColumnWidth',{'1x','1x'});
            topRow.Layout.Row = 1;
            bottomRow = uigridlayout(grid,[1 5],'ColumnWidth',{'fit','fit','1x','fit','fit'});
            bottomRow.Layout.Row = 2;
            
            %Create Time Series Table
            ts = this.Session.getAllTimeSeries();
            tsNames = {ts.Name}';
            selectedTS = get(this.Session.SelectedTimeSeries,'Name');
            [~,idxToCheck] =  intersect(tsNames,selectedTS);
            selections = false(length(ts),1);
            selections(idxToCheck) = true;
            tsTableData = [num2cell(selections),tsNames];
            this.TimeSeriesTable = uitable(topRow,...
                'Data',tsTableData,...
                'ColumnName',{getString(message('econ:econModeler:Select')),getString(message('econ:econModeler:TSColumnName'))},...
                'ColumnEditable',[true,false],...
                'CellEditCallback',@this.checkSelections,...
                'Tag','timeseriesTable');
            this.TimeSeriesTable.Layout.Column = 1;
            
            %Create model Table
            mdls = this.Session.getAllModels();
            mdlNames = {mdls.Name}';
            selectedModels = get(this.Session.SelectedModels,'Name');
            [~,idxToCheck] =  intersect(mdlNames,selectedModels);
            selections = false(length(mdls),1);
            selections(idxToCheck) = true;
            mdlTableData = [num2cell(selections),mdlNames];
            this.ModelTable = uitable(topRow,...
                'Data',mdlTableData,...
                'ColumnName',{getString(message('econ:econModeler:Select')),getString(message('econ:econModeler:ModelColumnName'))},...
                'ColumnEditable',[true,false],...
                'CellEditCallback',@this.checkSelections,...
                'Tag','modelTable');
            this.ModelTable.Layout.Column = 2;

            % Create ReportFormatDropDownLabel
            this.ReportFormatDropDownLabel = uilabel(bottomRow,...
                'HorizontalAlignment','right',...
                'Text',getString(message('econ:econModeler:ReportFormat')),...
                'Tag','reportFormatDropDownLabel');
            this.ReportFormatDropDownLabel.Layout.Column = 1;
            
            % Create ReportFormatDropDown
            this.ReportFormatDropDown = uidropdown(bottomRow,...
                'Items',{'PDF','DOCX','HTML'},...
                'Value','PDF',...
                'Tag','reportFormatDropDown');
            this.ReportFormatDropDown.Layout.Column = 2;

            % Create OKButton
            this.OKButton = uibutton(bottomRow,'push',...
                'Text',getString(message('econ:econModeler:OK')),...
                'ButtonPushedFcn',@this.generateReport,...
                'Enable','off',...
                'Tag','okButton');
            this.OKButton.Layout.Column = 4;
           
            % Create CancelButton
            this.CancelButton = uibutton(bottomRow,'push',...
                'Text',getString(message('econ:econModeler:Cancel')),...
                'ButtonPushedFcn',@this.closeFig,...
                'Tag','cancelButton');
            this.CancelButton.Layout.Column = 5;
            
            %Enable OK if there are any selections
            if (~isempty(this.TimeSeriesTable.Data) && any([this.TimeSeriesTable.Data{:,1}])) || ...
                    (~isempty(this.ModelTable.Data) &&any([this.ModelTable.Data{:,1}]))
                this.OKButton.Enable = 'on';
            end
            
            movegui(this.Figure,'center');
            this.Figure.Visible = 'on';
            
            this.Listeners{end+1} = event.listener(this.Session,'AppClosed',@(s,e)closeCallback(this));
        end
    end
    
    methods(Access = private)
        
        function checkSelections(this,~,~)
            if any([[this.TimeSeriesTable.Data{:,1}]';[this.ModelTable.Data{:,1}]'])
                this.OKButton.Enable = 'on';
            else
                this.OKButton.Enable = 'off';
            end
        end
        
        function closeFig(this,~,~)
            close(this.Figure);
        end
        
        function closeCallback(this,~,~)
            this.Session.notify('DialogClosed');
            delete(this.Figure);
            delete(this);
        end
        
        function generateReport(this,~,~)
            import internal.EconModeler.EventData.ReportEventData
            
            %Get all selections to begin report generation
            if ~isempty(this.TimeSeriesTable.Data)
                tsSelections = [this.TimeSeriesTable.Data{:,1}];
                selectedTimeSeries = cellstr(this.TimeSeriesTable.Data(tsSelections,2));
            else
                selectedTimeSeries = cell(0);
            end
            
            if ~isempty(this.ModelTable.Data)
                modelSelections = [this.ModelTable.Data{:,1}];
                selectedModels = cellstr(this.ModelTable.Data(modelSelections,2));
            else
                selectedModels = cell(0);
            end
            
            fileType = this.ReportFormatDropDown.Value;
            fileType = lower(fileType);
            
            %Open the dialog the save the report file
            [file, path] = uiputfile(['*.' fileType]);
            if isnumeric(file)
                this.Figure.Visible = 'off';
                this.Figure.Visible = 'on';
                return;
            end
            
            filePath = [path,file];
            if strcmp(fileType,'html')
                fileType = [fileType,'-file'];
            end
            event = ReportEventData(fileType,filePath,selectedTimeSeries,selectedModels);
            
            %Disable controls while report is being made
            this.ReportFormatDropDown.Enable = 'off';
            this.OKButton.Enable = 'off';
            this.CancelButton.Enable = 'off';
            this.TimeSeriesTable.Enable = 'off';
            this.ModelTable.Enable = 'off';
            closeRequest = this.Figure.CloseRequestFcn;
            this.Figure.CloseRequestFcn = '';
            drawnow;
            
            notify(this.Session,'ReportItemsChosen',event);
            
            %Close the figure
            this.Figure.CloseRequestFcn = closeRequest;
            this.closeFig();
        end
    end
    
    methods(Hidden,Access = public)
        function qeCheckVariables(this,t,selection)
            if strcmpi(t,'Time Series')
                this.TimeSeriesTable.Data{selection,1} = ~this.TimeSeriesTable.Data{selection,1};
            elseif strcmpi(t,'Model')
                this.ModelTable.Data{selection,1} = ~this.ModelTable.Data{selection,1};
            end
            this.checkSelections();
        end
    end
end

