function varargout = IMPACT_Data(varargin)
% IMPACT_Data
%   IMPACT_Data is main GUI for IMPACT data_analysis

%   Project: IMPACT
%   Title of Code: controller_design
%   Relevant additional documentation:
%   Developer: Carlos Gonzalez
%   External Dependencies: NA
%
%   Disclaimer
%   CAUTION: It is strongly recommended that changes to this code
%   should be avoided without first consulting with authors.
%-----------

gui_Singleton = 1;
gui_State = struct('gui_Name',       mfilename, ...
    'gui_Singleton',  gui_Singleton, ...
    'gui_OpeningFcn', @IMPACT_Data_OpeningFcn, ...
    'gui_OutputFcn',  @IMPACT_Data_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 IMPACT_Data is made visible.
function IMPACT_Data_OpeningFcn(hObject, eventdata, handles, varargin)
% start up picture
splash();

set(hObject,'Keypressfcn',@key_press);

movegui( gcf, 'center' );% move the gui to the center

addIMPACTIcon(hObject);

set(gcf, 'DefaultTextFontName', 'Verdana');

% Choose default command line output for IMPACT_Data
handles.output = hObject;
handles.group = []; % group counter
handles.files = {}; % group files
handles.filepath = {}; % group files path
handles.mainpath = cd; % current path
handles.loadFileType = {}; % loaded file types
handles.signal = {}; % signal list
handles.dellist = {}; % flex signal dellist
handles.Data = []; % data for current selected file
handles.sig = []; % selected signal in signal list
handles.psdLength = 2^12; % default value for spectrum analysis
handles.fft = 2^12;
handles.spectrumCounter = []; % counter for sprectrum analysis
handles.spectrumLegend = []; % legend for sprectrum analysis
handles.sigSpectrum = []; % spectrum signal from pwelch
handles.spectraUnit = []; % current spectra unit
handles.storedPaths = {}; % previously selected files and paths
handles.W1P.w1p = 0; % 1p frequency
handles.W1P.w = 0; % 1p speed
handles.W1P.n = 0; % 1p gearbox ratio
handles.W1P.b = 0; % number of blades 

% Update handles structure
guidata(hObject, handles);


%% toolbar settings
fh = handles.newfgui2;
set( fh, 'Toolbar', 'figure' );

tbh = findall(fh,'Type','uitoolbar'); % handle to the toolbar
% tooltipstrings
%
% 'Show Plot Tools and Dock Figure',
% 'Hide Plot Tools'
% 'Insert Legend'
% 'Insert Colorbar'
% 'Link Plot'
% 'Brush/Select Data'
% 'Data Cursor'
% 'Rotate 3D'
% 'Pan'
% 'Zoom Out'
% 'Zoom In'
% 'Edit Plot'
% 'Print Figure'
% 'Save Figure'
% 'Open File'
% 'New Figure'

saveh2 = findall( tbh, 'tooltipstring', 'Save Figure' );
saveh = findall( tbh, 'tooltipstring', 'Save Figure' );
openh = findall( tbh, 'tooltipstring', 'Open File' );
newh =  findall( tbh, 'tooltipstring', 'New Figure' );
edith = findall( tbh, 'tooltipstring', 'Edit Plot' );
printh = findall( tbh, 'tooltipstring', 'Print Figure' );
showPlotH = findall( tbh, 'tooltipstring', 'Show Plot Tools and Dock Figure' );
hidePlotH = findall( tbh, 'tooltipstring', 'Hide Plot Tools' );
insertLegendH = findall( tbh, 'tooltipstring', 'Insert Legend'   );
insertColorbarH = findall( tbh, 'tooltipstring', 'Insert Colorbar'   );
linkH = findall( tbh, 'tooltipstring', 'Link Plot'   );
brushH = findall( tbh, 'tooltipstring', 'Brush/Select Data'   );
rotateH = findall( tbh, 'tooltipstring', 'Rotate 3D'   );
panH = findall( tbh, 'tooltipstring', 'Pan'   );
% delete the 'save figure', 'open file' and 'new figure','edit plot', 'print figure',
% 'Show Plot Tools and Dock Figure', 'Hide Plot Tools', 'Insert Legend', 'Insert Colorbar' button
delete( [saveh2, saveh, openh, newh, edith, printh, showPlotH, hidePlotH, insertLegendH,...
    insertColorbarH, linkH, brushH, rotateH, panH ] );

%%
set( handles.edit_combinationSig, 'KeyPressFcn', @edit_combinationSig_KeyPressFcn );

[a,map]=imread('arrow3mod.jpg');
set(handles.pushbutton_timeFig,'CData',a);
set(handles.pushbutton_specFig,'CData',a);


% --- Outputs from this function are returned to the command line.
function varargout = IMPACT_Data_OutputFcn(hObject, eventdata, handles)
% Get default command line output from handles structure
varargout{1} = [];


% function bladedfile( signals )
function bladedReturn(signals)
% build the signal list and update guidata

hFigure = findobj( 'tag', 'newfgui2' ); % handles to the main figure
handles = guidata( hFigure );

group = handles.group;

%% set up the group list box
GroupStr = get(handles.listbox_groupList, 'String');
newGroupStr = vertcat(GroupStr, {['sim', num2str(group)]});
set(handles.listbox_groupList, 'String', newGroupStr, 'Value', group);

%% set up the files list box
set(handles.listbox_fileList, 'String', handles.files{group});

%% update signal list
handles.signal{group} = signals.fullSig; % signal list
handles.units{group} = signals.units; % group units
handles.signalBladed(group) = signals;

% exclude non-power production files
handles.files{group} = handles.files{group}(signals.isPowProd);
handles.fullFiles{group} = handles.fullFiles{group}(signals.isPowProd);

guidata( hFigure, handles );

listbox_groupList_Callback(handles.listbox_groupList, [], handles)

function bladedAddedReturn(signals)
% build the signal list and update guidata

hFigure = findobj( 'tag', 'newfgui2' ); % handles to the main figure
handles = guidata( hFigure );

group = get(handles.listbox_groupList, 'Value');

%% update signal list
handles.signal{group} = signals.fullSig; % signal list
handles.units{group} = signals.units; % group units
handles.signalBladed(group) = signals;

% exclude non-power production files
handles.files{group} = handles.files{group}(signals.isPowProd);
handles.fullFiles{group} = handles.fullFiles{group}(signals.isPowProd);

guidata( hFigure, handles );

listbox_groupList_Callback(handles.listbox_groupList, [], handles)


% --------------------------------------------------------------------
function menu_fileLoad_Callback(hObject, eventdata, handles)

groupStr = get(handles.listbox_groupList, 'String');
group = length(groupStr) + 1;

%% get filenames and filepath
pathsSelected = selectFiles(1, handles.storedPaths);
% pathsSelected = {'E:\External Data\'};
if isempty(pathsSelected)
    return;
end

fullFiles = {};
hWait = waitbarMLS(1, 'Loading folders...');
set(hWait, 'pointer', 'watch');

for m = 1:numel(pathsSelected)
    dirName = pathsSelected{m};
    if isdir(dirName)
        allPath = getAllSubs(dirName);
        %% check if there are available files
        All = getSubfolder(allPath);
        fullFiles = [fullFiles; All.fullFiles];
    else
        fullFiles = [fullFiles; dirName];
    end
end
close(hWait);


if isempty(fullFiles)
    warndlgMLS('There are no available simulations in the selected folder and its subfolders.');
    return
end


handle_tempFig = figureMLS('visible', 'off', 'handleVisibility', 'off');
guidata(handle_tempFig, 'Cancel');

nFiles = length(fullFiles);
filenames = cell(nFiles, 1);
[path, name, prevExt] = fileparts(fullFiles{1});
for m = 1:nFiles
    [path, name, ext] = fileparts(fullFiles{m});

    if ~strcmp(prevExt, ext)
        if ~strcmp(guidata(handle_tempFig), 'yes2all')
            hWarn = wrndlgMLS(handle_tempFig, sprintf('The file %s is a different file type from previous one. It will be ignored. Continue?', fullFiles{m}));
            uiwait(hWarn);
            button = guidata(handle_tempFig);
            if strcmp(button, 'Cancel')
                close(handle_tempFig);
                return
            end
            fullFiles{m} = [];
        else
            fullFiles{m} = [];
        end
    end
    filenames{m} = [name, ext];
end
close(handle_tempFig);

fullInd = cellfun('isempty', fullFiles);
fullFiles = fullFiles(~fullInd);
filenames = filenames(~fullInd);

handles.storedPaths = pathsSelected;
handles.fullFiles{group} = fullFiles;
handles.group = group;

% change $pj into $PJ
filenames = changePJ(filenames);

% tell which kind of files have been loaded, flex or bladed
[fold,fileN, ext] = fileparts(filenames{1});
ext = ext(2:end);


[fullFiles, fileInd] = sort(fullFiles);
filenames = filenames(fileInd);

%% set file names
filenames = regexprep(filenames, '\.\$PJ', '');% discard .$PJ
fullFiles = regexprep(fullFiles, '\.\$PJ', '');% discard .$PJ
handles.loadFileType{group} = 'bladed';
handles.files{group} = filenames;
handles.fullFiles{group} = fullFiles;
handles.returnFcnH = @bladedReturn;
% update guidata
guidata( hObject, handles );

%function for bladed signal selection
newbladedsignalchk( fullFiles,[], [], handles );


% --------------------------------------------------------------------
function menu_fileMenu_Callback(hObject, eventdata, handles)

% --------------------------------------------------------------------
function menu_fileClose_Callback(hObject, eventdata, handles)
close(ancestor(hObject, 'figure'));


function restart
hFig = findobj('tag', 'newfgui2');
close(hFig);
data_analyser;




% --- Executes on selection change in listbox_groupList.
function listbox_groupList_Callback(hObject, eventdata, handles)

% This is used to check if there are signals in the signal list
signalCh = get(handles.listbox_groupList, 'String');
if isempty(signalCh)
    errordlgMLS('No signals found.');
    return
end

group = get( hObject, 'Value' );

%% set up file and signal list
H1 = handles.listbox_fileList;
H2 = handles.listbox_signalList;
files = handles.files{group};
signal = handles.signal{group};

if get( handles.togglebutton_holdOn, 'Value' )
    val = [];
else val = 1;
end

set( H1, { 'Value', 'String' }, { 1, files } );
set( H2, { 'Value', 'String' }, { val, signal } );

listbox_fileList_Callback( H1, eventdata, handles)


% --- Executes during object creation, after setting all properties.
function listbox_groupList_CreateFcn(hObject, eventdata, handles)
if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
    set(hObject,'BackgroundColor','white');
end


% --- Executes on selection change in listbox_fileList.
function listbox_fileList_Callback(hObject, eventdata, handles)

% This is used to check if there are signals in the signal list
signalCh = get(handles.listbox_groupList, 'String');
if isempty(signalCh)
    errordlgMLS('No signals found.');
    return
end

group = get( handles.listbox_groupList, 'Value' );

if get( handles.togglebutton_holdOn, 'Value' )
    set(handles.listbox_signalList, 'Value', []);
end

set(handles.listbox_signalList, 'String', handles.signal{group});

%% set up the group info panel
fullFileArray = handles.fullFiles{group};
fullFile = fullFileArray{get(hObject, 'Value')};
groupInfo = fileparts(fullFile);
H3 = handles.text_groupInfo;
set( H3, 'String', groupInfo, 'toolTipString', groupInfo);

%%
listbox_signalList_Callback( handles.listbox_signalList, eventdata, handles)


% --- Executes during object creation, after setting all properties.
function listbox_fileList_CreateFcn(hObject, eventdata, handles)
if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
    set(hObject,'BackgroundColor','white');
end

function hWait_CloseRequestFcn_Callback(hObject, eventdata, handles)
set(handles.listbox_signalList, 'enable', 'on');
delete(gcbf);


% --- Executes on selection change in listbox_signalList.
function listbox_signalList_Callback(hObject, eventdata, handles)

% This is used to check if there are signals in the signal list
signalCh = get(handles.listbox_groupList, 'String');
if isempty(signalCh)
    errordlgMLS('No signals found.');
    return
end

% set the combinational signal listbox to empty
set( handles.listbox_combinationSig, 'Value', [] )


%% get the current signal
index = get(hObject, 'Value'); % signal index
if isempty(index)
    return
elseif numel(index) > 1
    index = index(1);
end

group = get( handles.listbox_groupList, 'Value' ); % group index

contents = get( hObject, 'String' ); % signal list string
strOfylabel = contents{ index }; % signal string in the signal list

%%
% filepath = handles.filepath{group};
% fileArray = get(handles.listbox_fileList, 'String' );
% fileIndex = get(handles.listbox_fileList,'Value');
% file = fileArray{fileIndex};
fullFileArray = handles.fullFiles{group};
fullFile = fullFileArray{get(handles.listbox_fileList, 'Value')};

hWait = waitbarMLS(1, 'Loading data. Please wait...',...
                      'CloseRequestFcn', {@hWait_CloseRequestFcn_Callback, handles} );
set(handles.listbox_signalList, 'enable', 'off');

groupChkRad = handles.signalBladed(group).groupChkRad;
ptFiles = handles.signalBladed(group).ptFiles;
[data, Data.time] = getSignal4B(fullFile, groupChkRad, ptFiles, index, 'time');
if isempty(data)
    close(hWait);
    return
end
Data.currentSig = data{1};
handles.Data = Data;
guidata(hObject, handles);
%% signal
signal = Data.currentSig; % double array signal

%% unit
Data.units = handles.units{group}; % units
unit = Data.units{ index }; % signal unit
%%
signalplot( signal, handles, unit, strOfylabel, hWait )

function signalplot( sig, handles, unit, strOfylabel, hWait )
% plot the signal in time and frequency domain

% can be used by both signal list and combinational signal list
%
% sig: the double array signal
% handles: handles to the current figure
% unit: the unit string for the signal
% strOfylabel: the string of the signal

time = handles.Data.time; % signal time

strOfxlabel = 'Time (s)';

%% remove NaN or Inf
sigInd = isfinite(sig);
if ~all(sigInd)
    newSig = sig(sigInd);
    set(handles.text_sigWarn, 'Visible', 'On');
    if numel(newSig) == 0
        errordlgMLS('No available finite data point.');
        close(hWait);
        return
    end
else
    newSig = sig;
    set(handles.text_sigWarn, 'Visible', 'Off');
end


%% statistics calculation and display
% mean
mean_str=sprintf('%g', mean(newSig));
set(handles.text_mean,'String',mean_str);
% standard deviation
stdev_str=sprintf('%g',sqrt(var(newSig)));
set(handles.text_stdDeviation,'String',stdev_str);
% maximum
max_str=sprintf('%g',max(newSig));
set(handles.text_maximum,'String',max_str);
% minimum
min_str=sprintf('%g',min(newSig));
set(handles.text_minimum,'String',min_str);
% Range
range_str=sprintf('%g',max(newSig)-min(newSig));
set(handles.text_range,'String',range_str);

%% plot in time domain
axes(handles.axes_timeDomain);

allSigs = findobj(gca, 'type', 'line');
if ishold
    sigTagInd = numel(allSigs)+1;
else sigTagInd = 1;
end

try 
    plot( time, sig, 'tag', sprintf('timeSig%d',sigTagInd) );
    handle_sig = findobj(gca, 'type', 'line', 'tag', sprintf('timeSig%d',sigTagInd));
    setLineColor(handle_sig, sigTagInd);
catch
    % for other data
    plot(sig);
end

xlabel(strOfxlabel);

grid on;

%% the string for the legend
groupStrAll = get(handles.listbox_groupList, 'String');
if isempty(groupStrAll)
    newSOY1 = strOfylabel;
else
    groupStr = groupStrAll{get(handles.listbox_groupList, 'value')};
    fileStrAll = get(handles.listbox_fileList, 'String');
    fileStr = fileStrAll{get(handles.listbox_fileList, 'Value')};
    signalNo = get(handles.listbox_signalList, 'Value');
    if isempty(signalNo)
        newSOY1 = strOfylabel;
    else
        newSOY1 = [groupStr, '_', fileStr, '_', strOfylabel];
    end
end
newSOY = regexprep(newSOY1, '\_', '\\\_');

%%
if ishold
    currentYLabel = get(get( handles.axes_timeDomain, 'ylabel'),'String');
    currentUnitArray = regexpi( currentYLabel, '\<[\S*', 'match' );

    try
        currentUnit = currentUnitArray{end}; % in case it doesnt exist
        % check if the units agree
        % if so, unit is kept; otherwise unit is set as '---'
        if strcmpi( currentUnit, unit )
            strYlabel = [ '---', ' ', unit ];
        else strYlabel = '---';
        end
    catch
        strYlabel = '---';
    end

    % get current legend
    hLegendTime = findobj(gcf, 'tag', 'dataAnalyserLegend');

    
    strLegendTime = get( hLegendTime, 'String' );
    
    newLegendNames = horzcat( strLegendTime, newSOY );
    
    delete(hLegendTime);
    temp = legend(handles.axes_timeDomain, newLegendNames );
    set(temp, 'tag', 'dataAnalyserLegend');
else
    strYlabel = [ strOfylabel, ' ' ];
    temp = legend(handles.axes_timeDomain, newSOY);
    set(temp, 'tag', 'dataAnalyserLegend');
end


strYlabel = regexprep(strYlabel, '_', '\\_');
ylabel( strYlabel );

%% plot in frequency domain
psdLength = handles.psdLength;
fft = handles.fft;
try
    sampFrequency = 1 / ( time(2) - time(1) ); % sampling frequency = 1/delta_T
catch
    % in case of scalar
    sampFrequency = 1;
end

% hold on
if get( handles.togglebutton_holdOn, 'Value' ) == 1

    counter = handles.spectrumCounter;
    counter = counter + 2;
    legendNames = handles.spectrumLegend;
    legendNames{ (counter +1) / 2 } = newSOY;

    if strcmp( strYlabel, '---' )
        unit = '---';
    else unit = unit( 2:end-1 );
    end

    % Put the signal in the listbox, so that it can be deleted 
    set(handles.listbox_allSigs, ...
        'String',          legendNames,...
        'Value',           numel(legendNames));
    
else
    counter = 1;
    legendNames{1} = newSOY;
    unit = unit( 2:end-1 );
    handles.sigSpectrum = {};

    % Put the signal in the listbox, so that it can be deleted 
    set(handles.listbox_allSigs, 'String', []);
end

handles.spectrumCounter = counter;
handles.spectrumLegend = legendNames;

try
    sigSpectrum = handles.sigSpectrum;
    [ sigSpectrum{ counter + 1 },sigSpectrum{ counter }]=...
        psdCalcMLS( sig, psdLength, psdLength/2, fft, sampFrequency );% use pwelch to find its gain,frequency

    handles.sigSpectrum = sigSpectrum;
    handles.spectraUnit = unit;
    guidata( handles.newfgui2, handles );
    set(handles.text_checkPSD, 'Visible', 'off');
catch
    %
    close(hWait);
    set(handles.text_checkPSD, 'Visible', 'on');
    return
end

axes(handles.axes_frequencyDomain);
try
   spectra( sigSpectrum{:}, legendNames{:}, unit );
catch
   errordlgMLS('Spectra cannot be plotted. The data may include Inf or NaN. Please check.'); 
   close(hWait);
   return
end

close(hWait);
guidata(handles.newfgui2, handles);

if ~get(handles.radiobutton_nPeaks, 'Value')
    return;
end
w = handles.W1P.w;
n = handles.W1P.n;
if isequal(n, 0)
    return;
end
w1p = w*pi/30/n;
if ~isFiniteNum(w1p, [0, inf; 0, 0])
    return;
end

% delete nP lines
nPLine = findobj('type', 'line', 'tag', 'nPLineSpectrum');
delete(nPLine)
% delete nP text
nPText = findobj('type', 'text', 'tag', 'nPTextSpectrum');
delete(nPText)

% redraw nP lines
yLim = get(handles.axes_frequencyDomain, 'YLim');
xLim = get(handles.axes_frequencyDomain, 'XLim');
ind = [1, 3, 6, 9];
for m = 1:4
    % nP
    val = w1p*ind(m);
    if val > xLim(2)
        break;
    end
    set(gcf, 'CurrentAxes', handles.axes_frequencyDomain);
    line([val, val], yLim, 'Color', 'k', 'tag', 'nPLineSpectrum');
    text(val, yLim(2), sprintf('%dP', ind(m)), 'HorizontalAlignment', 'right',...
        'VerticalAlignment', 'bottom', 'tag', 'nPTextSpectrum');
end
                
function listbox_signalList_CreateFcn(hObject, eventdata, handles)
if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
    set(hObject,'BackgroundColor','white');
end



% --- Executes on button press in togglebutton_holdOn.
function togglebutton_holdOn_Callback(hObject, eventdata, handles)

% This is used to check if there are signals in the signal list
signalCh = get(handles.listbox_groupList, 'String');
if isempty(signalCh)
    errordlgMLS('No signals found.');
    return
end

hTimeDomain = handles.axes_timeDomain;

% set hTimeDomain the current axes without changing its state
set( gcf, 'CurrentAxes', hTimeDomain );

%% set up current axes
if get( hObject, 'Value' )
    hold all;
else hold off;
    % check if the signal or combination signal is selected and make it
    % the current one
    signal = get( handles.listbox_signalList, 'Value' );
    signalComb = get( handles.listbox_combinationSig, 'Value' );
    
    % CC0003: hold on error if no signal is selected
    if isempty(signal)&&isempty(signalComb)
        return
    elseif isempty(signal)
        listbox_combinationSig_Callback( handles.listbox_combinationSig, [], handles );
    else listbox_signalList_Callback( handles.listbox_signalList, [], handles );
    end
    % CC0003
end


% --- Executes on selection change in listbox_combinationSig.
function listbox_combinationSig_Callback(hObject, eventdata, handles)

% This is used to check if there are signals in the signal list
signalCh = get(hObject, 'String');
if isempty(signalCh)
    errordlgMLS('No signals found.');
    return
end

set( handles.listbox_signalList, 'Value', [] );

selected = get( handles.listbox_combinationSig, 'Value' );
str = get( handles.listbox_combinationSig, 'String' );

strSig = str{ selected };

signal = handles.CombinationSig.( strSig );

char_=isa(signal,'char');
numeric_=isa(signal,'numeric');
tf_=isa(signal,'tf');
%---------------

% 07/05/2013 CG
try
    handles.Data.time = handles.CombinationSig.([strSig,'_time']);
    guidata(hObject,handles);
catch
    errordlgMLS('Time not found');
    return
end

if numeric_
    unit = '---';
    hWait = waitbarMLS(1, 'Loading data. Please wait...');
    signalplot( signal, handles, unit, strSig, hWait );
end
if tf_
    waitbar(0.2,'Plotting bode plot');
    figureMLS;
    bode(signal);
    h=waitbarMLS(1);
    close(h);
end


% --- Executes during object creation, after setting all properties.
function listbox_combinationSig_CreateFcn(hObject, eventdata, handles)
if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
    set(hObject,'BackgroundColor','white');
end






% --------------------------------------------------------------------
function menu_option_Callback(hObject, eventdata, handles)

% --------------------------------------------------------------------
function menu_optPSD_Callback(hObject, eventdata, handles)

str = inputdlgMLS({'Enter length of window of PSD', 'Enter length of FFT(nfft)'}, 'Length settings', 1,...
    {num2str(handles.psdLength), num2str(handles.fft)});
if isempty(str)
    return;
end

handles.psdLength = str2num(str{1});
handles.fft = str2num(str{2});
if ~isscalar(handles.psdLength)||~isfinite(handles.psdLength)
    errordlgMLS('length of window of PSD is not a finite number. Please check.');
    return
end
if ~isscalar(handles.fft) || ~isfinite(handles.fft)
    errordlgMLS('length of FFT is not a finite number. Please check.');
    return
end

guidata(hObject, handles);



% --- Executes on key press with focus on edit_combinationSig and none of its controls.
function edit_combinationSig_KeyPressFcn(hObject, eventdata )
handles = guidata( hObject );
handles.combinationPress = eventdata.Key;
guidata( hObject, handles );



function edit_combinationSig_Callback(hObject, eventdata, handles)

if strcmp( handles.combinationPress, 'return')
    try
        %% get the string from the edit box
        str1 = get( hObject, 'String' ); % original string
        % test if there is '='
        equalSign = findstr( str1, '=' );
        if isempty( equalSign )
            str = [ 'ans=' str1 ];
            str_start = 5;
        else str = str1;
            str_start = equalSign(1) + 1;
        end
        strVar = strtrim( str( 1: str_start-2 ) ); % the var name before '='
        str2 = str( str_start:end ); % the string after '='
        %% check if there are existing variables in the combinational signal listbox
        strCombinationSig = get( handles.listbox_combinationSig, 'String' );
        nCombinationSig = numel( strCombinationSig );
        
        allVariab = regexp(str2, '\w+', 'match');
        
        for iCombinationSig = 1: nCombinationSig
            currentStr = strCombinationSig{iCombinationSig};
            for m=1:numel(allVariab)
                if strcmp(allVariab{m}, currentStr)
                    eval([allVariab{m}, '= handles.CombinationSig.', currentStr, ';']);
                    eval(['data2.time = handles.CombinationSig.', currentStr, '_time;']);
                end
            end
        end
        %% group signals
        exprGroupSignal = 'sim\d+\_\d+\_\d+';
        
        groupSignal = regexp(str2, exprGroupSignal, 'match');
        nGroup = numel( groupSignal );

        % begin to get the groupSignal one by one
        for iGroup = 1: nGroup

            % groupSignal{ iGroup } is the groupSignal such as 'sim1_20a_Power'
            numberArray = regexp( groupSignal{ iGroup }, '\d+', 'match' );
            %% groupNo, fileNo, signalNo
            groupNo = str2double( numberArray{1} );

            fileNo = str2double(numberArray{2});
            fileArray = handles.files{groupNo};
            fileStr = fileArray{fileNo};

            signalNo = str2double(numberArray{3});

            fullFileArray = handles.fullFiles{groupNo};
            fullFile = fullFileArray{fileNo};


                % Files
                %% data structure
                % fieldnames:
                % - signalArray
                % - units
                % - description
                % - ??
                groupChkRad = handles.signalBladed(groupNo).groupChkRad;
                ptFiles = handles.signalBladed(groupNo).ptFiles;
                [dataTemp, data1.time, fieldArray] = getSignal4B(fullFile, groupChkRad, ptFiles, signalNo, 'time', 'fieldArray');
                if isempty(dataTemp)
                    return
                end
                
                data1.signalArray = dataTemp{1};
                
                fullSig = translateBladedSig;
                abbrevi = fullSig.abbreviation;
                descrip = fullSig.description;
                unitSig = fullSig.unit;
                abb_ind = find(strcmp(abbrevi, fieldArray{1}), 1);
                if ~isempty(abb_ind)
                    description =  descrip{abb_ind(1)};
                    unit = unitSig{abb_ind(1)};
                else
                    description = '.';
                    unit = '.';
                end
                data1.description = description;
                data1.unit = unit;
            eval([groupSignal{iGroup}, '= data1.signalArray;']);
        end % iGroup
        %%
        eval( [ 'handles.CombinationSig.', strVar, '=', str2, ';' ] );
        % Save the time for combined signals
        % Needed for uploading data from MATLAB workspace
        if exist('data2','var')
            if exist('data1','var')
                if numel(data1.time)~=numel(data2.time)
                    errordlgMLS('Combined signals and Signals have to have to same number of elements','Error');
                    return;
                end
            else
                time = data2.time;
            end
        else
            time = data1.time;
        end
            
        handles.CombinationSig.([strVar,'_time']) = time;
    catch
        errordlgMLS( lasterr, 'Incorrect expression' );
        return
    end
    %         strVariable2 = strfind( strCombinationSig, strVariable );
    for m = nCombinationSig : -1 :1
        currentStr = strCombinationSig{m};
        if strcmp( currentStr, strVar )
            strCombinationSig( m ) = [];
        end
    end

    newStr = vertcat( { strVar}, strCombinationSig );

    cd( handles.mainpath )
    set( handles.listbox_combinationSig, 'String', newStr );

    guidata( hObject, handles );
    set( handles.listbox_combinationSig, 'Value', 1 );
    listbox_combinationSig_Callback( handles.listbox_combinationSig, eventdata, handles );

end



% --- Executes during object creation, after setting all properties.
function edit_combinationSig_CreateFcn(hObject, eventdata, handles)
if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
    set(hObject,'BackgroundColor','white');
end


function contMenuSignalPass_Callback(hObject, eventdata, handles)

% This is used to check if there are signals in the signal list
signalCh = get(handles.listbox_groupList, 'String');
if isempty(signalCh)
    errordlgMLS('No signals found.');
    return
end

groupNo = get( handles.listbox_groupList , 'Value' );
fileNo = get(handles.listbox_fileList, 'Value' );
signalNo = get( handles.listbox_signalList, 'Value' );
oldStr = get( handles.edit_combinationSig, 'String' );
set(handles.edit_combinationSig,'String',sprintf('%s sim%d_%d_%d', oldStr, groupNo, fileNo, signalNo));


function contMenusignalList_Callback(hObject, eventdata, handles)


function menu_help_Callback(hObject, eventdata, handles)

% --------------------------------------------------------------------
function menu_helpDoc_Callback(hObject, eventdata, handles)
try
    open(fullfile(matlabroot,'toolbox','IMPACT','help','IMPACT Data Analyser Manual.pdf'));
catch
    errordlgMLS(sprintf('The manual cannot be opened.\nPlease make sure you have not changed the path %s',fullfile(matlabroot,'toolbox','IMPACT','help')));
end



function contMenu_comSignal_Callback(hObject, eventdata, handles)


function contMenu_deleteSig_Callback(hObject, eventdata, handles)

% This is used to check if there are signals in the signal list
signalCh = get(handles.listbox_groupList, 'String');
if isempty(signalCh)
    errordlgMLS('No signals found.');
    return
end

hListbox = handles.listbox_combinationSig;
deleteOneSig(hListbox);



function contMenu_comSig2ws_Callback(hObject, eventdata, handles)

% This is used to check if there are signals in the signal list
signalCh = get(handles.listbox_groupList, 'String');
if isempty(signalCh)
    errordlgMLS('No signals found.');
    return
end
props = get( handles.listbox_combinationSig, { 'String', 'Value' } ); % get the properties
contentsSig = props{1}; % strings for all signals
indexSig = props{2}; % index

strSig = contentsSig{indexSig}; % signal string
signal = handles.CombinationSig.(strSig); % double array signal

assignin( 'base', strSig, signal ); % pass to Matlab workspace


function contMenu_sig2ws_Callback(hObject, eventdata, handles)

% This is used to check if there are signals in the signal list
signalCh = get(handles.listbox_groupList, 'String');
if isempty(signalCh)
    errordlgMLS('No signals found.');
    return
end

props = get( handles.listbox_signalList, { 'String', 'Value' } ); % get the properties
contentsSig = props{1}; % strings for all signals
indexSig = props{2}; % index

fullStrSig = contentsSig{indexSig}; % signal string
%% get the double array signal

if isempty(indexSig)
    return
end
% group = get( handles.listbox_groupList, 'Value' );

expr = '\[.*\]|\-';
strSig = regexprep( fullStrSig, expr, '' );

signal = handles.Data.currentSig; % double array signal

assignin( 'base', genvarname(strSig), signal ); % pass to Matlab workspace



function pushbutton_timeFig_Callback(hObject, eventdata, handles)
newFig = figureMLS( 'numbertitle', 'off', 'name', 'Time Series' ); % new figure


hListbox = handles.listbox_allSigs;
str = get(hListbox, 'String');
if isempty(str)
    index = 1;
else
    index = 1:numel(str);
end

% delete time domain signal
axes_time = handles.axes_timeDomain;
for m=1:numel(index)
    sig = findobj(axes_time, 'type', 'line', 'tag', sprintf('timeSig%d', index(m)));
    copyobj(sig,gca);
end
grid on;

% get the children of the time axes
axes_child = get( handles.axes_timeDomain,'children'  );
% get the legend string and set
strLegendTemp = get( axes_child, 'displayname' );
if ~iscell(strLegendTemp)
   strLegendTemp = {strLegendTemp}; 
end
strLegend = cell(1, numel(strLegendTemp));
for m = 1:numel(strLegendTemp)
    strLegend(m) = strLegendTemp(end-m+1);
end
if ~all(cellfun(@isempty,strLegend))
    legend(strLegend);
end

function pushbutton_specFig_Callback(hObject, eventdata, handles)

sigSpectrum = handles.sigSpectrum;
legendNames = handles.spectrumLegend;
unit = handles.spectraUnit;

figureMLS( 'numbertitle', 'off', 'name', 'Spectrum' ); % new figure

try
    spectra( sigSpectrum{:}, legendNames{:}, unit );
catch
    errordlgMLS('Spectra cannot be plotted. The data may include Inf or NaN. Please check.');
    return
end

if ~get(handles.radiobutton_nPeaks, 'Value')
    return;
end
w = handles.W1P.w;
n = handles.W1P.n;
if isequal(n, 0)
    return;
end
w1p = w*pi/30/n;
if ~isFiniteNum(w1p, [0, inf; 0, 0])
    return;
end

% redraw nP lines
yLim = get(handles.axes_frequencyDomain, 'YLim');
xLim = get(handles.axes_frequencyDomain, 'XLim');
ind = [1, 3, 6, 9];
for m = 1:4
    % nP
    val = w1p*ind(m);
    if val > xLim(2)
        break;
    end
    line([val, val], yLim, 'Color', 'k', 'tag', 'nPLineSpectrum');
    text(val, yLim(2), sprintf('%dP', ind(m)), 'HorizontalAlignment', 'right',...
        'VerticalAlignment', 'bottom', 'tag', 'nPTextSpectrum');
end


function menu_about_Callback(hObject, eventdata, handles)
About();



function key_press(source,event)


% --- Executes on selection change in listbox_allSigs.
function listbox_allSigs_Callback(hObject, eventdata, handles)


% --- Executes during object creation, after setting all properties.
function listbox_allSigs_CreateFcn(hObject, eventdata, handles)
if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
    set(hObject,'BackgroundColor','white');
end


% --------------------------------------------------------------------
function deleteOneSig_Callback(hObject, eventdata, handles)
% hObject    handle to deleteOneSig (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)



% --------------------------------------------------------------------
function contMenu_deleteOneSig_Callback(hObject, eventdata, handles)


% This is used to check if there are signals in the signal list
signalCh = get(handles.listbox_groupList, 'String');
if isempty(signalCh)
    errordlgMLS('No signals found.');
    return
end

hListbox = handles.listbox_allSigs;

% if there is only one signal, error
contents = get(hListbox, 'String');
nSigs = numel(contents);

if numel(get(hListbox, 'Value')) == nSigs
    errordlgMLS('Cannot delete all signals.');
    return
end

% the deleted signal index
[index, newContents] = deleteOneSig(hListbox);

% delete time domain signal
axes_time = handles.axes_timeDomain;

for m=1:numel(index)
    sig = findobj(axes_time, 'type', 'line', 'tag', sprintf('timeSig%d', index(m)));
    delete(sig);
end

% reset the color
allSigs = 1:nSigs;
allSigs(index) = [];

for m = 1:nSigs - numel(index)
    sig = findobj(axes_time, 'type', 'line', 'tag', sprintf('timeSig%d', allSigs(m)));
    % reset the tag
    set(sig, 'tag', sprintf('timeSig%d', m));
    
    setLineColor(sig, m);
end

% time axis legend
hLegendTime = findobj(gcf, 'tag', 'dataAnalyserLegend');
delete(hLegendTime);
temp = legend(axes_time, newContents);
set(temp, 'tag', 'dataAnalyserLegend');


% delete freq domain singal
hWait = waitbarMLS(1, 'Deleting data. Please wait...',...
    'CloseRequestFcn', {@hWait_CloseRequestFcn_Callback, handles} );

for m=numel(index):-1:1
    handles.spectrumCounter = handles.spectrumCounter - 2;
    handles.sigSpectrum(2*index(m) - 1: 2*index(m)) = [];
    handles.spectrumLegend(index(m)) = [];
end

sigSpectrum = handles.sigSpectrum;
legendNames = handles.spectrumLegend;
unit = handles.spectraUnit;
axes(handles.axes_frequencyDomain);
try
   spectra( sigSpectrum{:}, legendNames{:}, unit );
catch
   errordlgMLS('Spectra cannot be plotted. The data may include Inf or NaN. Please check.'); 
   close(hWait);
   return
end

close(hWait);
guidata(hObject, handles);

if ~get(handles.radiobutton_nPeaks, 'Value')
    return;
end
w = handles.W1P.w;
n = handles.W1P.n;
w1p = w*pi/30/n;
if ~isFiniteNum(w1p, [0, inf; 0, 0])
    return;
end

% delete nP lines
nPLine = findobj('type', 'line', 'tag', 'nPLineSpectrum');
delete(nPLine)
% delete nP text
nPText = findobj('type', 'text', 'tag', 'nPTextSpectrum');
delete(nPText)

% redraw nP lines
yLim = get(handles.axes_frequencyDomain, 'YLim');
xLim = get(handles.axes_frequencyDomain, 'XLim');
ind = [1, 3, 6, 9];
for m = 1:4
    % nP
    val = w1p*ind(m);
    if val > xLim(2)
        break;
    end
    set(gcf, 'CurrentAxes', handles.axes_frequencyDomain);
    line([val, val], yLim, 'Color', 'k', 'tag', 'nPLineSpectrum');
    text(val, yLim(2), sprintf('%dP', ind(m)), 'HorizontalAlignment', 'right',...
        'VerticalAlignment', 'bottom', 'tag', 'nPTextSpectrum');
end



function setLineColor(hObject, index)
% set the line color according to its index

color = [...
    0 0 1;
    0 0.5 0;...
    1 0 0;...
    0 0.75 0.75;...
    0.75 0 0.75;...
    0.75 0.75 0;...
    0.25 0.25 0.25];

set(hObject, 'color', color(index,:));


function [index, contents] = deleteOneSig(hListbox)
% This is used to delete the selected signal string for the given listbox handle

contents = get( hListbox, 'String' );
index = get( hListbox, 'Value' );
if ~isempty(contents)
    contents(index) = [];
end
set( hListbox, 'String', contents, 'value', numel(contents) );



function data_analyser_CloseRequestFcn(hObject, evd, handles)
handle_tempFig = figureMLS('visible', 'off', 'handleVisibility', 'off');
guidata(handle_tempFig, 'Cancel');
hWarn = wrndlgMLS(handle_tempFig, sprintf('This will close all data analyser tools. Continue?'), 'invisible');
uiwait(hWarn);
button = guidata(handle_tempFig);
close(handle_tempFig);
if strcmp(button, 'OK')
    hFig{1} = findobj('type', 'figure', 'tag', 'newfgui2');
    hFig{2} = findobj('type', 'figure', 'tag', 'MLS_icon');
    hFig{3} = findobj('type', 'figure', 'Name', 'Length settings');
    allFig = [hFig{:}];
    delete(allFig);   
end




% --- Executes on button press in radiobutton_nPeaks.
function radiobutton_nPeaks_Callback(hObject, eventdata, handles)
%% nP lines
if ~get(handles.radiobutton_nPeaks, 'Value')
    % delete nP lines
    nPLine = findobj('type', 'line', 'tag', 'nPLineSpectrum');
    delete(nPLine)
    % delete nP text
    nPText = findobj('type', 'text', 'tag', 'nPTextSpectrum');
    delete(nPText)
else
    str = inputdlgMLS({'Wave period (s)'}, 'Enter value', 1,...
        {num2str(handles.W1P.w)});
    
    if ~isempty(str)
        w = str2double(str{1});
        if ~isFiniteNum(w, [0, inf; 0, 0])
            errordlgMLS('Values must be a positive number');
        else
            w1p = 2*pi/w;
            handles.W1P.w = w1p;
            guidata(handles.newfgui2, handles);
            
            % delete nP lines
            nPLine = findobj('type', 'line', 'tag', 'nPLineSpectrum');
            delete(nPLine)
            % delete nP text
            nPText = findobj('type', 'text', 'tag', 'nPTextSpectrum');
            delete(nPText)

            % redraw nP lines
            yLim = get(handles.axes_frequencyDomain, 'YLim');
            xLim = get(handles.axes_frequencyDomain, 'XLim');
            numP = 4;                 % Number of nP to be drawn
            ind = 1:numP;              
            for m = 1:numP
                % nP
                val = w1p*ind(m);
                if val > xLim(2)
                    break;
                end
                set(gcf, 'CurrentAxes', handles.axes_frequencyDomain);
                line([val, val], yLim, 'Color', 'k', 'tag', 'nPLineSpectrum');
                text(val, yLim(2), sprintf('%dP', ind(m)), 'HorizontalAlignment', 'right',...
                    'VerticalAlignment', 'bottom', 'tag', 'nPTextSpectrum');
            end
        end
    end
end



% --------------------------------------------------------------------
function menu_addRemoveSims_Callback(hObject, eventdata, handles)
signalCh = get(handles.listbox_groupList, 'String');
if isempty(signalCh)
    errordlgMLS('No signals found.');
    return
end

fcnH.groupList = @listbox_groupList_Callback;
addRemoveSims(handles, fcnH);


% --------------------------------------------------------------------
function menu_addRemoveSigs_Callback(hObject, eventdata, handles)
% This is used to check if there are signals in the signal list
signalCh = get(handles.listbox_groupList, 'String');
if isempty(signalCh)
    errordlgMLS('No signals found.');
    return
end

group = get(handles.listbox_groupList, 'Value');
fullFiles = handles.fullFiles{group};
groupChkRad = handles.signalBladed(group).groupChkRad;
switch handles.loadFileType{group}
    case 'bladed'
        handles.returnFcnH = @bladedAddedReturn;
        guidata(hObject,handles);
        newbladedsignalchk(fullFiles, groupChkRad, [], handles);
end




% --------------------------------------------------------------------
function contMenu_uploadFromWs_Callback(hObject, eventdata, handles)
[Data ok] = uploadVbles();
if ok
    strCombinationSig = get( handles.listbox_combinationSig, 'String' );
    nCombinationSig = numel( strCombinationSig );
    for m = nCombinationSig : -1 :1
        currentStr = strCombinationSig{m};
        if strcmp( currentStr, Data.name)
            strCombinationSig( m ) = [];
        end
    end

    newStr = vertcat( strCombinationSig, { Data.name} );

    set( handles.listbox_combinationSig, 'String', newStr );
    handles.CombinationSig.([Data.name,'_time']) = Data.time;
    handles.CombinationSig.([Data.name]) = Data.currentSig;
    guidata(hObject,handles);
else
    errordlgMLS('Data could not be uploaded from the MATLAB workspace','Error');
end
% --------------------------------------------------------------------
