%--------------------------------------------------------------------------
% Copyright 2012
% Sudharshan Varadarajan, H. M. N. Dilum Bandara and Anura P. Jayasumana,
% Colorado State University, Fort Collins, CO.
% http://www.cnrl.colostate.edu/
%
%  Licensed under the Apache License, Version 2.0 (the "License");
%  you may not use this file except in compliance with the License.
%  You may obtain a copy of the License at
% 
%      http://www.apache.org/licenses/LICENSE-2.0
% 
%  Unless required by applicable law or agreed to in writing, software
%  distributed under the License is distributed on an "AS IS" BASIS,
%  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
%  See the License for the specific language governing permissions and
%  limitations under the License.
%--------------------------------------------------------------------------


function varargout = ResGen(varargin)
% RESGEN MATLAB code for ResGen.fig
%      RESGEN, by itself, creates a new RESGEN or raises the existing
%      singleton*.
%
%      H = RESGEN returns the handle to a new RESGEN or the handle to
%      the existing singleton*.
%
%      RESGEN('CALLBACK',hObject,eventData,handles,...) calls the local
%      function named CALLBACK in RESGEN.M with the given input arguments.
%
%      RESGEN('Property','Value',...) creates a new RESGEN or raises the
%      existing singleton*.  Starting from the left, property value pairs are
%      applied to the GUI before ResGen_OpeningFcn gets called.  An
%      unrecognized property name or invalid value makes property application
%      stop.  All inputs are passed to ResGen_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 ResGen

% Last Modified by GUIDE v2.5 30-Sep-2012 09:35:27

% Begin initialization code - DO NOT EDIT
gui_Singleton = 1;
gui_State = struct('gui_Name',       mfilename, ...
                   'gui_Singleton',  gui_Singleton, ...
                   'gui_OpeningFcn', @ResGen_OpeningFcn, ...
                   'gui_OutputFcn',  @ResGen_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


% --- Executes just before ResGen is made visible.
function ResGen_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 ResGen (see VARARGIN)

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

% Update handles structure
guidata(hObject, handles);

set(handles.ListBoxStatic, 'Value', []); %Makesure no selection is allowed
set(handles.ListBoxDynamic, 'Value', []);
set(handles.ListBoxCorrelate, 'Value', []);

%Track static & dynamic attributes
handles.resourceData = struct('numStaticAtts', -1, 'staticAttsName', -1,...
    'numStaticRes', -1, 'static', -1, 'dynamic', -1, 'sampleInterval', ...
    -1, 'numTSStatic', -1, 'TSStaticName', -1);
% Update handles structure
guidata(hObject, handles);

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


% --- Outputs from this function are returned to the command line.
function varargout = ResGen_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;



function EditBxStaticFileName_Callback(hObject, eventdata, handles)
% hObject    handle to EditBxStaticFileName (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 EditBxStaticFileName as text
%        str2double(get(hObject,'String')) returns contents of EditBxStaticFileName as a double


% --- Executes during object creation, after setting all properties.
function EditBxStaticFileName_CreateFcn(hObject, eventdata, handles)
% hObject    handle to EditBxStaticFileName (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


% --- Executes during object creation, after setting all properties.
function EditBxStaticStatus_CreateFcn(hObject, eventdata, handles)
% hObject    handle to EditBxStaticStatus (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


% --- Executes on selection change in ListBoxStatic.
function ListBoxStatic_Callback(hObject, eventdata, handles)
% hObject    handle to ListBoxStatic (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 ListBoxStatic contents as cell array
%        contents{get(hObject,'Value')} returns selected item from ListBoxStatic
contents = cellstr(get(hObject, 'String')); %Attribute names
idx = get(hObject, 'Value'); %Indexes
tmpAttribs = [];
for i = 1:numel(idx);
    tmpAttribs = [tmpAttribs ; contents(idx(i))];
end
set(handles.ListBoxCorrelate, 'String', tmpAttribs);

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

% Hint: listbox 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


% --- Executes during object creation, after setting all properties.
function EditBxNumRes_CreateFcn(hObject, eventdata, handles)
% hObject    handle to EditBxNumRes (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



% --- Executes during object creation, after setting all properties.
function EditBxInterval_CreateFcn(hObject, eventdata, handles)
% hObject    handle to EditBxInterval (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


% --- Executes during object creation, after setting all properties.
function EditBxDuration_CreateFcn(hObject, eventdata, handles)
% hObject    handle to EditBxDuration (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



function EditBxSeed_Callback(hObject, eventdata, handles)
% hObject    handle to EditBxSeed (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 EditBxSeed as text
%        str2double(get(hObject,'String')) returns contents of EditBxSeed as a double


% --- Executes during object creation, after setting all properties.
function EditBxSeed_CreateFcn(hObject, eventdata, handles)
% hObject    handle to EditBxSeed (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



% --- Executes during object creation, after setting all properties.
function EditBxFileoutput_CreateFcn(hObject, eventdata, handles)
% hObject    handle to EditBxFileoutput (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



function EditBxStatus_Callback(hObject, eventdata, handles)
% hObject    handle to EditBxStatus (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 EditBxStatus as text
%        str2double(get(hObject,'String')) returns contents of EditBxStatus as a double


% --- Executes during object creation, after setting all properties.
function EditBxStatus_CreateFcn(hObject, eventdata, handles)
% hObject    handle to EditBxStatus (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


% --- Executes on button press in BtnStaticBrowse.
function BtnStaticBrowse_Callback(hObject, eventdata, handles)
% hObject    handle to BtnStaticBrowse (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)
[fileName, pathName] = uigetfile('*.txt' , 'Text Files (*.txt)', ...
    'Select static dataset');
if isequal(fileName, 0)
    set(handles.EditBxStaticFileName,'String', 'Cancel selected.');
    return;
end

[tok, remain]= strtok(fileName, '.');
if (~strcmp(remain, '.txt')) %Is it a .txt file?
    h = errordlg('Invalid static attributes file. Not a ".txt"');
    uiwait(h);
    set(handles.EditBxStaticFileName, 'String', '');
    return;
end
staticFileName = fullfile(pathName, fileName);
set(handles.EditBxStaticFileName,'String', staticFileName);

%Read one line at a time
fid = fopen(staticFileName); %Open file for reading
line = fgetl(fid); %Read first line
if isempty(line) %Is file empty
    h = errordlg('Empty static attributes file.');
    uiwait(h);
    set(handles.EditBxStaticFileName, 'String', '');    
    return;
end

error = 0; %Error code
attribs = []; %List of attribute names
numAtts = -1; %No of attributes
numRes = 0; %No of resources
fileState = ''; %what's being read from file
staticValues = []; %Static attribute values

while (line ~= -1)
    if strcmp(line(1), '#') %Skip comment lines starting with '#'
        line = fgetl(fid);
        continue;
    end

    r = regexp(line,'\t','split'); % Tokenize based on tab
    if strcmpi(r{1}, 'ATTNAMES') %Attribute names
        [m, n] = size(r);
        if n == 1
            error = -1;
        else
            for i = 2:n
                attribs = strvcat(attribs, r{i});
            end
            set(handles.ListBoxStatic, 'String', attribs); %Update listbox
        end
    elseif strcmpi(r{1}, 'DATA') %Data
        fileState = 'DATA';
        [numAtts, n] = size(attribs);
    elseif fileState == 'DATA'
        if numAtts ~= numel(r)
            error = -2;
        else
            tmpValues = [];            
            for i = 1:numAtts
                tmpValues = [tmpValues str2double(char(r{i}))];
            end
            staticValues = [staticValues; tmpValues];
            numRes = numRes + 1;
        end
    else
        error = -3;
    end
        
    if error < 0
        h = '';
        if error == -1
            h = errordlg('Error in attribute names (ATTNAMES).');
        elseif error == -2
            h = errordlg('No of attributes in ATTNAMES & DATA don''t match.');
        else
            h = errordlg(['Unknown tag in static attribute file. ', line]);
        end
        uiwait(h);
        return;
    end
    
    line = fgetl(fid); % Get next Line from the File
end

fclose(fid); %close file
tmpStr = ['No attributes: ' num2str(numAtts) ' No of resources: ' ...
    num2str(numRes)];
set(handles.EditBxStaticStatus, 'String', tmpStr);    

handles.resourceData.numStaticAtts = numAtts;
handles.resourceData.staticAttsName = attribs;
handles.resourceData.numStaticRes = numRes;
handles.resourceData.static = staticValues;
guidata(hObject,handles);


% --- Executes on button press in BtnGenerate.
function BtnGenerate_Callback(hObject, eventdata, handles)
% hObject    handle to BtnGenerate (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)
staticSelected = false; %Generate static attributes
dynamicSelected = false; %Generate dynamic attributes
correlateSelected = false; %Establish correlation between static & dynamic 

idxStatic = get(handles.ListBoxStatic, 'Value');%Index of static attributes
numSelStatic = numel(idxStatic); %No of selected static attributes
if numSelStatic > 0
    staticSelected = true;
end
idxDynamic = get(handles.ListBoxDynamic, 'Value');%Index of dynamic attribs
numSelDynamic = numel(idxDynamic);
if numSelDynamic > 0
    dynamicSelected = true;
end
%Index of attributes to use for correlation
idxCorrelate = get(handles.ListBoxCorrelate, 'Value');
if numel(idxCorrelate) > 1
    h = errordlg('Cannot correlate with more than 1 static attribute.');
    uiwait(h);
    return;
elseif numel(idxCorrelate) > 0
    correlateSelected = true;
end
                
numRes = int32(str2num(get(handles.EditBxNumRes, 'String')));
interval = int32(str2num(get(handles.EditBxInterval, 'String')));
duration = str2num(get(handles.EditBxDuration, 'String'));
rndSeed = str2num(get(handles.EditBxSeed, 'String'));
accuracy = str2num(get(handles.EditBxAccuracy, 'String'));
outFileName = get(handles.EditBxFileoutput, 'String');

if (numRes <= 0)
    h = errordlg('Invalid no of resources.');
    uiwait(h);
    return;
end

sampleInterval = handles.resourceData.sampleInterval;
if dynamicSelected == true
    if (interval < sampleInterval) | (mod(interval, sampleInterval) > 0)
        h = errordlg(['Invalid interval. Must be greater than & integer'...
            ' multiple of ' num2str(sampleInterval) '.']);
        uiwait(h);
        return;
    end
end
sampleWindow = interval / sampleInterval;%If subset of samples to be picked

if (rndSeed < 1) | (rndSeed > 128)
    h = errordlg('Invalid seed. Should be between 1-128.');
    uiwait(h);
    return;
else
    rand('twister', rndSeed); %Set random seed.
end

% 1 <= accuracy <= number of samples in file & 
numStaticAttribs = handles.resourceData.numStaticAtts;
numStaticResources = handles.resourceData.numStaticRes;
if staticSelected == true
    if (accuracy < 1) | (accuracy > numStaticResources)
        h = errordlg(['Invalid Accuracy. Should be between [1, ' ...
            num2str(numStaticResources) ']. See user guide for details.']);
        uiwait(h);
        return;
    end
end

%Build table that track lods at different time instances
%This implementation supports load based on CPU free only. If CPU free >
%BusyIdleThresh then IDLE otherwise BUSY. MODERATE is created by comining 
%time seires samples from both BUSY & IDLE states.
busyThresh = -1;
modBusyThresh = 100.0; %Defaul if no specific state is given
idleThresh = -1;
strBusyIdleThresh = get(handles.EditBusyIdleThresh, 'String');
strLoadPeriods = get(handles.EditPeriods, 'String');
r = regexp(strBusyIdleThresh(1, :),',','split'); % Tokenize
[m, n] = size(r);
if ~isempty(strLoadPeriods) 
    if isempty(strBusyIdleThresh) || n ~= 3
        h = errordlg('Error in Busy/Idle thresholds.');
        uiwait(h);
        return;
    end
    busyThresh = str2num(r{1});
    modBusyThresh = str2num(r{2});
    idleThresh = str2num(r{3});
end

[m, n] = size(strLoadPeriods);
loadPeriods = zeros(m, 3);
if ~isempty(strLoadPeriods)
    for i = 1:m
        r = regexp(strLoadPeriods(i, :),',','split'); % Tokenize
        state = -1; %Which state
        if strcmp(r{1}, 'I') %IDLE
            state = 1;
        elseif strcmp(r{1}, 'M') %MODERATE
            state = 2;
        elseif strcmp(r{1}, 'B') %BUSY
            state = 3;
        else
            h = errordlg('Syntax error in Busy, moderate, idle periods.');
            uiwait(h);
            return;
        end
        
        newTime = str2num(r{2});
        if newTime <= 0
            h = errordlg('Time in Busy, moderate, idle periods cannot be <= 0');
            uiwait(h);
            return;
        end
        
        preTime = 0; %end of last period
        if i > 1
            preTime = loadPeriods(i - 1, 2);
            if newTime <= preTime
                h = errordlg('Wrong time in Busy, moderate, idle periods.');
                uiwait(h);
                return;
            end
            preTime = preTime + 1;
        end
        loadPeriods(i, 1) = preTime;
        loadPeriods(i, 2) = newTime;
        loadPeriods(i, 3) = state;
        
        if i == m && newTime ~= duration %Last specification & not the end
            loadPeriods = [loadPeriods; [newTime, duration, 2]];
        end
    end
end
%Busy, moderate, idle periods not given. Set default as MODERATE
if loadPeriods(1, 3) == 0 %No state
    loadPeriods = [0, duration, 2];
end
[mLoadPeriods, n] = size(loadPeriods);

%Generate staic data using pwlcopula---------------------------------------
staticData = [];
useAllAttributes = true;
if staticSelected == true
    set(handles.EditBxStatus, 'String', 'Generating static attributes.');
    %Shall we use only selected attributes to calculate empirical copular
    if get(handles.checkboxUseAllAttrib, 'Value') ~= ...
            get(handles.checkboxUseAllAttrib, 'Max')
        useAllAttributes = false;
    end
    
    staticValuesToUse = handles.resourceData.static;
    numStaticAttribsUse = numStaticAttribs;
    attNamesUse = handles.resourceData.staticAttsName;
    if useAllAttributes == false %Use only selected attributes
        numStaticAttribsUse = numSelStatic;
        staticValuesToUse = staticValuesToUse(:, idxStatic);
        attNamesUse = attNamesUse(idxStatic, :);
    end
    staticData = pwlCopula(numStaticAttribsUse, numStaticResources, ...
        rndSeed, accuracy, numRes, staticValuesToUse, {attNamesUse});
    set(handles.EditBxStatus, 'String', ...
        'Static attribute generation complete.');
end

fid = fopen(outFileName, 'w'); %Open output file

%Generate only the static data --------------------------------------------
if staticSelected == true & dynamicSelected == false
    for i = 1: numRes
        fprintf(fid, '%d', i);
        for j = 1: numSelStatic
            if useAllAttributes == true
                fprintf(fid, '\t%g', staticData(i, idxStatic(j)));
            else
                fprintf(fid, '\t%g', staticData(i, j));                
            end
            if j == numSelStatic
                fprintf(fid, '\n'); %No tab for last line
            end
        end
    end
end

%Generate dynamic data ----------------------------------------------------
if dynamicSelected == true
    set(handles.EditBxStatus, 'String', 'Generating dynamic attributes.');
    
    numSamples = (duration/interval) + 1;
    numCols = numSelStatic + numSamples * numSelDynamic;
    genData = zeros(numRes, numCols); %Generated data
    [numTSSamples, x] = size(handles.resourceData.dynamic);
    %Index of time series length in dynamic file
    tsCountIdx = handles.resourceData.numTSStatic + ...
        handles.resourceData.numTSDynamic + 1;

    %If need to establish correlation with 1 static attribute. Find
    %which indexs can be used
    idxTSCorrelate = -1;
    idxSelStatic = -1; %Index of selected static attribute
    if correlateSelected == true
        tmpAttNamesCorre = get(handles.ListBoxCorrelate, 'String');
        selAttName = tmpAttNamesCorre(idxCorrelate);
        tmpTSAttNamesStatic = handles.resourceData.TSStaticName;
        [m, n] = size(tmpTSAttNamesStatic);
        for j = 1:m
            if strcmpi(selAttName, strtrim(tmpTSAttNamesStatic(j, :))) ...
                    == true
                idxTSCorrelate = j;
                break
            end
        end
        if idxTSCorrelate == -1
            h = errordlg('Static attribute selected for correlation not in time series library.');
            uiwait(h);
            return;
        end
        
        tmpAttNamesStatic = get(handles.ListBoxStatic, 'String');
        [m, n] = size(tmpAttNamesStatic);
        for j = 1:m
            if strcmpi(selAttName, strtrim(tmpAttNamesStatic(j, :)))== true
                idxSelStatic = j;
                break
            end
        end
        if idxSelStatic == -1
            h = errordlg('Static attribute selected to establish correlation must be selected as one of the static attributes to include in generated data.');
            uiwait(h);
            return;
        end
        %Find what samples can be used. Only integer values are used to
        %establish correlation. Modify following lines if more complex 
        %options are needed
        allStaticValues = round(handles.resourceData.dynamic(:, ...
            idxTSCorrelate));
    end

    %Modify following if attribute other than CPUFree to be used
    idxCPUFree = -1; 
    tmpAttNamesDynamic = get(handles.ListBoxDynamic, 'String');
    [m, n] = size(tmpAttNamesDynamic);
    for j = 1:m
        if strcmpi('CFree', strtrim(tmpAttNamesDynamic(j, :)))== true
            idxCPUFree = handles.resourceData.numTSStatic + j;
            break
        end
    end
    sharpChange = get(handles.checkboxSharp, 'Value');
    
    for i = 1:numRes %Generate all resources
        if staticSelected == true %static attribs of node being generated
            for j = 1:numSelStatic %Copy each attribute
                if useAllAttributes == true %All attributes used in copular 
                    genData(i, j) = staticData(i, idxStatic(j));
                else %Only selected attributes were fed to copula generator
                    genData(i, j) = staticData(i, j);
                end
            end
        end

        idxsToUse = [];
        if idxSelStatic > -1 %Find subset of time series samples to use
            tmpStaticValue = round(genData(i, idxSelStatic));
            idxsToUse = find(allStaticValues == tmpStaticValue);
        end

        %If no correlation with static attributes, any sample is valid
        if correlateSelected == false
            idxsToUse = 1:numTSSamples;
        else %Enforce correlation with 1 static attribute
            if numel(idxsToUse) == 0 %But no indexes to use
                %warning('No matching value in generated static data to correlate with static values in time seires library. So a time series is randomly picked.');
                idxsToUse = 1:numTSSamples;
            end
        end
        
        tmpCount = 0;
        rndIdx = -1;
        while 1
            %Find what state to use for randomly selecting a time series. 
            %Default is MODERATE
            state = 2; 
            currentTime = tmpCount * interval;
            endTimePeriod = -1; %end time of period
            if idxCPUFree > -1 %Has CPUFree time series
                for l = 1:mLoadPeriods
                    if loadPeriods(l, 1) <= currentTime && ...
                            currentTime <= loadPeriods(l, 2)
                        state = loadPeriods(l, 3);
                        endTimePeriod = loadPeriods(l, 2);
                        break;
                    end
                end
            end
            
            CPUFreeValues = handles.resourceData.dynamic(idxsToUse, ...
                    idxCPUFree);
            idxCPUFreeValues = [];
            if state == 1 %Pick IDLE samples. Set any threshold you like
                idxCPUFreeValues = find(modBusyThresh < CPUFreeValues & ...
                    CPUFreeValues <= idleThresh);
            elseif state == 2 %Pick Moderately BUSY samples
                idxCPUFreeValues = find(busyThresh < CPUFreeValues & ...
                    CPUFreeValues <= modBusyThresh);
            elseif state == 3 %Pick BUSY samples
                idxCPUFreeValues = find(CPUFreeValues <= busyThresh);
            end
            idxsToUse = idxsToUse(idxCPUFreeValues); %Original index

            if numel(idxsToUse) == 0 %No indexes to use
                warning('No matching value for given load (BUSY or IDLE) condition. Try changing CPUFreeValues threshold. A time series is randomly picked.');
                idxsToUse = 1:numTSSamples;
            end            
            %Pick a random sample from remaining indexes
            tmpIdx = randi(numel(idxsToUse)); 
            rndIdx = idxsToUse(tmpIdx);

            tmpNumSamples = handles.resourceData.dynamic(rndIdx, ...
                tsCountIdx);
            for j = 1:tmpNumSamples
                %If subsampling skip these samples
                if sampleWindow ~= 1 && mod(j, sampleWindow) ~= 1
                    continue
                end
                %Don't copy anymore samples if attribute values should
                %reflect a sharp/rapid change. e.g., sudden change from 
                %IDLE to BUSY state
                if sharpChange == true
                    currentTime = tmpCount * interval;
                    if currentTime > endTimePeriod
                        break;
                    end
                end
                
                for k = 1:numSelDynamic
                    l = tsCountIdx + j + ...
                        (idxDynamic(k) - 1) * tmpNumSamples;
                    m = numSelStatic + (tmpCount * numSelDynamic) + k;
                    genData(i, m) = ...
                        handles.resourceData.dynamic(rndIdx, l);
                end
                tmpCount = tmpCount + 1;
                if tmpCount == numSamples
                    break
                end
            end
            if tmpCount == numSamples
                break
            end
        end
    end
    
    for i = 1:numSamples %dump data to file
        for j = 1: numRes
            fprintf(fid, '%d\t%d', j, (i - 1)* interval);
            for k = 1:numSelStatic %Get static attributes
                fprintf(fid, '\t%g', genData(j, k));
            end
            for k = 1:numSelDynamic %Get static attributes
                l = numSelStatic + (i - 1) * numSelDynamic + k;
                fprintf(fid, '\t%g', genData(j, l));
            end
            fprintf(fid, '\n'); %No tab for last line
        end
    end
end

fclose(fid); %Close file
set(handles.EditBxStatus, 'String', 'Data generation complete.');


% --- Executes on button press in BtnBack.
function BtnBack_Callback(hObject, eventdata, handles)
% hObject    handle to BtnBack (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)
close all ;
currentFolder = pwd;
filePath = [currentFolder '\ResQue.fig'];
backbtn = open(filePath);


% --- Executes on button press in BtnExit.
function BtnExit_Callback(hObject, eventdata, handles)
% hObject    handle to BtnExit (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)
close all ;


% --- Executes during object creation, after setting all properties.
function EditBxDynamicFileName_CreateFcn(hObject, eventdata, handles)
% hObject    handle to EditBxDynamicFileName (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


% --- Executes on button press in BtnDynamicBrowse.
function BtnDynamicBrowse_Callback(hObject, eventdata, handles)
% hObject    handle to BtnDynamicBrowse (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)
[fileName, pathName] = uigetfile('*.txt' , 'Text Files (*.txt)', ...
    'Select dynamic dataset');
if isequal(fileName, 0)
    set(handles.EditBxDynamicFileName,'String', 'Cancel selected.');
    return
end

[tok, remain]= strtok(fileName, '.');
if (~strcmp(remain, '.txt')) %Is it a .txt file
    h = errordlg('Invalid dynamic attributes file. Not a ".txt"');
    uiwait(h);
    set(handles.EditBxDynamicFileName, 'String', '');
    return;
end
dynamicFileName = fullfile(pathName, fileName);
set(handles.EditBxDynamicFileName,'String', dynamicFileName);

%Read one line at a time
fid = fopen(dynamicFileName); %Open file for reading
line = fgetl(fid); %Read first line
if isempty(line) %Is file empty
    h = errordlg('Empty dynamic attributes file.');
    uiwait(h);
    set(handles.EditBxDynamicFileName, 'String', '');    
    return;
end

fileState = ''; %What data is being read
error = 0; %Error code
numStatic = -1;
numDynamic = -1;
sampleInterval = -1; %Sampling interval
numSamples = -1; % No of samples
maxSampleLen = -1; %Length of longest sample
staticAttribs = []; %Static attribute names
dynamicAttribs = []; %Dynamic attributee names
dynamicData = []; %Collection of time series with static attributes
count = 1; %Counter for TS samples

while (line ~= -1)
    if strcmp(line(1), '#') %Skip comment lines starting with '#'
        line = fgetl(fid);
        continue;
    end
    
    r = regexp(line,'\t','split'); % Tokenize based on tab
    [m, n] = size(r);
    if strcmpi(r{1}, 'NUM_STATIC') %Read no of static attributes
       if n == 1 %Missing value
            error = -1;
       else
           numStatic = str2num(r{2});
       end
    elseif strcmpi(r{1}, 'NUM_DYNAMIC') %Read no of dynamic attributes
       if n == 1 %Missing value
            error = -2;
       else
           numDynamic = str2num(r{2});
       end
    elseif strcmpi(r{1}, 'SAMPLE_INTERVAL') %Read sampling interval
       if n == 1 %Missing value
            error = -3;
       else
           sampleInterval = str2num(r{2});
           set(handles.EditBxInterval, 'String', sampleInterval);
       end
    elseif strcmpi(r{1}, 'NUM_SAMPLES') %Read no of samples
       if n == 1 %Missing value
            error = -4;
       else
           numSamples = str2num(r{2});
       end       
    elseif strcmpi(r{1}, 'MAX_SAMPLE_LEN') %Read length of longest sample
       if n == 1 %Missing value
            error = -5;
       else
           maxSampleLen = str2num(r{2});
       end       
    elseif strcmpi(r{1}, 'ATTNAMES') %List of attribute names
        if n == 1 %Missing value
            error = -6;
        else
            if n ~= 1 + (numStatic + numDynamic) %Check attribute name list
                error = -7;
            else
                for i = 2:(numStatic + 1) %Extract static attributes
                    staticAttribs = strvcat(staticAttribs, r{i});
                end
                for i = (numStatic + 2):n %Extract dynamic attributes
                    dynamicAttribs = strvcat(dynamicAttribs, r{i});
                end
                tmpStr = ['Static attribs: ' num2str(numStatic) ...
                    ' Dynamic attribs: ' num2str(numDynamic) ...
                    ' Sampling interval: ' num2str(sampleInterval) ...
                    ' No of samples: ' num2str(numSamples)];
                set(handles.EditBxDynamicStatus, 'String', tmpStr);
                %Update dynamic attibute listbox
                set(handles.ListBoxDynamic, 'String', dynamicAttribs);
            end
        end
    elseif strcmpi(r{1}, 'DATA')
        fileState = 'DATA';
        staticAve = numStatic + numDynamic; %Static & average data
        dynamicData = ones(numSamples, (staticAve + 1 + ...
                                    maxSampleLen * numDynamic)) * -1.0; 
    elseif strcmpi(fileState, 'DATA') %Data
        numTSSamples = str2num(char(r{staticAve + 1})); %no of ts samples
        %Check total no of samples
        if (staticAve + 1 + numTSSamples * numDynamic) ~= numel(r)
            error = -8;
        else
            tmpTS = [];
            for i = 1:numel(r)
                dynamicData(count, i) = str2double(char(r{i}));
            end
            count = count + 1;
        end
    else
        error = -9;
    end
    
    if error < 0
        h = '';
        if error == -1
            h = errordlg('Error in no of static attributes (NUM_STATIC).');
        elseif error == -2
            h = errordlg('Error in no of dynamic attributes (NUM_DYNAMIC).');
        elseif error == -3
            h = errordlg('Error in sampling interval (SAMPLE_INTERVAL).');
        elseif error == -4
            h = errordlg('Error in number of samples (NUM_SAMPLES).');
        elseif error == -5
            h = errordlg('Error in MAX sample length (MAX_SAMPLE_LEN).');
        elseif error == -6
            h = errordlg('Error in attribute names (ATTNAMES).');            
        elseif error == -7
            h = errordlg('No of attributes in ATTNAMES & DATA don''t match.');
        elseif error == -8
            h = errordlg('No of samples in time series not correct.');
        else
            h = errordlg(['Unknown tag in file. ', line]);
        end
        uiwait(h);
        return;
    end
     
    line = fgetl(fid); % Get next Line from the File
end
if (count - 1) ~= numSamples
    h = errordlg(['No of time series samples != ', num2str(numSamples)]);
    uiwait(h);
    return;
end

handles.resourceData.sampleInterval = sampleInterval;
handles.resourceData.dynamic = dynamicData;
handles.resourceData.numTSStatic = numStatic;
handles.resourceData.numTSDynamic = numDynamic;
handles.resourceData.TSStaticName = staticAttribs;
guidata(hObject,handles)


% --- Executes during object creation, after setting all properties.
function EditBxDynamicStatus_CreateFcn(hObject, eventdata, handles)
% hObject    handle to EditBxDynamicStatus (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


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

% Hint: listbox 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


% --- Executes on selection change in ListBoxCorrelate.
function ListBoxCorrelate_Callback(hObject, eventdata, handles)
% hObject    handle to ListBoxCorrelate (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 ListBoxCorrelate
% contents as cell array contents{get(hObject,'Value')} returns selected 
% item from ListBoxCorrelate


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

% Hint: listbox 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


% --- Executes on button press in BtnOutputFile.
function BtnOutputFile_Callback(hObject, eventdata, handles)
% hObject    handle to BtnOutputFile (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)
[fileName, pathName] = uiputfile('resources.txt', 'Save file name');
if isequal(fileName, 0)
    set(handles.EditBxFileoutput, 'String', 'Cancel selected');
else
    set(handles.EditBxFileoutput, 'String', fullfile(pathName, fileName));
    set(handles.BtnGenerate, 'Enable', 'on')
end


% --- Executes during object creation, after setting all properties.
function EditBxAccuracy_CreateFcn(hObject, eventdata, handles)
% hObject    handle to EditBxAccuracy (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


% --- Executes on button press in checkboxUseAllAttrib.
function checkboxUseAllAttrib_Callback(hObject, eventdata, handles)
% hObject    handle to checkboxUseAllAttrib (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)

% Hint: get(hObject,'Value') returns toggle state of checkboxUseAllAttrib



function EditPeriods_Callback(hObject, eventdata, handles)
% hObject    handle to EditPeriods (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 EditPeriods as text
%        str2double(get(hObject,'String')) returns contents of EditPeriods as a double


% --- Executes during object creation, after setting all properties.
function EditPeriods_CreateFcn(hObject, eventdata, handles)
% hObject    handle to EditPeriods (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


% --- Executes on button press in checkboxSharp.
function checkboxSharp_Callback(hObject, eventdata, handles)
% hObject    handle to checkboxSharp (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)

% Hint: get(hObject,'Value') returns toggle state of checkboxSharp



function EditBusyIdleThresh_Callback(hObject, eventdata, handles)
% hObject    handle to EditBusyIdleThresh (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 EditBusyIdleThresh as text
%        str2double(get(hObject,'String')) returns contents of EditBusyIdleThresh as a double


% --- Executes during object creation, after setting all properties.
function EditBusyIdleThresh_CreateFcn(hObject, eventdata, handles)
% hObject    handle to EditBusyIdleThresh (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
