function ResumeGraphMO
    % read data from log file AppLog.xml
    [XArray, YArray, status] = GetCompletedData();
    if(status == 0)
        % dislay graph
        status = DisplayCompletedData(XArray, YArray);
        if(status ~= 0)
            return;
        end
         % display message box
        choice = questdlg('Do you want to resume the program?', 'Resume program', 'Yes', 'No', 'Yes');
        switch choice
            case 'Yes'
                result = ResumeProgram();
                if (result == 1)
                    return;
                end
            case 'No'
                % do nothing
                return;
        end
    else
        return;
    end

end

function [status] = ResumeProgram()
    status = 0;
try
%------------------- INITIALIZE DATA --------------------------------------
    status = InitializeVariables();
    % if we have errors
    if(status == 1)
       return;
    end
    
 %------------------------- DRAW GRAPH ------------------------------------
    
    status = DrawCurrentData();
    % if the task fails, exit application
    if(status == 1)
        return;
    end
   
catch err
     % display message when we have exceptions
     msg = getReport(err);
     disp(msg);
     % delete waitbar
     global progressBar;
     if(ishandle(progressBar) == 1)
         delete(progressBar);
     end

end

end



function [status] = InitializeVariables()
status = 0;
try
   
    % progress bar
    global progressBar;
    
    % values to draw graph and log
    global XToDraw;
    global YToDraw;
    
    % unprocessed points
    global UnprocessedX;
    global UnprocessedY;
    global NumberOfPoints;
    
    [UnprocessedX, UnprocessedY, status] = GetUnprocessedData();
        
catch err
    disp('ERROR: Cannot initialize Matlab variables.');
    status = 1;
end

end




% get unprocessed data from log file AppLog.xml
function [UnprocessedX, UnprocessedY, status] = GetUnprocessedData()
status = 0;
try
      xDoc = xmlread('AppLog.xml');
        % root Node
        xRoot = xDoc.getDocumentElement;
        % get node UnprocessedJobs
        UnprocessedJobsNode = xRoot.getChildNodes.item(5);
        % get all node X
        xNodes = UnprocessedJobsNode.getElementsByTagName('X');
        % get all node Y
        yNodes = UnprocessedJobsNode.getElementsByTagName('Y');
        n = xNodes.getLength;
        % if we don't have any unprocessed job
        if(n == 0)
            % do nothing
            return;
        end
        count = 1;
        % read all the node X, and store values into failedX
        for i = 0:n-1
            % get current value of node X
            x = str2num(xNodes.item(i).getTextContent);
            % get current value of node Y
            y = str2num(yNodes.item(i).getTextContent);
            % add x values to UnprocessedX
            UnprocessedX(count) = x;
            % add y values to UnprocessedY
            UnprocessedY(count) = y;
            count = count + 1;
        end
        
        global NumberOfPoints;
        NumberOfPoints = length(UnprocessedX);
catch err
      disp('ERROR: Cannot read data in node UnprocessedJobs from log file AppLog.xml');
        % display exception
        % display message when we have exceptions
        msg = getReport(err);
        disp(msg);
        status = 1;
end

end

% draw current new points from XArray and YArray
function [status] = DrawCurrentData()
    status = 0;
try
    global NumberOfPoints;
    global progressBar;
    global XToDraw;
    global YToDraw;
    global UnprocessedX;
    global UnprocessedY;
    % create progress bar
    progressBar = waitbar(0, 'Please wait...', 'CreateCancelBtn', 'setappdata(gcf, ''abort'',1);', 'WindowStyle', 'normal');
        % set bar always on top
            %frames = java.awt.Frame.getFrames();
            %frames(end).setAlwaysOnTop(1);
        % set initial value for param 'abort'
        setappdata(progressBar,'abort',0);
        
    % process every 5 points
    bunchSize = 5;
    % start index of array
    count = 1;
    
    % repeat the loop until all jobs completed
    while true
        % get next 5 jobs
        rear = count + bunchSize - 1;
        if(rear > NumberOfPoints)
            rear = NumberOfPoints;
        end
        
        XToDraw = UnprocessedX(count: rear);
        YToDraw = UnprocessedY(count: rear);
        
        % write new points to log file
        status = WriteLog(XToDraw, YToDraw, rear, NumberOfPoints);
        if(status == 1)
            return;
        end
        % draw new points to graph
        status = PlotXY(XToDraw, YToDraw, rear, NumberOfPoints);
        hold on;
        if(status == 1)
            return;
        end
        
        
        count = rear + 1;
        
        % display progress bar
        waitbar(rear/NumberOfPoints, progressBar, [sprintf('Completed: %.2f', rear*100/NumberOfPoints), '%']);
        % when click on Cancel button, stop here
        if(getappdata(progressBar, 'abort') == 1)
            break;
        end;
             
        
        % if all the points are drawn, we are done
        if(count >= NumberOfPoints)
            break;
        end
        
        % delay 3s
        pause(1);
    end
    % remove progress bar
    delete(progressBar);
catch err
    disp('ERROR: Cannot draw current data.');
    status = 1;
end
    

end

% log data into file AppLog.xml
function [status] = WriteLog(XToDraw, YToDraw, currentIndex, NumberOfPoints)
    % log completed jobs
    status = LogCompletedJobs(XToDraw, YToDraw);
    if(status == 1)
        return;
    end
    % log unprocessed jobs
    status = LogUnprocessedJobs(currentIndex, NumberOfPoints);
    if(status == 1)
        return;
    end
    % remove extra white spaces in log file AppLog.xml
    status = RemoveSpace('AppLog.xml');
    % exit function if fail
    if(status == 1)
        return;
    end

end

%The extra whitespace is introduced by the Saxon XML processor, 
% which is the library that MATLAB uses for the XML processing.
function [status] = LogCompletedJobs(XToDraw, YToDraw)
    status = 0;
    
try
    % write the completed jobs to AppLog.xml
    xDoc = xmlread('AppLog.xml');
    % get the 'LogInfo' node
    xRoot = xDoc.getDocumentElement;
    % get the 'CompletedJobs' node
    completedJobNode = xRoot.getChildNodes.item(1);
    % append child to completeJob node
    for i=1: length(XToDraw)
        % create Job node
        jobNode = xDoc.createElement('CompletedJob');
            % create X node
            xNode = xDoc.createElement('X');
            % add value to X node
            xNode.appendChild(xDoc.createTextNode(num2str(XToDraw(i))));
            jobNode.appendChild(xNode);
            % create Y node
            yNode = xDoc.createElement('Y');
            % add value to Y node
            yNode.appendChild(xDoc.createTextNode(num2str(YToDraw(i))));
            jobNode.appendChild(yNode);
        % append Job node to CompletedJob node
        completedJobNode.appendChild(jobNode);      
    end
    
     % write data to file AppLog.xml
     xmlwrite('AppLog.xml',xDoc);
    
catch err
    status = 1;
    disp('ERROR: Cannot write completed jobs to AppLog.xml');
    % display message when we have exceptions
     msg = getReport(err);
     disp(msg);
end
end    

function [status] = LogUnprocessedJobs(currentIndex, NumberOfPoints)
    status = 0;
    global UnprocessedX;
    global UnprocessedY;
try
    % write the unprocessed jobs to AppLog.xml
    xDoc = xmlread('AppLog.xml');
    % get the node 'LogInfo'
    xRoot = xDoc.getDocumentElement;
    % get the node 'UnprocessedJobs'
    unprocessedJobNode = xRoot.getChildNodes.item(5);
    % remove node UnprocessedJobs and all its children
    xRoot.removeChild(unprocessedJobNode);
    % create new node UnprocessedJobs
    unprocessedJobNode = xDoc.createElement('UnprocessedJobs');
    % append child to node UnprocessedJobs
    for i = currentIndex + 1: NumberOfPoints
            % create UnprocessedJob node
            jobNode = xDoc.createElement('UnprocessedJob');
            % create X node
            xNode = xDoc.createElement('X');
            % add value to X node
            xNode.appendChild(xDoc.createTextNode(num2str(UnprocessedX(i))));
            jobNode.appendChild(xNode);
             % create Y node
            yNode = xDoc.createElement('Y');
            % add value to Y node
            yNode.appendChild(xDoc.createTextNode(num2str(UnprocessedY(i))));
            jobNode.appendChild(yNode);
        % append Job node to UnprocessedJobs node
        unprocessedJobNode.appendChild(jobNode);
       
    end
    % append new node UnprocessedJobs to document
    xRoot.appendChild(unprocessedJobNode);
    % write data to file AppLog.xml
    xmlwrite('AppLog.xml', xDoc);
    
catch err
    status = 1;
    disp('ERROR: Cannot write unprocessed jobs to AppLog.xml');
    % display message when we have exceptions
     msg = getReport(err);
     disp(msg);
end
end


function [status] = PlotXY(XToDraw, YToDraw, currentIndex, NumberOfPoints)

status = 0;

try
    strComplete = sprintf('Percentage of Completion: %.2f%', currentIndex*100/NumberOfPoints);
    plot(XToDraw, YToDraw, '.-r','LineStyle','none', 'MarkerFaceColor','r');
    title(strComplete);
    xlabel('X value');
    ylabel('Y value');

catch err
    disp('ERROR: Cannot draw new points.');
    status = 1;
end
end

% remove spaces in the application log file AppLog.xml
function [status] = RemoveSpace(filePath)
    status = 0;
    try
        % Read file.
        fId = fopen(filePath, 'r');
        fileContents = fread(fId, '*char')';
        fclose(fId);

        % Write new file.
        fId = fopen(filePath, 'w');
        % Remove extra lines.
        fwrite(fId, regexprep(fileContents, '\n\s*\n', '\n'));
        fclose(fId);
    catch err
        msg = sprintf('ERROR: Error when remove white spaces in the file %s', filePath);
        disp(msg);
        status = 1;
    end
end

% display existing points from file AppLog.xml
function [xArray, yArray, success] = GetCompletedData()
    xArray = [];
    yArray = [];
    success = 0;
    
    try
        
        xDoc = xmlread('AppLog.xml');
        % root Node
        xRoot = xDoc.getDocumentElement;
        % get node CompletedJobs
        CompletedJobsNode = xRoot.getChildNodes.item(1);
        % get all node X
        xNodes = CompletedJobsNode.getElementsByTagName('X');
        % get all node Y
        yNodes = CompletedJobsNode.getElementsByTagName('Y');
        
        n = xNodes.getLength;
        if(n == 0)
            success = 1;
            return;
        end
        count = 1;
        % read all the node X, Y and store values into xArray and yArray
        for i = 0:n-1
            % get current value of node X
            x = str2num(xNodes.item(i).getTextContent);
            % get current value of node Y
            y = str2num(yNodes.item(i).getTextContent);
            % add x and y values to xArray and yArray
            xArray(count) = x;
            yArray(count) = y;
            count = count + 1;
        end
        

    catch err
        disp('ERROR: Cannot read data from log file AppLog.xml');
        % display exception
        % display message when we have exceptions
        msg = getReport(err);
        disp(msg);
        success = 1;
    end
end

% display the last completed points before the application crashed
function [success] = DisplayCompletedData(xArray, yArray)
    success = 0;
    try

        plot(xArray, yArray, '.-r','LineStyle','none', 'MarkerFaceColor','r');
        xlabel('X value');
        ylabel('Y value');
        hold on;
        
    catch err
        disp('ERROR: Cannot display graph');
        success = 1;
    end

end
