function ResumeGraph3D()
    % clear all temporary files
    status = ClearOldData();
    if(status == 1)
        return;
    end
    
    % display data from the last time application ran
    status = DisplayLastGraph();
    if(status == 1) 
        return;
    end
    
    
    % resume application?
    choice = questdlg('Do you want to resume the program?', 'Resume program', 'Yes', 'No', 'Yes');
        switch choice
            case 'Yes'
                status = ResumeApplication();
                if (status == 1)
                    return;
                end
                % draw histogram
                status = DrawHistogram();
                if(status == 1)
                    return;
                end
            case 'No'
                % do nothing
                return;
        end

end




% draw histogram about running time of all the jobs ALL THE CHUNKS
function [status] = DrawHistogram()
status = 0;
global TOTAL_CHUNKS;
global TOTAL_POINTS;

try
    timeList = zeros(1, TOTAL_POINTS);
    total = 1;
    
    % get all the times in all chunks
    for i=0:TOTAL_CHUNKS
           [status, timeList, total] = GetTimeInChunk(i, timeList, total);
           if(status == 1)
               return;
           end
           
    end
    % truncate the array
    timeList = timeList(1:total-1);   
    % find min, max elements, then draw histogram
    minValue = min(timeList);
    maxValue = max(timeList);
    % divide the time from min to max into every seconds
    group = maxValue - minValue;
    DISTANCE = group + 1;
    if(DISTANCE > 100)
        DISTANCE = 100;
    end
    ranges = linspace(minValue, maxValue, DISTANCE);
    % draw histogram
    figure('name', 'Histogram');
    hist(timeList, ranges);
    % set title and x-label, y-label, and color
    title('Run-time distribution of the jobs');
    xlabel('Run-time(s)');
    ylabel('Number of jobs');
    % set color for histogram
    h = findobj(gca, 'Type', 'patch');
    set(h, 'FaceColor','g','EdgeColor','w');
    
catch err
    msg = getReport(err);
    disp(msg);   
end

end

% draw histogram about running time of all the jobs from start chunk to the
% current chunk
function [status] = DrawHistogramToCurrentChunk(currentChunk)
status = 0;

global TOTAL_POINTS;

try
    timeList = zeros(1, TOTAL_POINTS);
    total = 1;
    
    % get all the times in all chunks
    for i=0:currentChunk
           [status, timeList, total] = GetTimeInChunk(i, timeList, total);
           if(status == 1)
               return;
           end
           
    end
    % truncate the array
    timeList = timeList(1:total-1);   
    % find min, max elements, then draw histogram
    minValue = min(timeList);
    maxValue = max(timeList);
    % divide the time from min to max into every seconds
    group = maxValue - minValue;
    DISTANCE = group + 1;
    if(DISTANCE > 100)
        DISTANCE = 100;
    end
    ranges = linspace(minValue, maxValue, DISTANCE);
    % draw histogram
    figure('name', 'Histogram');
    hist(timeList, ranges);
    % set title and x-label, y-label, and color
    title('Run-time distribution of the jobs');
    xlabel('Run-time(s)');
    ylabel('Number of jobs');
    % set color for histogram
    h = findobj(gca, 'Type', 'patch');
    set(h, 'FaceColor','g','EdgeColor','w');
    
    
catch err
     msg = getReport(err);
     disp(msg);   
end
end


% get time of complete jobs in a specific chunk
function [status, timeListOut, totalOut ] = GetTimeInChunk(currentChunk, timeListIn, totalIn)
status = 0;
timeListOut = timeListIn;
totalOut = totalIn;
logfileName = 'CondorMatlab_AppLog';
try
        logFile = [logfileName, num2str(currentChunk), '.xml'];
        if(exist(logFile, 'file') == 0)
            return;
        end
        xDoc = xmlread(logFile);
        % root Node
        xRoot = xDoc.getDocumentElement;
        % get node CompletedJobs
        CompletedJobsNode = xRoot.getChildNodes.item(1);
        % get all submitted time
        sNodes = CompletedJobsNode.getElementsByTagName('SubmittedTime');
        % get all finish Time
        fNodes = CompletedJobsNode.getElementsByTagName('FinishTime');
        
        n = sNodes.getLength;
        if(n == 0)
            return;
        end
        
        % read all the node SubmittedTime, FinishTime and store the
        % runningTime in array timeList
        for i = 0:n-1
            % get current value of node X
            s = str2double(sNodes.item(i).getTextContent);
            % get current value of node Y
            f = str2double(fNodes.item(i).getTextContent);
            % add x and y values to xArray and yArray
            timeListIn(totalIn) = f - s;
            totalIn = totalIn + 1;
        end
    timeListOut = timeListIn;
    totalOut = totalIn;
catch err
    msg = getReport(err);
    disp(msg);
end


end



function [status] = ResumeApplication()
 status = 0;
    global CURRENT_CHUNK;
    global TOTAL_CHUNKS;
    global LOG_FILE_NAME;
    global XSTART_POINT;
    global XEND_POINT;
    global YSTART_POINT;
    global YEND_POINT;
    global MAX_POINT;
    global TOTAL_POINTS;
    global FUNCTION;
    settingFile = 'CondorMatlab_AppSettings.xml';
    
    XDistance = (XEND_POINT - XSTART_POINT)/(TOTAL_POINTS-1);
    XRange = XDistance * (MAX_POINT -1);
    YDistance = (YEND_POINT - YSTART_POINT)/(TOTAL_POINTS-1);
    YRange = YDistance * (MAX_POINT -1);
    % close the current histogram, because we will have an other one at the
    % end
    close(findobj('type','figure','name','Histogram'));
    
    % if all the chunks are complete, we done -> do nothing
    if(CURRENT_CHUNK == TOTAL_CHUNKS)
       return;
    end
        
    if(CURRENT_CHUNK == TOTAL_CHUNKS-1)
        % check log file of chunk (current + 1)
        % if that log file exists, we will call function Resume for the
        % last chunk
        if(exist([LOG_FILE_NAME, num2str(TOTAL_CHUNKS), '.xml'], 'file') ~= 0)
            status =  ResumeGraphOneChunk3D(TOTAL_CHUNKS, settingFile);
            if(status == 1)
                return;
            end
        else
        % if log file doesn't exist, so we call the function Draw for the last chunk
            status = DrawGraphOneChunk3D(XSTART_POINT + TOTAL_CHUNKS*MAX_POINT*XDistance, XEND_POINT,YSTART_POINT + TOTAL_CHUNKS*MAX_POINT*YDistance, YEND_POINT, TOTAL_POINTS- TOTAL_CHUNKS*MAX_POINT, FUNCTION, TOTAL_CHUNKS, MAX_POINT, TOTAL_POINTS, settingFile);  
            if(status == 1)
                return;
            end
        end
        
    else
    % current chunk + 1 < total of chunks
        % check log file of chunk (current+1)
        % if that log file exists, we will call function Resume for that chunk
        if(exist([LOG_FILE_NAME, num2str(CURRENT_CHUNK + 1), '.xml'], 'file') ~= 0)
            status =  ResumeGraphOneChunk3D(CURRENT_CHUNK + 1, settingFile);
            if(status == 1)
                return;
            end
        else
    % if log file doesn't exist, so we call the function Draw for that chunk
        status = DrawGraphOneChunk3D(XSTART_POINT + (CURRENT_CHUNK+1)*MAX_POINT*XDistance, XEND_POINT, YSTART_POINT + (CURRENT_CHUNK+1)*MAX_POINT*YDistance, YEND_POINT, TOTAL_POINTS - (CURRENT_CHUNK +1)*MAX_POINT, FUNCTION, CURRENT_CHUNK + 1, MAX_POINT, TOTAL_POINTS, settingFile);  
           if(status == 1)
              return;
           end
        end
        % call for loop to process the chunks from CURRENT_CHUNK +2 to
        % TOTAL_CHUNKS-1
        for i=CURRENT_CHUNK + 2: TOTAL_CHUNKS-1
            status = DrawGraphOneChunk3D(XSTART_POINT + i*MAX_POINT*XDistance, XSTART_POINT + i*MAX_POINT*XDistance + XRange, YSTART_POINT + i*MAX_POINT*YDistance, YSTART_POINT + i*MAX_POINT*YDistance + YRange, MAX_POINT, FUNCTION, i, MAX_POINT, TOTAL_POINTS, settingFile);
            if(status == 1)
                return
            end
        end
        % finish the last chunk
         status = DrawGraphOneChunk3D(XSTART_POINT + TOTAL_CHUNKS*MAX_POINT*XDistance, XEND_POINT, YSTART_POINT + TOTAL_CHUNKS*MAX_POINT*YDistance, YEND_POINT, TOTAL_POINTS- TOTAL_CHUNKS*MAX_POINT, FUNCTION, TOTAL_CHUNKS, MAX_POINT, TOTAL_POINTS, settingFile);  
            if(status == 1)
                return;
            end
   end
end


function [status] = ResumeGraphOneChunk3D(currentChunk, settingFile)
    status = ResumeGraphBasic(currentChunk);
    if(status == 1)
        return;
    end
    status = UpdateAppSettings(currentChunk, settingFile);
    if(status == 1)
        return;
    end
end


function [status] = UpdateAppSettings(currentChunk, settingFile)
status = 0;
try
    xDoc = xmlread(settingFile);
    % get the 'Settings' node
    xRoot = xDoc.getDocumentElement;
    % get the 'CurrentChunk' node, then set the new value
    xRoot.getChildNodes.item(15).getFirstChild.setNodeValue(num2str(currentChunk));
    % write data to file AppSettings.xml
    xmlwrite(settingFile,xDoc);
    % remove space from that file
    status = RemoveSpace(settingFile);
    if(status == 1)
        return;
    end
     
catch err
    disp('Cannot update data to CondorMatlab_AppSettings.xml');
    status = 1;
    msg = getReport(err);
    disp(msg);
    return;
end

end

% display all the data from the last time application ran
function [status] = DisplayLastGraph()
    status = 0;
    % get the application infor from application setting file
    status = InitAppParams();
    if(status == 1)
        return;
    end
    % display all complete points
    [status, lastJobs] = DisplayAllCompletedChunks();
    if(status == 1)
        return;
    end
    % save the number of completed jobs
    global LAST_JOBS;
    LAST_JOBS = lastJobs;
    % display histogram
    global CURRENT_CHUNK;
    status = DrawHistogramToCurrentChunk(CURRENT_CHUNK+1);
    if(status == 1)
        return;
    end
end

% display all the points in all the completed chunks from the last time
% application ran
function [status, lastJobs] = DisplayAllCompletedChunks()
    status = 0;
    lastJobs = 0;
    global CURRENT_CHUNK;
    try
       for i=0:(CURRENT_CHUNK + 1)
           [xArray, yArray, zArray, status] = GetCompletedData(i);
           if(status == 1)
               return;
           end
           lastJobs = lastJobs + length(xArray);
           status = DisplayCompletedData(xArray, yArray, zArray);
           if(status == 1)
               return;
           end
       end
        
        
    catch err
        disp('Cannot display complete points');
        msg = getReport(err);
        disp(msg);
        status = 1;
        return;
    end
end

function [status] = InitAppParams()
    global XSTART_POINT;
    global XEND_POINT;
    global YSTART_POINT;
    global YEND_POINT;
    global TOTAL_POINTS;
    global FUNCTION;
    global MAX_POINT;
    global CURRENT_CHUNK;
    global TOTAL_CHUNKS;
    global LOG_FILE_NAME;
    LOG_FILE_NAME = 'CondorMatlab_AppLog';
    status = 0;
 try
    xDoc = xmlread('CondorMatlab_AppSettings.xml');
    % get the 'Settings' node
    xRoot = xDoc.getDocumentElement;
    
    XSTART_POINT      = str2double(xRoot.getChildNodes.item(1).getFirstChild.getData);
    XEND_POINT        = str2double(xRoot.getChildNodes.item(3).getFirstChild.getData);
    YSTART_POINT      = str2double(xRoot.getChildNodes.item(5).getFirstChild.getData);
    YEND_POINT        = str2double(xRoot.getChildNodes.item(7).getFirstChild.getData);
    TOTAL_POINTS      = str2double(xRoot.getChildNodes.item(9).getFirstChild.getData);
    FUNCTION          = char(xRoot.getChildNodes.item(11).getFirstChild.getData);
    MAX_POINT         = str2double(xRoot.getChildNodes.item(13).getFirstChild.getData);
    CURRENT_CHUNK     = str2double(xRoot.getChildNodes.item(15).getFirstChild.getData);
    TOTAL_CHUNKS      = floor(TOTAL_POINTS/MAX_POINT);
    if(rem(TOTAL_POINTS, MAX_POINT)== 0)
        TOTAL_CHUNKS = TOTAL_CHUNKS -1;
    end
 catch err
     disp('Cannot read application settings from file CondorMatlab_AppSettings.xml');
     status = 1;
     return;
 end
    
end



function [status] = ResumeGraphBasic(currentChunk)
        
    status = ResumeProgram(currentChunk);
    if (status == 1)
      return;
    end
    

end


% clear all data from the last crash time
function [result] = ClearOldData()
    result = 0;
        
    result = DeleteFiles();
    if(result == 1)
        return;
    end
end


function [result] = ResumeProgram(currentChunk)
    result = 0;
try
%------------------- INITIALIZE DATA --------------------------------------
    [result, points] = InitializeVariables(currentChunk);
    % if we have errors
    if(result == 1)
        return;
    end
    
    % if the number of points that need to submit are 0, so return
    if(points == 0)
        return;
    end
    
%------------------------- SUBMIT DATA TO CONDOR --------------------------
    
    % generate Condor submit file with custom executable file (exeFile)
    % and number of Condor jobs (length(XArray))
    global FUNCTION;
    
    result = GenerateCondorSubmitFile(FUNCTION);
    % if we have errors
    if(result == 1)
        return;
    end
    % submit data to Condor system
    result = SubmitDataToCondor();
    if(result == 1)
        return;
    end
 
%------------------------- DRAW GRAPH -------------------------------------
    
    result = DrawCurrentData(currentChunk);
    % if the task fails, exit application
    if(result == 1)
        return;
    end
    
    result = CleanApplication();
    % if the task fails, exit application
    if(result == 1)
        return;
    end

%------------------------ DISPLAY INFORMATION -----------------------------
   DisplayInfo();
     
catch err
     % display message when we have exceptions
     msg = getReport(err);
     disp(msg);
     % delete waitbar
     global progressBar;
     if(ishandle(progressBar) == 1)
         delete(progressBar);
     end
     % delete all the temporary files
     DeleteFiles();
end

end

% display info to screen
function DisplayInfo()
    global completedPoints;
    global failedJobs;

    mess1 = sprintf('Total completed jobs with output values: %d jobs.', completedPoints);
    disp(mess1);
    mess2 = sprintf('Total failed jobs without output values: %d jobs.', sum(failedJobs));
    disp(mess2);
end


% clear all temporary data
function [success] = CleanApplication()
success = 0;

% remove unprocessed Condor jobs
global totalPoints;
global NumberOfPoints;
global completedJobs;
global failedJobs;
global clusterNumber;

if(totalPoints < NumberOfPoints)
    success = RemoveJobs(completedJobs, failedJobs, clusterNumber);
    if(success == 1)
        return;
    end
end
    % delete temporary files
    success = DeleteFiles();
    if(success == 1)
        return;
    end
end

function [status, points] = InitializeVariables(currentChunk)
    status = 0;
    status = InitializeMatlabVariables();
    if(status ==1)
        return;
    end
    [status, points] = InitializeCondorVariables(currentChunk);
    if(status == 1)
        return;
    end
end

function [success] = InitializeMatlabVariables()
success = 0;
try
    
    global FUNCTION;
    
    % total points that have been drawn on the graph
    global completedPoints;
    completedPoints = 0;
    
    global totalPoints;
    
    % Condor submit file name
    global submitFileName;
    submitFileName = 'CoverMe.sub';
    
    global PointsToLog;
    PointsToLog = 0;
    
    % progress bar
    global progressBar;
catch err
    disp('ERROR: Cannot initialize Matlab variables.');
    success = 1;
end
end


function [status, points] = InitializeCondorVariables(currentChunk)
    status = 0;
 
try
    % Condor input file name
    global inp;
    inp = 'inp';
    % Condor error file name
    global errorFileName;
    errorFileName = 'ResumeGraph.err';
    % Condor output file
    global outputFileName;
    outputFileName = 'out';
    % Condor log file name
    global logFileName;
    logFileName = 'ResumeGraph.log'; 
    
    global availableX;
    global availableY;
    global availableZ;
    % get all the available X to submit new jobs to Condor
    [availableX, availableY, status] = GetAvailableXY(currentChunk);
    % if has error then exit
    if(status == 1)
        return;
    end
    global NumberOfPoints;
    % total number of value X we have so far
    NumberOfPoints = length(availableX);
    points = NumberOfPoints;
    if(NumberOfPoints == 0)
        return;
    end
    % list of jobs that finished and have exact return values.
    global completedJobs;
    completedJobs = zeros(1, NumberOfPoints);
    % list of jobs that finished but don't have exact return values.
    global failedJobs;
    failedJobs = zeros(1, NumberOfPoints);
    % list of completed output results
    global ZArray;
    ZArray = zeros(1, NumberOfPoints);
    ZArray(1:NumberOfPoints) = intmin;
    global submittedTime;
    submittedTime = zeros(1, NumberOfPoints);
    % list of finish time of the jobs
    global finishTime;
    finishTime = zeros(1, NumberOfPoints);
    
    % the array that contains old Y elements from previous step
    global oldZ;
    oldZ =[];
    %
    global XToDraw;
    XToDraw = [];
    global YToDraw;
    YToDraw = [];
    global ZToDraw;
    ZToDraw = [];
    %
    
    % the array that contains failed jobs from previous step
    global oldFailedJobs;
    oldFailedJobs = [];
    % cluster number
    global clusterNumber;
    
    % jobs to log
    global CompletedXToLog;
    CompletedXToLog = [];
    global CompletedYToLog;
    CompletedYToLog = [];
    global CompletedZToLog;
    CompletedZToLog = [];
    global finishTimeToLog;
    global submittedTimeToLog;
    finishTimeToLog = [];
    submittedTimeToLog = [];
    global XFailedJobsToLog;
    XFailedJobsToLog = [];
    global YFailedJobsToLog;
    YFailedJobsToLog = [];
    global XUnprocessedJobsToLog;
    XUnprocessedJobsToLog = [];
    global YUnprocessedJobsToLog;
    YUnprocessedJobsToLog = [];
    % write points of X to files, 1 point in 1 input file: inp.1,
    % inp.2, inp.3....
    status = WriteData(availableX, availableY);
    if(status == 1)
        return;
    end
    
catch err
    disp('ERROR: Cannot initialize Condor variables.');
    status = 1;
end
end

function [success] = SubmitDataToCondor()
        success = 0;
        global submitFileName;
        % submit file CoverMe.sub to Condor
        command = sprintf('condor_submit %s',submitFileName);
        % store status and return values of command 'system' in 2 params
        [cmdStatus, cmdResult] = system(command);
        % if the action fails
        if(cmdStatus ~= 0)
            success = 1;
            % display error message
            disp(cmdResult);
            % exit function
           return;
        end
        % so now condor_submit command is submitted successfully
        % display information to screen
        disp('Submitted Condor jobs successfully! Please wait for return values...');
        % get the cluster number from the result of condor_submit command
        global clusterNumber;
        [clusterNumber, success]  = GetClusterNumber(cmdResult);
        if(success == 1)
            return;
        end
end

function [status] = DrawCurrentData(currentChunk)
status = 0;
try
        global oldFailedJobs;
        global completedJobs;
        global failedJobs;
        global NumberOfPoints;
        global oldZ;
        global ZArray;
        global availableX;
        global availableY;
        global completedPoints;
        global totalPoints;
        global TOTAL_POINTS;
        
        % draw graph with the points are made from elements of XArray and YArray.
        % create progress bar
        global progressBar;
        progressBar = waitbar(0, 'Please wait...', 'CreateCancelBtn', 'setappdata(gcf, ''abort'',1);', 'WindowStyle', 'modal');
            % set bar always on top
                %frames = java.awt.Frame.getFrames();doneList
                %frames(end).setAlwaysOnTop(1);
            % set initial value for param 'abort'
            setappdata(progressBar,'abort',0);

        % repeat the loop until all log files completed
        while true
            oldFailedJobs = failedJobs;
            % get the list of completed log files
            [completedJobs, failedJobs] = CheckLogFile(NumberOfPoints, completedJobs, failedJobs);
            % if all the jobs finished but don't have correct values (they are
            % all uncompleted jobs)
            if(sum(failedJobs) == NumberOfPoints)
                % delete progress bar
                if(ishandle(progressBar) == 1)
                     delete(progressBar);
                end
                disp('ERROR: Jobs terminated. Could not find output values.');
                return;
            end
            % if we haven't got any completed job
            if(sum(completedJobs) == 0)
                % wait 30 seconds
                pause(30);
                % then return to the beginning of while loop to check values
                % again
                continue;
            end
            % store the values of completed Z elements to previous Z array
            oldZ = ZArray;
            % get the current values of completed Z elements
            ZArray = GetOutputs(completedJobs,ZArray);
            % write data to log file AppLog.xml
            resultLog = WriteLog(availableX, availableY, ZArray, oldZ, completedJobs, failedJobs, oldFailedJobs, currentChunk);
            % display info if the task fails
            if(resultLog == 1)
                disp('ERROR: Cannot write data to log file.');
            end

            % display graph
            completedPoints = PlotXY(availableX, availableY, ZArray, oldZ, completedPoints, currentChunk);
            hold on;

            % total processed points so far
            totalPoints = completedPoints + sum(failedJobs);
            
            global LAST_JOBS;
            TotalPointsWithLast = totalPoints + LAST_JOBS;
            
            % display progress bar
            waitbar(TotalPointsWithLast/TOTAL_POINTS, progressBar, [sprintf('Completed: %.2f', TotalPointsWithLast*100/TOTAL_POINTS), '%']);
            % when click on Cancel button, stop here
            if(getappdata(progressBar, 'abort') == 1)
                 % clean application
                CleanApplication();
                % display statistic information
                DisplayInfo();
                 % remove progress bar
                delete(progressBar);
                % draw histogram
                status = DrawHistogramToCurrentChunk(currentChunk);
                if(status == 1)
                    return;
                end
                status = 1;
                return;
            end;
            if(totalPoints == NumberOfPoints)
                break;
            end
            % delay 30s
           % pause(30);
        end
        % remove progress bar
        delete(progressBar);
catch err
    disp('ERROR: Cannot draw current data.');
    % delete progress bar if error
    if(ishandle(progressBar) == 1)
         delete(progressBar);
     end
    % display message when we have exceptions
    msg = getReport(err);
    disp(msg);
    status = 1;
end
end


function [availableX, availableY, success] = GetAvailableXY(currentChunk)
    availableX = [];
    availableY = [];
    [failedX, failedY, success] = GetXYFromFailedJobs(currentChunk);
    if(success == 1)
        return;
    end
           
    [unprocessedX, unprocessedY, success] = GetXYFromUnprocessedJobs(currentChunk);
    if(success == 1)
        return;
    end
    
    availableX = [failedX unprocessedX];
    availableY = [failedY unprocessedY];
end

function [unprocessedX, unprocessedY, success] = GetXYFromUnprocessedJobs(currentChunk)
    unprocessedX = [];
    unprocessedY = [];
    success = 0;
    global LOG_FILE_NAME;
    logFile = [LOG_FILE_NAME, num2str(currentChunk), '.xml'];
    try
        xDoc = xmlread(logFile);
        % 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
        
        unprocessedX = zeros(1, n);
        unprocessedY = zeros(1, n);
        index = 1;
        % read all the node X, and store values into failedX
        for i = 0:n-1
            % get current value of node X
            x = str2double(xNodes.item(i).getTextContent);
            % get current value of node Y
            y = str2double(yNodes.item(i).getTextContent);
            % add x values to failedX
            unprocessedX(index) = x;
            unprocessedY(index) = y;
            index = index + 1;            
        end
        
        unprocessedX = unprocessedX(1:index-1);
        unprocessedY = unprocessedY(1:index-1);
        
    catch err
        disp(['ERROR: Cannot read data in node UnprocessedJobs from log file ', logFile]);
        % display exception
        % display message when we have exceptions
        msg = getReport(err);
        disp(msg);
        success = 1;
    end

end

function [failedX, failedY, success] = GetXYFromFailedJobs(currentChunk)
    failedX = [];
    failedY = [];
    success = 0;
    global LOG_FILE_NAME;
    logFile = [LOG_FILE_NAME, num2str(currentChunk), '.xml'];
    try
        
        xDoc = xmlread(logFile);
        % root Node
        xRoot = xDoc.getDocumentElement;
        % get node FailedJobs
        FailedJobsNode = xRoot.getChildNodes.item(3);
        % get all node X
        xNodes = FailedJobsNode.getElementsByTagName('X');
        % get all node Y
        yNodes = FailedJobsNode.getElementsByTagName('Y');
        n = xNodes.getLength;
        % if we don't have any failed job
        if(n == 0)
            % do nothing
            return;
        end
        failedX = zeros(1, n);
        failedY = zeros(1, n);
        index = 1;
        % read all the node X, and store values into failedX
        for i = 0:n-1
            % get current value of node X
            x = str2double(xNodes.item(i).getTextContent);
            % get current value of node Y
            y = str2double(yNodes.item(i).getTextContent);
            % add x values to failedX
            failedX(index) = x;
            % add y values to failedY
            failedY(index) = y;
            index = index + 1;
            
        end
        failedX = failedX(1:index-1);
        failedY = failedY(1:index-1);
    catch err
        disp(['ERROR: Cannot read data in node FailedJobs from log file ', logFile]);
        % display exception
        % display message when we have exceptions
        msg = getReport(err);
        disp(msg);
        success = 1;
    end
end


% Stores elements of input array into files. Each file contains 1 element in real value. 
% For example: xArray = [1 2 3], the output will be: file inp.0 has number 1, 
% file inp.1 has number 2, file inp.2 has number 3.
% INPUT:
% - xArray: input array which has real-type elements.
% OUTPUT:
% Boolean type. True if all the processes have completed, else return false. 
function [status] = WriteData(XArray, YArray)
    status = 0; % true        
try
    % create input and output folders
    mkdir('inp');
    mkdir('out');
    fname = 'inp/inp';
    
    for i = 1: length(XArray)
        fid = fopen([fname,'.',int2str(i-1)], 'w');
        fprintf(fid, '%f %f ', XArray(i), YArray(i));
        fclose(fid);
    end
catch err
    status = 1; % false
end

end

% display existing points from file AppLog.xml
function [xArray, yArray, zArray, success] = GetCompletedData(currentChunk)
    xArray = [];
    yArray = [];
    zArray = [];
    success = 0;
    global LOG_FILE_NAME;
    logFile = [LOG_FILE_NAME, num2str(currentChunk), '.xml'];
    if(exist(logFile, 'file') == 0)
        return;
    end
    try
        
        
        xDoc = xmlread(logFile);
        % 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');
        % get all node Z
        zNodes = CompletedJobsNode.getElementsByTagName('Z');
        
        n = xNodes.getLength;
        if(n == 0)
            return;
        end
        xArray = zeros(1, n);
        yArray = zeros(1, n);
        zArray = zeros(1, n);
        index = 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 = str2double(xNodes.item(i).getTextContent);
            % get current value of node Y
            y = str2double(yNodes.item(i).getTextContent);
            % get current value of node Z
            z = str2double(zNodes.item(i).getTextContent);
            % add x and y values to xArray and yArray
            xArray(index) =  x;
            yArray(index) =  y;
            zArray(index) =  z;
            index = index + 1;
        end
        xArray = xArray(1:index-1);
        yArray = yArray(1:index-1);
        zArray = zArray(1:index-1);
    catch err
        
        disp(['ERROR: Cannot read data from log file ', logFile]);
        % display exception
        % display message when we have exceptions
        msg = getReport(err);
        disp(msg);
        success = 1;
    end
end

function [success] = DisplayCompletedData(xArray, yArray, zArray)
    success = 0;
    try
        if(isempty(xArray)||isempty(yArray)|| isempty(zArray))
            return;
        end

        plot3(xArray, yArray, zArray, '.-r','LineStyle','none', 'MarkerFaceColor','r');
        grid on;
        view([45 30]);
        xlabel('X value');
        ylabel('Y value');
        zlabel('Z value');
        hold on;
        
    catch err
        disp('ERROR: Cannot display graph');
        success = 1;
        msg = getReport(err);
        disp(msg);
    end

end

% generate Condor submit file
% INPUT:
% - exeFile: executable file in Condor submit file
% - num: number of Condor jobs
% can phai chac la file nay duoc tao ra
function [out] = GenerateCondorSubmitFile(cusFunction)
   out = 0;
try
    global NumberOfPoints;
    global inp;
    global outputFileName;
    global errorFileName;
    global logFileName;
% write necessary data into Condor submit file (CoverMe.sub)
fid = fopen('CoverMe.sub', 'w');
    % config executable file info. Ex: executable=a.out
    fprintf(fid, 'executable=%s\r\n', cusFunction);
    % config universe info. Ex: universe=vanilla
    fprintf(fid, 'universe=%s\r\n', 'vanilla');
    % config arguments with inputs. Ex: arguments=inp.0
    fprintf(fid, 'arguments=%s.$(Process)\r\n', inp);
    % config environment. Ex: getenv=true
    fprintf(fid, 'getenv=%s\r\n', 'true');
    % config transfer files. Ex: when_to_transfer_output=ON_EXIT
    fprintf(fid, 'when_to_transfer_output=%s\r\n', 'ON_EXIT');
    % should_transfer_files=yes
    fprintf(fid, 'should_transfer_files=yes\r\n');
    % transfer_input_files=a.out,inp.0
    fprintf(fid, 'transfer_input_files=%s,inp/%s.$(Process)\r\n',cusFunction, inp);
    % config output file name. output=out.0, out.1.... 
    fprintf(fid, 'output=out/%s.$(Process)\r\n',outputFileName);
    % config error file name. error=err.0, err.1.....
    fprintf(fid, 'error=%s\r\n',errorFileName);
    % config log file. log=log.0, log.1
    fprintf(fid, 'log=%s\r\n', logFileName);
    % disable sending email function. notification=never
    fprintf(fid, 'notification=%s\r\n', 'never');
    % config queue. Ex: queue 1000
    fprintf(fid, 'queue %d', NumberOfPoints);
fclose(fid); 
catch err
    disp('ERROR: Cannot create Condor submit file.');
    % display message when we have exceptions
     msg = getReport(err);
     disp(msg);
    out = 1;
end
end

% get cluster number from the result of condor_submit command
function [clusterNum, success] =  GetClusterNumber(cmdResult)
success = 0;
try
    % get the start location of string 'cluster '
    startLoc = strfind(cmdResult, 'cluster ');
    % get the cluster number, need to remove the last space character
    clusterNum = cmdResult(startLoc + 8: length(cmdResult)-1);
catch err
    disp('ERROR: Cannot get cluster number.');
    success = 1;
end
end


% Check the log files to detect the completed Condor jobs.
% search the line: (1) Normal termination
% INPUT:
% - n : number of log files. With n, we will have n log files from �log.0� to �log.(n-1)�.
% - doneList: the completed log files so far.
% OUTPUT: 
% - outCompletedJobs: This is the current completedJobs which mark all the completed jobs.
% - outUncompletedJobs: This is the current uncompletedJobs which mark all
% the completed jobs but don't have correct output values.
function [outCompletedJobs, outUncompletedJobs] = CheckLogFile(n, completedJobs, uncompletedJobs)
global submittedTime;
global finishTime;
try
    fileName = 'ResumeGraph.log';
    lastLine = '';
    % open file
    fid = fopen(fileName, 'r');
    % read a line in the file
    curLine = fgetl(fid);
    
   while ischar(curLine)
        % if the line contains 'Job submitted from host', store the
        % submitted time of that jobs
        submittedLine = strfind(curLine, 'Job submitted from host');
        if(isempty(submittedLine) == 0)
             % get the process code
            [status, processNumber] = GetProcess(curLine);
             % if didn't log the submitted time
             if(submittedTime(processNumber) == 0)
                % get the submitted time
                [status, time] = GetTime(curLine);
                submittedTime(processNumber) = time;
             end
        else
              
            % if the line contains '(1) Normal termination (return value 0)'
            completedLine = strfind(curLine, '(1) Normal termination (return value 0)');
            if(isempty(completedLine) == 0)
                     % get the process code
                    [status, processNumber] = GetProcess(lastLine);
                    % add the process number to the output list
                    completedJobs(processNumber) = 1;
                    uncompletedJobs(processNumber) = 0;
                    % get the finish time of the job
                    if(finishTime(processNumber) == 0)
                        [status, time] = GetTime(lastLine);
                        finishTime(processNumber) = time;
                    end
                    
            else
               % check if the job finished but didn't have correct output value
               % if job was aborted
               aborted = strfind(lastLine, 'Job was aborted by the user.');% can kiem tra lai dieu kien nay
               % if the job finished but didn't have value
               error = strfind(lastLine, 'Job terminated.');
               if(isempty(aborted) == 0 || isempty(error) == 0)
                    % get the process code
                    [status, processNumber] = GetProcess(lastLine);
                    % add the process number to the uncompleted list
                    uncompletedJobs(processNumber) = 1;
               end

            end
        end
        
        % read the next line
        lastLine = curLine;
        curLine = fgetl(fid);
    end
    fclose(fid);
catch  err
    % display message when we have exceptions
    msg = getReport(err);
    disp(msg);
end

outCompletedJobs = completedJobs;
outUncompletedJobs = uncompletedJobs;
end


% extract the process number in a line
function [status, number] = GetProcess(line)
status = 0;
number = -1;
try
% extract the process number
    % find the character .
    dotPositions = strfind(line, '.');
    % get the process code
    processCode = line(dotPositions(1)+1: dotPositions(2)-1);
    % convert process code to number
    number = str2double(processCode) + 1;
catch err
    status = 1;
end
end

% extract the date time in a line
function [status, time] = GetTime(line)
status = 0;
time = 0;
try
% extract the date time value
    % find the character /
    slash = strfind(line, '/');
    % get the process code
    timeStr = line(slash-2: slash+11);
    % set time format
    fmt = 'mm/dd HH:MM:SS';
    time = datenum(timeStr, fmt)*86400;
catch err
    status = 1;
end
end



% Get the values from output files that are returned back from Condor (out.0 to out.(n-1))
% INPUT:
% - outDone: current list of completed output files
% - outValue: current values of output
% OUTPUT:
% out: an array. This is the current outValue array which has all the output values.
function [out] = GetOutputs(completedJobs, outValue)
    
for i = 1: length(completedJobs)
    
    if(outValue(i) ~= intmin)
        continue;
    end
    
    
    if(completedJobs(i) ~= intmin) % if i-th log file done, then read the outputfile
        try
            count = 0;
            % open output file to read
            fid = fopen(['out/out.',int2str(i-1)], 'r');
            tline = fgetl(fid);
            % read value line-by-line
            while ischar(tline)
                count = count + 1;
                y = strread(tline, '%f');
                outValue(i) = y;
                tline = fgetl(fid);
            end
            fclose(fid);
        % catch exceptions when reading the file
        catch err
            msg = getReport(err);
            disp(msg);
        end
    end
    
end

out = outValue;
end


% write currenWriteLog data into file AppLog.xml
% OUTPUT:
% result:
%       0: success
%       1: fail

function [result] = WriteLog(xArray, yArray, zArray, oldZ, completedJobs, failedJobs, oldFailedJobs, currentChunk)
    global PointsToLog;
    
    
    % calculate new points we have so far
    % only log the  jobs if yArray has much more 100 elements than the old one.
    % get the number of zeros in old Z array
    oldNumberOfZeros = sum(oldZ(:) == intmin);
    % get the number of intmin in current Z array
    curNumberOfZeros = sum(zArray(:) == intmin);
    
    PointsToLog = PointsToLog + oldNumberOfZeros - curNumberOfZeros;
    
% if we have less than 100 new points, then we do not write the current
    % new points into log file
    NeedLog = 1;
    if(PointsToLog < 100 && sum(completedJobs) + sum(failedJobs) < length(xArray))
        % we dont need to log current new points
        NeedLog = 0;
    end
    
        % write completed jobs
        success = LogCompletedJobs(xArray, yArray, zArray, oldZ, NeedLog, currentChunk);
            % exit function if fail
            if(success == 1)
                result = 1;
                return;
            end
        % write failed jobs
        success = LogFailedJobs(xArray, yArray, failedJobs, oldFailedJobs, NeedLog, currentChunk);
            % exit function if fail
            if(success == 1)
                result = 1;
                return;
            end
        % write unprocessed jobs
        success = LogUnprocessedJobs(xArray, yArray, completedJobs, failedJobs, NeedLog, currentChunk);
            % exit function if fail
                if(success == 1)
                    result = 1;
                    return;
                end
                
        % remove extra white spaces in log file AppLog.xml
        
        global LOG_FILE_NAME;
        logFile = [LOG_FILE_NAME, num2str(currentChunk), '.xml'];
        success = RemoveSpace(logFile);
            % exit function if fail
                if(success == 1)
                    result = 1;
                    return;
                end
              
   % clear value after logging the new points
   if(NeedLog == 1)
       PointsToLog = 0;
   end
   result = 0;
 
end
%The extra whitespace is introduced by the Saxon XML processor, 
% which is the library that MATLAB uses for the XML processing.
function [success] = LogCompletedJobs(xArray, yArray, zArray, oldZ, NeedLog, currentChunk)
    success = 0;
    global finishTimeToLog;
    global submittedTimeToLog;
    global submittedTime;
    global finishTime;
    global CompletedXToLog;
    global CompletedYToLog;
    global CompletedZToLog;
    LENGTH = length(yArray);
    listSubmittedTime = zeros(1, LENGTH);
    listFinishTime = zeros(1, LENGTH);
    listX = zeros(1, LENGTH);
    listY = zeros(1, LENGTH);
    listZ = zeros(1, LENGTH);
    count = 1;
    
    
 try
     
    % get the new points
    for i = 1:LENGTH
        if(zArray(i) ~= intmin)
            if(oldZ(i) == intmin)
                listX(count) = xArray(i);             
                listY(count) = yArray(i);
                listZ(count) = zArray(i);
                listSubmittedTime(count) = submittedTime(i);
                listFinishTime(count) = finishTime(i);
                count = count + 1;
            end
        end
    end
    listX = listX(1:count-1);
    listY = listY(1:count-1);
    listZ = listZ(1:count-1);
    listSubmittedTime = listSubmittedTime(1:count-1);
    listFinishTime = listFinishTime(1:count-1);
    
    CompletedXToLog = [CompletedXToLog listX];
    CompletedYToLog = [CompletedYToLog listY];
    CompletedZToLog = [CompletedZToLog listZ];
    submittedTimeToLog = [submittedTimeToLog listSubmittedTime];
    finishTimeToLog = [finishTimeToLog listFinishTime];
    
    % if we dont need to log the data, then exit the function
    if(NeedLog == 0)
        return;
    end
    
    % write the completed jobs to AppLog.xml
    global LOG_FILE_NAME;
    logFile = [LOG_FILE_NAME, num2str(currentChunk), '.xml'];
    xDoc = xmlread(logFile);
    % 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(CompletedXToLog);
        % create Job node
        jobNode = xDoc.createElement('CompletedJob');
            % create X node
            xNode = xDoc.createElement('X');
            % add value to X node
            xNode.appendChild(xDoc.createTextNode(num2str(CompletedXToLog(i))));
            jobNode.appendChild(xNode);
            % create Y node
            yNode = xDoc.createElement('Y');
            % add value to Y node
            yNode.appendChild(xDoc.createTextNode(num2str(CompletedYToLog(i))));
            jobNode.appendChild(yNode);
            % create Z node
            zNode = xDoc.createElement('Z');
            % add value to Z node
            zNode.appendChild(xDoc.createTextNode(num2str(CompletedZToLog(i))));
            jobNode.appendChild(zNode);
            % create SubmittedTime node
            sNode = xDoc.createElement('SubmittedTime');
            % add value to SubmittedTime node
            sNode.appendChild(xDoc.createTextNode(num2str(submittedTimeToLog(i))));
            jobNode.appendChild(sNode);
            % create FinishTime node
            fNode = xDoc.createElement('FinishTime');
            % add value to FinishTime node
            fNode.appendChild(xDoc.createTextNode(num2str(finishTimeToLog(i))));
            jobNode.appendChild(fNode);
        % append Job node to CompletedJob node
        completedJobNode.appendChild(jobNode);      
    end
    
     % write data to file AppLog.xml
     xmlwrite(logFile,xDoc);
     % clear data
     CompletedXToLog = [];
     CompletedYToLog = [];
     CompletedZToLog = [];
     submittedTimeToLog = [];
     finishTimeToLog = [];
    
catch err
    success = 1;
    disp('ERROR: Cannot write completed jobs to log file.');
    % display message when we have exceptions
     msg = getReport(err);
     disp(msg);
end
end


function [success] = LogFailedJobs(xArray, yArray, failedJobs, oldFailedJobs, NeedLog, currentChunk)
    success = 0;
    global XFailedJobsToLog;
    global YFailedJobsToLog;
try
   % if we don't have any failed job
    if(sum(failedJobs) == 0)
        % do nothing
        return;
    end
    
% get only X values of the new failedJobs
LENGTH = length(xArray);
XnewJobs = zeros(1, LENGTH);
YnewJobs = zeros(1, LENGTH);
count = 1;
    % get the new points
    for i = 1:LENGTH
        if(failedJobs(i) ~=0)
            if(oldFailedJobs(i) == 0)
                XnewJobs(count) = xArray(i);
                YnewJobs(count) = yArray(i);
                count = count + 1;
            end
        end
    end
XnewJobs = XnewJobs(1:count-1);
YnewJobs = YnewJobs(1:count-1);
% if have no jobs
if (isempty(newJobs))
    % do nothing
    return;
end

XFailedJobsToLog = [XFailedJobsToLog XnewJobs];
YFailedJobsToLog = [YFailedJobsToLog YnewJobs];


% if we dont need to log new points, exit the function
if(NeedLog == 0)
    return;
end
    % write the failed jobs to AppLog.xml
    global LOG_FILE_NAME;
    logFile = [LOG_FILE_NAME, num2str(currentChunk), '.xml'];
    xDoc = xmlread(logFile);
    % get the 'LogInfo' node
    xRoot = xDoc.getDocumentElement;
    % get the 'FailedJob' node
    failedJob = xRoot.getChildNodes.item(3);
    % append child to FailedJob node
    for i = 1: length(XFailedJobsToLog)
            % create Job node
            jobNode = xDoc.createElement('FailedJob');
            % create X node
            xNode = xDoc.createElement('X');
            % add value to X node
            xNode.appendChild(xDoc.createTextNode(num2str(XFailedJobsToLog(i))));
            jobNode.appendChild(xNode);
            
            % create Y node
            yNode = xDoc.createElement('Y');
            % add value to Y node
            yNode.appendChild(xDoc.createTextNode(num2str(YFailedJobsToLog(i))));
            jobNode.appendChild(yNode);
        % append Job node to FailedJob node
        failedJob.appendChild(jobNode);
    end
    % write data to file AppLog.xml
    xmlwrite(logFile, xDoc);
    % clear data
    XFailedJobsToLog = [];
    YFailedJobsToLog = [];
    
catch err
    success = 1;
    disp('ERROR: Cannot write failed jobs to log file.');
    % display message when we have exceptions
     msg = getReport(err);
     disp(msg);
end
end

function [success] = LogUnprocessedJobs(xArray, yArray, completedJobs, failedJobs, NeedLog, currentChunk)
     success = 0;
    if(NeedLog == 0)
        return;
    end
try
    % write the failed jobs to AppLog.xml
    global LOG_FILE_NAME;
    logFile = [LOG_FILE_NAME, num2str(currentChunk), '.xml'];
    xDoc = xmlread(logFile);
    % 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 = 1:length(xArray)
        % if we find an unprocessed job
        if((completedJobs(i) == 0) && failedJobs(i) == 0)
            % create UnprocessedJob node
            jobNode = xDoc.createElement('UnprocessedJob');
            % create node JobID
            idNode = xDoc.createElement('JobID');
            % add process id to node JobID
            idNode.appendChild(xDoc.createTextNode(num2str(i-1)));
            jobNode.appendChild(idNode);
            % create X node
            xNode = xDoc.createElement('X');
            % add value to X node
            xNode.appendChild(xDoc.createTextNode(num2str(xArray(i))));
            jobNode.appendChild(xNode);
            % create Y node
            yNode = xDoc.createElement('Y');
            % add value to Y node
            yNode.appendChild(xDoc.createTextNode(num2str(yArray(i))));
            jobNode.appendChild(yNode);
        % append Job node to FailedJob node
        unprocessedJobNode.appendChild(jobNode);
        end
    end
    % append new node UnprocessedJobs to document
    xRoot.appendChild(unprocessedJobNode);
    % write data to file AppLog.xml
    xmlwrite(logFile, xDoc);
    
catch err
    success = 1;
    disp('ERROR: Cannot write unprocessed jobs to application log file.');
    % display message when we have exceptions
     msg = getReport(err);
     disp(msg);
end
end

function [success] = RemoveSpace(filePath)
    success = 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
        msg = sprintf('ERROR: Error when remove white spaces in the file %s', filePath);
        disp(msg);
        success = 1;
    end
end
% Draw graph with the points from xArray and yArray.
% INPUT:
% - xArray: array that has current input elements
% - yArray: array that has current output elements (current step)
% - oldY: array that has old output elements (previous step)
% - total: total elements that are represented so far.
% OUTPUT:
% - result: total points that are being represented by the graph.
function [result] = PlotXY(xArray, yArray, zArray, oldZ, total, currentChunk)
global XToDraw;
global YToDraw;
global ZToDraw;
global failedJobs;
global completedJobs;
global TOTAL_POINTS;

% only draw the points if yArray has much more elements than the old one.
    % get the number of intmin in old Z array
    oldNumberOfZeros = sum(oldZ(:) == intmin);
    % get the number of intmin in current Z array
    curNumberOfZeros = sum(zArray(:) == intmin);
    
    % if 2 values are equal, it means we haven't got new values in zArray
    if(curNumberOfZeros == oldNumberOfZeros)
        % result doesn't change
        result = total;
        % exit this function
        return;
    end

    LENGTH = length(yArray);
    listX = zeros(1, LENGTH);
    listY = zeros(1, LENGTH);
    listZ = zeros(1, LENGTH);
    count = 1;

    for i = 1:LENGTH
        if(zArray(i) ~=intmin)
            if(oldZ(i) == intmin)
                listX(count) = xArray(i);             
                listY(count) = yArray(i);
                listZ(count) = zArray(i);
                count = count + 1;
            end
        end
    end
    listX = listX(1:count-1);
    listY = listY(1:count-1);
    listZ = listZ(1:count-1);
    result = total + count - 1;
   
    %jFrame = get(handle(gcf),'JavaFrame');
    %jFrame.setMaximized(true);
    XToDraw = [XToDraw listX];
    YToDraw = [YToDraw listY];
    ZToDraw = [ZToDraw listZ];
    % if we have less then 100 new points
    if(length(XToDraw) < 100 && sum(completedJobs) + sum(failedJobs) < length(xArray))
        % exit function
        return;
    end
    global LAST_JOBS;
    strComplete = [sprintf('Completed: %.2f', (result + LAST_JOBS)*100/TOTAL_POINTS), '%'];
    plot3(XToDraw, YToDraw, ZToDraw, '.-r','LineStyle','none', 'MarkerFaceColor','r');
    grid on;
    view([45 30]);
    title(strComplete);
    xlabel('X value');
    ylabel('Y value');
    zlabel('Z value');
    
    % clear global X, Y arrays
    XToDraw = [];
    YToDraw = [];
    ZToDraw = [];
end

% remove all the uncompleted Condor jobs
% INPUT:
% - doneList: the list has information about completed jobs, and
% uncompleted jobs. Ex: doneList(3) = 1, then 3rd job is complete.
% doneList(4) = 0, then 4th job is uncomplete.
function [success] = RemoveJobs(completedJobs, uncompletedJobs, clusterNumber)
success = 0;
try
    % n is total jobs that are submitted to Condor
    n = length(completedJobs);
    % get the list of current completed jobs
    [completedJobs, uncompletedJobs] = CheckLogFile(n, completedJobs, uncompletedJobs);
    % check if all the jobs completed
    totalProcessedJobs = sum(completedJobs) + sum(uncompletedJobs);
    if(totalProcessedJobs == n)
        success = 1;
        % then exit
        return;
    end
     
    % remove all uncompleted processes
        for i = 1:n
             % remove only unprocessed jobs
             if((completedJobs(i) == 0) && (uncompletedJobs(i) ==0))
                 % current output file name. Ex: out.1, out.2
                 outputFileName = ['out/out.', int2str(i-1)];
                 % we need to be sure that the output files dont have
                 % values
                 if (CheckData(outputFileName) == 1)
                     % now try to remove cluster.process in Condor queue
                     process = [clusterNumber, int2str(i-1)];
                     command = sprintf('condor_rm %s', process);
                     [cmdStatus, cmdResult] = system(command);
                     % if the action fails
                     % if(cmdStatus ~= 0)
                         % display error message
                         % disp(cmdResult);
                     % end
                 end
             end
        end
   
catch err
     disp('ERROR: Cannot clear temporary data.');
     msg = getReport(err);
     disp(msg);
     success = 1;
end
    

end


% check the value in output file
% INPUT: file name
% OUTPUT: result 0: has value
%                1: no value

function [result] = CheckData(file)
    result = 1;
    % if file not found, return 1
    if(exist(file, 'file') == 0)
        return;
    end
    % if file size > 0 bytes
    fileInfo = dir(file);
    if(fileInfo.bytes > 0)
        result = 0;
    end
end
% Delete all the temporary files: input files, output files, log files, error files.
% INPUT:
% - n: the maximum index of the files. (indexes from 0 to n-1)
function [success] = DeleteFiles()
success = 0;
try
    cover = 'CoverMe';
    global errorFileName;
    errorFileName = 'ResumeGraph.err';
    global logFileName;
    logFileName = 'ResumeGraph.log';

    % delete CoverMe files
     delete(['*',cover,'*']);
     % delete log file
     if(exist(logFileName, 'file') ~= 0)
        delete(logFileName);
     end
    % delete error file
     if(exist(errorFileName, 'file') ~= 0)
         delete(errorFileName);
     end

    % delete input files
    if(exist('inp', 'file') == 7)
         rmdir('inp','s');
    end

    % delete output files
    if(exist('out', 'file') == 7)
         rmdir('out','s');
    end
catch err
    disp('ERROR: Cannot delete temporary files.');
    success = 1;
end
end

 

