function [data,columns] = queryDatabase(db,query)
%QUERYDATABASE Query a database.
%   queryDatabase(DATABASE,QUERY) returns results of the query and the
%   column names as cell arrays.  Any errors will be thrown as
%   real errors.
%
%   Example:
%
%     db = database('foo','bar','baz');
%     query = 'select * from something';
%     [data,names] = queryDatabase(db,query)
%     s = cell2struct(data,names,2);
%     close(db);

% Matthew J. Simoneau
% Copyright 1984-2007 The MathWorks, Inc.

curs = exec(db,query);
error(curs.Message);
curs = fetch(curs);
error(curs.Message)
data = curs.Data;

cnames = columnnames(curs);
% This doesn't work if there are single quotes in the field names.
% eval(['columns = {' cnames(:) '};'])
% Use split instead.
columns = split(cnames(2:end-1),''',''');

close(curs)

if isequal(size(data),[1 1]) && isequal(data{1},'No Data')
    data = cell(0,length(columns));
end

function cellArray = split(str,delimiter)
%SPLIT divides a string into a cell array of strings based on a delimiter.
%   SPLIT(STR,DELIMITER) breaks STR into chunks sectioned by DELIMITER and
%   returns a cell array of these chunks.
%
%     >> split('fooMJSbarMJSbaz','MJS')
%
%     ans =
%
%         'foo'
%         'bar'
%         'baz'

% Matthew J. Simoneau, April 2003

dLength = length(delimiter);
matches = strfind(str,delimiter);
if isempty(matches)
    cellArray{1} = str;
else
    cellArray{1} = str(1:matches(1)-1);
    for i = 1:length(matches)-1
        cellArray{end+1,1} = str(matches(i)+dLength:matches(i+1)-1);
    end
    cellArray{end+1,1} = str(matches(end)+dLength:end);
end


function stackorder_menu(parent)
    % stackorder_menu context menu for sort order

    %FIXME doesn't seem to attach to all items
    c=uicontextmenu('Tag','StackOrderContext');
    set(parent,'UIContextMenu',c);
    uimenu(c,'Label','top'    , 'MenuSelectedFcn',@(s,~)setstack(s,'top'));
    uimenu(c,'Label','up'     , 'MenuSelectedFcn',@(s,~)setstack(s,'up'));
    uimenu(c,'Label','down'   , 'MenuSelectedFcn',@(s,~)setstack(s,'down'));
    uimenu(c,'Label','bottom' , 'MenuSelectedFcn',@(s,~)setstack(s,'bottom'));

    function setstack(source,val)
        uistack(source.Parent,val);
    end
end


function model = mappingOptimise(model, X, Y, varargin)

% MAPPINGOPTIMISE Optimise the given model.

% MLTOOLS

fhandle = str2func([model.type 'Optimise']);
model = fhandle(model, X, Y, varargin{:});


function [ state ] = getPin3State( t )
%% This function is used to get the state of the input pin 3
%     on the media flange, of the KUKA iiwa 7 R 800.

%% Syntax:
% [ state ] = getPin3State( t )

%% About:
% This function is used to get the state of the input pin number 3
%  on the media flange, of the KUKA iiwa 7 R 800.

%% Arreguments:
% t: is the TCP/IP connection.
% state:  represents the state of the input-pin. It is an integer equal to
% 1 when the pin state is true, or it is an integer equal to 0 when the
% pin state is false. Otherwise, if the pin is not connected the return
% value is empty.

% Copyright, Mohammad SAFEEA, 9th of May 2017

theCommand='getPin3';
fprintf(t, theCommand);
message=fgets(t);
state=str2num(message);
end


function tf = isVarInLaunchVehicle(var, lvdData)
    lv = lvdData.launchVehicle;
    [lvVars,~] = lv.getActiveOptVars();

    tf = false;
    for(i=1:length(lvVars))
        lvVar = lvVars(i);

        if(var == lvVar)
            tf = true;
            break;
        end
    end
end


function [output, creationString] = prtUtilObjectGuiSimple(obj)
% PRTUTILOBJECTGUISIMPLE Provides a graphical method to change an object
%
% Syntax: prtUtilStructureGui(BaseStructure,DefaultStructure,DefinitionStructure)
%
% Internal
% xxx Need Help xxx

% Numberic types bounds etc do not work
newFunctionOutput = [];

% Create default creationString
if isstruct(obj)
    guiPropNames = fieldnames(obj);
    name = inputname(1);
else
    thisClass = class(obj);
    m = meta.class.fromName(thisClass);
    name = thisClass;

    isInThisClass = cellfun(@(c)strcmp(c.DefiningClass.Name,thisClass),m.Properties);
    isSetable = cellfun(@(c)strcmp(c.SetAccess,'public'),m.Properties);
    isHidden = cellfun(@(c)c.Hidden,m.Properties);
    provideInGui = isInThisClass & ~isHidden & isSetable;

    GuiProperties = m.Properties(provideInGui);

    nGuiProperties = length(GuiProperties);
    % Create default structure

    if nGuiProperties == 0
        msgbox(sprintf('%s has no properties that can be set using this GUI.',name),'No Properties','modal');
        output = obj;
        creationString = sprintf('%s()',class(obj));

        return
    end

    guiPropNames = cellfun(@(c)c.Name,GuiProperties,'uniformoutput',false);
end

guiPropValues = cell(nGuiProperties,1);
for iProp = 1:nGuiProperties
    guiPropValues{iProp} = obj.(guiPropNames{iProp});
end

% Determine types of each field in DefaultStructure
%   This is rather difficult to do robustly
%   The if else try below is just hueristic
types = cell(length(guiPropValues),1);
for iProp = 1:length(guiPropValues)
    cVal = guiPropValues{iProp};

    if isnumeric(cVal) || islogical(cVal)
        types{iProp} = 'numeric';

    elseif ischar(cVal)
        types{iProp} = 'char';

    elseif isstruct(cVal);
        types{iProp} = 'structure';

    elseif isa(cVal,'function_handle')
        types{iProp} = 'function';

    else
        % Not a default MATLAB data type
        % Use the structure version to iteratively call this function
        types{iProp} = 'structure';

    end
end

% At this point we can't handle sub-objects or sub-structures
% So we remove them from the GUI
removeFields = strcmpi(types,'structure');
guiPropNames = guiPropNames(~removeFields);
guiPropValues = guiPropValues(~removeFields);
types = types(~removeFields);

nGuiProperties = length(guiPropValues);

structInputs = cell(nGuiProperties*2,1);
structInputs(1:2:end) = guiPropNames;
structInputs(2:2:end) = guiPropValues;
DefaultStructure = struct(structInputs{:});

OutputStructure = DefaultStructure;
BaseStructure = DefaultStructure;

%backgroundColor = get(0,'defaultFigureColor');
backgroundColor = [0.95 0.95 0.95];

DefaultMainPanelOptions.style = 'panel';
DefaultMainPanelOptions.units = 'normalized';
DefaultMainPanelOptions.position = [0.01 0.1 0.98 0.89];
DefaultMainPanelOptions.title = '';
DefaultMainPanelOptions.borderType = 'none';
DefaultMainPanelOptions.backgroundColor = backgroundColor;

MainPanelOptions = DefaultMainPanelOptions;

% Default MainFigureOptions
ss = get(0,'screensize');

windowSize = [754 600];

% Center the window
sizePads = round((ss(3:4)-windowSize));
sizePads(1) = sizePads(1)/2; % We should use 2 right?
sizePads(2) = sizePads(2)/2;
pos = cat(2,sizePads,windowSize);

DefaultMainFigureOptions.style = 'figure';
DefaultMainFigureOptions.units = 'pixels';
DefaultMainFigureOptions.position = pos;
DefaultMainFigureOptions.menuBar = 'none';
DefaultMainFigureOptions.toolbar = 'none';
DefaultMainFigureOptions.numberTitle = 'off';
DefaultMainFigureOptions.name = cat(2,'PRT Action Editor - ',name);
DefaultMainFigureOptions.color = backgroundColor;
DefaultMainFigureOptions.windowStyle = 'modal';
DefaultMainFigureOptions.CloseRequestFcn = @cancelCallback;
DefaultMainFigureOptions.backingstore = 'off';
DefaultMainFigureOptions.DoubleBuffer = 'off';

MainFigureOptions = DefaultMainFigureOptions;

% Finish making the primary elements of the gui
MainFigureOptions.Children.MainPanel = MainPanelOptions;

buttonHeight = 0.06;
MainFigureOptions.Children.Apply.style = 'pushbutton';
MainFigureOptions.Children.Apply.units = 'normalized';
MainFigureOptions.Children.Apply.position = [0.2550 0.02 0.23 buttonHeight];%[0.1 0.02 0.23 0.06];
MainFigureOptions.Children.Apply.string = 'Accept';
MainFigureOptions.Children.Apply.callback = @applyCallback;

MainFigureOptions.Children.Defaults.style = 'pushbutton';
MainFigureOptions.Children.Defaults.units = 'normalized';
MainFigureOptions.Children.Defaults.position = [0.5350 0.02 0.23 buttonHeight];%[0.38 0.02 0.23 0.06];
MainFigureOptions.Children.Defaults.string = 'Restore Defaults';
MainFigureOptions.Children.Defaults.callback = @defaultCallback;

% MainFigureOptions.Children.Cancel.style = 'pushbutton';
% MainFigureOptions.Children.Cancel.units = 'normalized';
% MainFigureOptions.Children.Cancel.position = [0.66 0.02 0.23 0.06];
% MainFigureOptions.Children.Cancel.string = 'Cancel';
% MainFigureOptions.Children.Cancel.callback = @cancelCallback;

%%

GuiInfo.usableVerticalRange = [0.1 0.85];
GuiInfo.label.horizontal = [0.01 0.32];
GuiInfo.value.horizontal = [0.34 0.65];
GuiInfo.edit.horizontal = [0.67 0.99];

GuiInfo.maxHeight = 0.05;

%% Create the field boxes

fields = fieldnames(BaseStructure);
nFields = length(fields);

itemHeight = min((GuiInfo.usableVerticalRange(2)-GuiInfo.usableVerticalRange(1))./(nFields+(nFields-1)/2), GuiInfo.maxHeight);

if itemHeight==GuiInfo.maxHeight
    % Things are maxed out in size.
    % So we resize the window to make it look nice.
    newWindowHeight = (itemHeight*nFields + GuiInfo.usableVerticalRange(1) + (1-GuiInfo.usableVerticalRange(2)))*windowSize(2);

    itemHeight = itemHeight*windowSize(2)/newWindowHeight;

    buttonHeight = buttonHeight*windowSize(2)/newWindowHeight;

    MainFigureOptions.Children.Apply.position(4) = buttonHeight;
    MainFigureOptions.Children.Defaults.position(4) = buttonHeight;

    windowSize(2) = newWindowHeight;

    sizePads = round((ss(3:4)-windowSize));
    sizePads(1) = sizePads(1)/2; % We should use 2 right?
    sizePads(2) = sizePads(2)/2;
    pos = cat(2,sizePads,windowSize);

    MainFigureOptions.position = pos;
end

bottom = max(GuiInfo.usableVerticalRange(1),mean(GuiInfo.usableVerticalRange) - itemHeight*nFields/2 - (nFields-1)/2*itemHeight/2);

verticalStarts = fliplr(bottom + cumsum([0 0.5*ones(1,nFields-1)])*itemHeight + (0:(nFields-1))*itemHeight);

if length(verticalStarts) > 1
    editOffSet = [0 (verticalStarts(1)-verticalStarts(2)-itemHeight)/2 -0.01 0];
else
    editOffSet = [0 itemHeight/4 -0.01 0];
end

fontSize = 9;

for iField = 1:nFields

    %if mod(iField,2)
        %cBackgroundColor = max(MainPanelOptions.backgroundColor-0.05,[0 0 0]);
    %else
        cBackgroundColor = MainPanelOptions.backgroundColor;
    %end

    % Label string area
    MainFigureOptions.Children.MainPanel.Children.(['label' fields{iField}]).style = 'text';
    MainFigureOptions.Children.MainPanel.Children.(['label' fields{iField}]).units = 'normalized';
    MainFigureOptions.Children.MainPanel.Children.(['label' fields{iField}]).position = [GuiInfo.label.horizontal(1) verticalStarts(iField) GuiInfo.label.horizontal(2)-GuiInfo.label.horizontal(1) itemHeight];
    MainFigureOptions.Children.MainPanel.Children.(['label' fields{iField}]).fontweight = 'bold';
    MainFigureOptions.Children.MainPanel.Children.(['label' fields{iField}]).horizontalAlignment = 'right';
    MainFigureOptions.Children.MainPanel.Children.(['label' fields{iField}]).backgroundcolor = cBackgroundColor;
    MainFigureOptions.Children.MainPanel.Children.(['label' fields{iField}]).string = [guiPropNames{iField}  ':'];

    % Value string area
    MainFigureOptions.Children.MainPanel.Children.(['value' fields{iField}]).style = 'text';
    MainFigureOptions.Children.MainPanel.Children.(['value' fields{iField}]).units = 'normalized';
    MainFigureOptions.Children.MainPanel.Children.(['value' fields{iField}]).position = [GuiInfo.value.horizontal(1) verticalStarts(iField) GuiInfo.value.horizontal(2)-GuiInfo.value.horizontal(1) itemHeight];
    MainFigureOptions.Children.MainPanel.Children.(['value' fields{iField}]).horizontalAlignment = 'left';
    MainFigureOptions.Children.MainPanel.Children.(['value' fields{iField}]).backgroundcolor = cBackgroundColor;

    % Crerate the uicontrol object
    switch types{iField}
        case 'numeric'
            MainFigureOptions.Children.MainPanel.Children.(['edit' fields{iField}]).style = 'edit';
            MainFigureOptions.Children.MainPanel.Children.(['edit' fields{iField}]).units = 'normalized';
            MainFigureOptions.Children.MainPanel.Children.(['edit' fields{iField}]).position = [GuiInfo.edit.horizontal(1) verticalStarts(iField) GuiInfo.edit.horizontal(2)-GuiInfo.edit.horizontal(1) itemHeight]+editOffSet;
            MainFigureOptions.Children.MainPanel.Children.(['edit' fields{iField}]).callback = {@numericCallback fields{iField}};
            MainFigureOptions.Children.MainPanel.Children.(['edit' fields{iField}]).fontSize = fontSize;

        case 'char'
            MainFigureOptions.Children.MainPanel.Children.(['edit' fields{iField}]).style = 'edit';
            MainFigureOptions.Children.MainPanel.Children.(['edit' fields{iField}]).units = 'normalized';
            MainFigureOptions.Children.MainPanel.Children.(['edit' fields{iField}]).position = [GuiInfo.edit.horizontal(1) verticalStarts(iField) GuiInfo.edit.horizontal(2)-GuiInfo.edit.horizontal(1) itemHeight]+editOffSet;
            MainFigureOptions.Children.MainPanel.Children.(['edit' fields{iField}]).callback = {@charCallback fields{iField}};
            MainFigureOptions.Children.MainPanel.Children.(['edit' fields{iField}]).fontSize = fontSize;

        case 'function'
            MainFigureOptions.Children.MainPanel.Children.(['edit' fields{iField}]).style = 'edit';
            MainFigureOptions.Children.MainPanel.Children.(['edit' fields{iField}]).units = 'normalized';
            MainFigureOptions.Children.MainPanel.Children.(['edit' fields{iField}]).position = [GuiInfo.edit.horizontal(1) verticalStarts(iField) GuiInfo.edit.horizontal(2)-GuiInfo.edit.horizontal(1) itemHeight]+editOffSet;
            MainFigureOptions.Children.MainPanel.Children.(['edit' fields{iField}]).callback = {@functionCallback fields{iField}};
            MainFigureOptions.Children.MainPanel.Children.(['edit' fields{iField}]).fontSize = fontSize;

        case 'boolean'
            MainFigureOptions.Children.MainPanel.Children.(['edit' fields{iField}]).style = 'checkbox';
            MainFigureOptions.Children.MainPanel.Children.(['edit' fields{iField}]).units = 'normalized';
            MainFigureOptions.Children.MainPanel.Children.(['edit' fields{iField}]).position = [GuiInfo.edit.horizontal(1)+(GuiInfo.edit.horizontal(2)-GuiInfo.edit.horizontal(1))/2.25 verticalStarts(iField)+itemHeight/2 (GuiInfo.edit.horizontal(2)-GuiInfo.edit.horizontal(1))/4 itemHeight-itemHeight/3]; %[GuiInfo.edit.horizontal(1) verticalStarts(iField) GuiInfo.edit.horizontal(2)-GuiInfo.edit.horizontal(1) itemHeight];
            MainFigureOptions.Children.MainPanel.Children.(['edit' fields{iField}]).callback = {@booleanCallback fields{iField}};
            MainFigureOptions.Children.MainPanel.Children.(['edit' fields{iField}]).string = '';
            MainFigureOptions.Children.MainPanel.Children.(['edit' fields{iField}]).backgroundColor = backgroundColor;
            MainFigureOptions.Children.MainPanel.Children.(['edit' fields{iField}]).fontSize = fontSize;

        case 'structure'
            MainFigureOptions.Children.MainPanel.Children.(['edit' fields{iField}]).style = 'pushbutton';
            MainFigureOptions.Children.MainPanel.Children.(['edit' fields{iField}]).units = 'normalized';
            MainFigureOptions.Children.MainPanel.Children.(['edit' fields{iField}]).position = [GuiInfo.edit.horizontal(1) verticalStarts(iField) GuiInfo.edit.horizontal(2)-GuiInfo.edit.horizontal(1) itemHeight]+editOffSet;
            MainFigureOptions.Children.MainPanel.Children.(['edit' fields{iField}]).callback = {@structureCallback fields{iField}};
            MainFigureOptions.Children.MainPanel.Children.(['edit' fields{iField}]).string = 'More Options';
            MainFigureOptions.Children.MainPanel.Children.(['edit' fields{iField}]).fontSize = fontSize;
    end

    MainFigureOptions.Children.MainPanel.Children.(['hline' num2str(iField)]).style = 'frame';
    MainFigureOptions.Children.MainPanel.Children.(['hline' num2str(iField)]).units = 'normalized';
    MainFigureOptions.Children.MainPanel.Children.(['hline' num2str(iField)]).position = [GuiInfo.label.horizontal(1) verticalStarts(iField) GuiInfo.edit.horizontal(2)-GuiInfo.label.horizontal(1) 1];
end

MainFigureOptions.Children.MainPanel.Children.('vline1').style = 'frame';
MainFigureOptions.Children.MainPanel.Children.('vline1').units = 'normalized';
MainFigureOptions.Children.MainPanel.Children.('vline1').position = [GuiInfo.label.horizontal(1) min(verticalStarts) 1 max(verticalStarts)-min(verticalStarts)+itemHeight*3/2];

MainFigureOptions.Children.MainPanel.Children.('vline2').style = 'frame';
MainFigureOptions.Children.MainPanel.Children.('vline2').units = 'normalized';
MainFigureOptions.Children.MainPanel.Children.('vline2').position = [mean([GuiInfo.label.horizontal(2) GuiInfo.value.horizontal(1)]) min(verticalStarts) 1 max(verticalStarts)-min(verticalStarts)+itemHeight*3/2];

MainFigureOptions.Children.MainPanel.Children.('vline3').style = 'frame';
MainFigureOptions.Children.MainPanel.Children.('vline3').units = 'normalized';
MainFigureOptions.Children.MainPanel.Children.('vline3').position = [mean([GuiInfo.value.horizontal(2) GuiInfo.edit.horizontal(1)]) min(verticalStarts) 1 max(verticalStarts)-min(verticalStarts)+itemHeight*3/2];

MainFigureOptions.Children.MainPanel.Children.('vline4').style = 'frame';
MainFigureOptions.Children.MainPanel.Children.('vline4').units = 'normalized';
MainFigureOptions.Children.MainPanel.Children.('vline4').position = [GuiInfo.edit.horizontal(2) min(verticalStarts) 1 max(verticalStarts)-min(verticalStarts)+itemHeight*3/2];

MainFigureOptions.Children.MainPanel.Children.(['hline' num2str(nFields+1)]).style = 'frame';
MainFigureOptions.Children.MainPanel.Children.(['hline' num2str(nFields+1)]).units = 'normalized';
MainFigureOptions.Children.MainPanel.Children.(['hline' num2str(nFields+1)]).position = [GuiInfo.label.horizontal(1) max(verticalStarts)+itemHeight*3/2 GuiInfo.edit.horizontal(2)-GuiInfo.label.horizontal(1) 1];

Handles = prtUtilSuicontrol(MainFigureOptions);

set(Handles.handle,'windowStyle','normal');

% Set the lines which are actually frames to have a width of 1 pixel
for iV = 1:4
    v = getpixelposition(Handles.MainPanel.(['vline' num2str(iV)]));
    setpixelposition(Handles.MainPanel.(['vline' num2str(iV)]),[v(1) v(2) 1 v(4)]);
end

for iField = 1:nFields+1
   v = getpixelposition(Handles.MainPanel.(['hline' num2str(iField)]));
   setpixelposition(Handles.MainPanel.(['hline' num2str(iField)]),[v(1) v(2) v(3) 1]);
end

modifiedProperties = false(nFields,1);
modifiedValues = cell(nFields,1);

updateValueFields;
updateEditFields;

uiwait(Handles.handle)

% Now that OutputStructure is set we need to set the values
modifiedValues = modifiedValues(modifiedProperties);
modifiedNames = guiPropNames(modifiedProperties);

output = obj;
for iProp = 1:length(modifiedNames)
    output.(modifiedNames{iProp}) = OutputStructure.(modifiedNames{iProp});
end

if isstruct(obj)
    creationString = '';
else
    creationString = sprintf('%s(',class(obj));
    for iProp = 1:length(modifiedNames)
        creationString = cat(2,creationString,'''',modifiedNames{iProp},''',',modifiedValues{iProp},',');
    end
    if strcmpi(creationString(end),',');
        creationString = creationString(1:(end-1));
    end
    creationString = cat(2,creationString,')');
end

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    function numericCallback(myHandles,eventData,fieldName) %#ok

        shouldRevert = false;
        newNumber = [];
        try
            eval(sprintf('newNumber = %s;',get(myHandles,'string')))
        catch ME %#ok<NASGU>
            errordlg('This is not valid MATLAB syntax for a numeric value.','Invalid numeric value.','modal')
            shouldRevert = true;
        end

        try
            objTest = obj;
            objTest.(fieldName) = newNumber;
        catch ME
            errordlg(ME.message,'modal')
            shouldRevert = true;
        end

        if shouldRevert
            updateEditFields;
        else

            propInd = find(strcmp(guiPropNames,fieldName),1,'first');
            modifiedProperties(propInd) = true;
            modifiedValues{propInd} = get(myHandles,'string');

            OutputStructure.(fieldName) = newNumber;
            updateValueFields;
            updateEditFields;
        end
    end
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    function charCallback(myHandles,eventData,fieldName) %#ok

        shouldRevert = false;
        newString = [];
        try
            eval(sprintf('newString = ''%s'';',get(myHandles,'string')))
        catch ME %#ok<NASGU>
            errordlg('This is not valid MATLAB syntax for a string value.','Invalid string','modal')
            shouldRevert = true;
        end

        try
            objTest = obj;
            objTest.(fieldName) = newString;
        catch ME
            errordlg(ME.message,'modal')
            shouldRevert = true;
        end

        if shouldRevert
           updateEditFields;
        else
            propInd = find(strcmp(guiPropNames,fieldName),1,'first');
            modifiedProperties(propInd) = true;
            modifiedValues{propInd} = get(myHandles,'string');

            OutputStructure.(fieldName) = newString;
            updateValueFields;
            updateEditFields;
        end
    end
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    function functionCallback(myHandles,eventData,fieldName) %#ok

        shouldRevert = false;

        cString = get(myHandles,'string');
        if length(cString) < 1
            errordlg('This is not valid MATLAB syntax for a function.','Invalid function','modal');
            shouldRevert = true;
        end

        if ~shouldRevert
            try
                eval(sprintf('newFunctionOutput = %s;',cString));

                try
                    objTest = obj;
                    objTest.(fieldName) = newFunctionOutput;
                catch ME
                    errordlg(ME.message,'modal')
                    shouldRevert = true;
                end

            catch ME %#ok<NASGU>
                errordlg('This is not valid MATLAB syntax for a function.','Invalid function','modal')
                shouldRevert = true;
            end
        end

        if shouldRevert
            updateEditFields;
        else
            propInd = find(strcmp(guiPropNames,fieldName),1,'first');
            modifiedProperties(propInd) = true;
            modifiedValues{propInd} = cString;

            OutputStructure.(fieldName) = eval(cString);
            updateValueFields;
            updateEditFields;
        end
    end
    %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

%     %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%     function structureCallback(myHandles,eventData,fieldName) %#ok
%
%         %newMainFigureOptions = rmfield(newMainFigureOptions,'CloseRequestFcn'); % This is really important. We will need the handle to the newly create cancelCallback not this one.
%         %newMainPanelOptions = MainPanelOptions;
%
%         [OutputStructure.(fieldName), subCreationString] = prtUtilObjectGuiSimple(OutputStructure.(fieldName));
%
%         updateValueFields;
%         updateEditFields;
%
%     end
%     %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

    %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    function booleanCallback(myHandles,eventData,fieldName) %#ok

        OutputStructure.(fieldName) = get(myHandles,'value');

        propInd = find(strcmp(guiPropNames,fieldName),1,'first');
        modifiedProperties(propInd) = true;
        if OutputStructure.(fieldName)
            modifiedValues{propInd} = 'true';
        else
            modifiedValues{propInd} = 'false';
        end

        updateValueFields;
        updateEditFields;
    end
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    function defaultCallback(myHandles,eventdata) %#ok

        OutputStructure = DefaultStructure;

        updateValueFields;
        updateEditFields;

    end
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    function cancelCallback(myHandles,eventdata) %#ok

        set(Handles.handle,'visible','off');

        OutputStructure = BaseStructure;

        delete(Handles.handle);
    end
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    function applyCallback(myHandles,eventdata) %#ok
        delete(Handles.handle);
    end
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    function updateValueFields
        for jField = 1:nFields
            switch types{jField}
                case 'numeric'
                    set(Handles.MainPanel.(['value' fields{jField}]),'string',mat2str(OutputStructure.(fields{jField})));
                case 'char'
                    set(Handles.MainPanel.(['value' fields{jField}]),'string',OutputStructure.(fields{jField}));
                case 'function'
                    set(Handles.MainPanel.(['value' fields{jField}]),'string',func2str(OutputStructure.(fields{jField})));
                case 'boolean'
                    trueFalse = {'False','True'};
                    set(Handles.MainPanel.(['value' fields{jField}]),'string',trueFalse{OutputStructure.(fields{jField})+1});
                case 'structure'
                    set(Handles.MainPanel.(['value' fields{jField}]),'string','To view and edit additional parameters use the button to the right.');

            end
        end
    end
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    function updateEditFields
        for jField = 1:nFields
            switch types{jField}
                case 'numeric'
                    set(Handles.MainPanel.(['edit' fields{jField}]),'string',mat2str(OutputStructure.(fields{jField})));
                case 'char'
                    set(Handles.MainPanel.(['edit' fields{jField}]),'string',OutputStructure.(fields{jField}));
                case 'function'
                   set(Handles.MainPanel.(['edit' fields{jField}]),'string',func2str(OutputStructure.(fields{jField})));
                case 'boolean'
                    set(Handles.MainPanel.(['edit' fields{jField}]),'value',OutputStructure.(fields{jField}));
                case 'structure'
                    % We shouldn't have to do anything.
            end
        end
    end
    %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
end


classdef TankToTankConnState < matlab.mixin.SetGet & matlab.mixin.Copyable
    %TankToTankConnState Summary of this class goes here
    %   Detailed explanation goes here

    properties
        conn(1,1) TankToTankConnection
        active(1,1) logical = true;
        flowRate(1,1) double = 0;
    end

    methods
        function obj = TankToTankConnState(conn)
            obj.conn = conn;
        end

        function newT2TState = deepCopy(obj)
            newT2TState = obj.copy();
            newT2TState.conn = obj.conn;
        end
    end
end


% this function detects potential malware in the current folder and subfolders
%
% Author: A. Delorme, Cotober 2013

function detectmalware(currentFolder);

if nargin < 1
    currentFolder = pwd;
end;

folderContent = dir(currentFolder);
folderContent = { folderContent.name };

malwareStrings = { 'eval(' 'evalin(' 'evalc(' 'delete(' 'movefile(' 'rmdir' 'mkdir' 'copyfile' 'system(' '!' };

for iFile = 1:length(folderContent)

    currentFile = folderContent{iFile};
    if length(currentFile) > 2 && strcmpi(currentFile(end-1:end), '.m')

        fid = fopen(fullfile(currentFolder, currentFile), 'r');
        countLine = 0;
        prevstr = '';
        while ~feof(fid)
            str = fgetl(fid);
            countLine = countLine+1;

            if length(str) > 1 && str(1) ~= '%'
                res = cellfun(@(x)~isempty(findstr(x, str)), malwareStrings(1:end-1));
                if str(1) == '!', res(end+1) = 1; end;
                if any(res)
                    pos = find(res); pos = pos(1);
                    disp('************************************')
                    fprintf('Potential malware command detected containing "%s" in\n %s line %d\n', malwareStrings{pos}, fullfile(currentFolder, currentFile), countLine);
                    fprintf('%d: %s\n%d: %s\n%d: %s\n', countLine-1, prevstr, countLine, str, countLine+1, fgetl(fid));
                    countLine = countLine+1;
                end;
            end;

            prevstr = str;
        end;
        fclose(fid);

    elseif exist(currentFile) == 7 && ~strcmpi(currentFile, '..') && ~strcmpi(currentFile, '.')
        detectmalware(fullfile(currentFolder, currentFile));
    end;
end;


function w=getwords(s)
% w=getwords(s)
%
% Returns a cell array with the individual words in the string 's'

s = upper2space(s);
w = strread(s, '%s', 'delimiter', '-_., ');
w = strrep(w, '(', '');
w = strrep(w, ')', '');
w = strrep(w, '''', '');
w = strrep(w, '"', '');
w = strrep(w, ';', '');
w = strrep(w, '&', '');
w = strrep(w, '?', '');
w = strrep(w, '!', '');


%% PRIME_BATCH_ITHACA uses the BATCH command to run the PRIME code on the VT ITHACA cluster.
%
%  Discussion:
%
%    The PRIME code is a function, so first we must write a script
%    called PRIME_SCRIPT that runs the function.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    01 April 2010
%
%  Author:
%
%    John Burkardt
%
  clear

  fprintf ( 1, '\n' );
  fprintf ( 1, 'PRIME_BATCH_ITHACA:\n' );
  fprintf ( 1, '  Run PRIME_SCRIPT on Ithaca.\n' );
%
%  The BATCH command sends the script for execution.
%
  my_job = batch ( 'prime_script', ...
    'Configuration', 'ithaca_2009b', ...
    'CaptureDiary', true, ...
    'FileDependencies', { 'prime_fun' }, ...
    'CurrentDirectory', '/home/burkardt/matlab', ...
    'matlabpool', 4 );
%
%  WAIT pauses the MATLAB session til the job completes.
%
  wait ( my_job );
%
%  DIARY displays any messages printed during execution.
%
  diary ( my_job );
%
%  LOAD makes the script's workspace available.
%
%  total = total number of primes.
%
  load ( my_job );

  fprintf ( 1, '\n' );
  fprintf ( 1, '  Total number of primes = %d\n', total );
%
%  DESTROY cleans up data about the job we no longer need.
%
  destroy ( my_job );

  fprintf ( 1, '\n' );
  fprintf ( 1, 'PRIME_BATCH_ITHACA:\n' );
  fprintf ( 1, '  Normal end of execution.\n' );


function pth = sessionGUI_roiPath(roi);
% return a full path to an ROI file, given the name of an ROI in the
% current ROI list, or the numeric index. If a full path is already
% provided, return it unchanged.
mrGlobals2;

% get the parent directory for ROIs
switch get(GUI.controls.roiType, 'Value')
	case 1, parent = roiDir(INPLANE{1},1); % inplane
	case 2, parent = roiDir(VOLUME{1},0); % volume shared
	case 3, parent = roiDir(VOLUME{1},1); % gray local
	case 4, parent = fullfile(HOMEDIR, 'Volume', 'ROIs');  % volume local
	case 5,  % browse for directory
		parent = get(GUI.controls.roiType, 'String');
		parent = parent{end};
end

% use the roi value and the parent directory to construct a full ROI path.
if ischar(roi) & exist(roi, 'file')
    pth = fullpath(roi);

elseif isnumeric(roi)
    roiNames = get(GUI.controls.roi, 'String');
    pth = fullfile(parent, roiNames{roi(1)});

elseif ischar(roi)
    pth = fullfile(parent, roi);

else
    error('Invalid ROI specification. ')

end

return


function savetSeries(tSeries,vw,scan,slice,nii)
% Save time series to a nifti file
%
%   savetSeries(tSeries,vw,scan,[slice],[nii])
%
% This function should be called everytime you save a tSeries. Makes the
% tSeries directory and scan subdirectory if they don't already exist.
%
% Nifti functionality has been added. In the directory
% '[sessionDir]/[dataTYPE]/TSeries/tSeriesScan[Scan#]Slice[Slice#].nii.gz'
%
% tSeries: matrix of N time samples by M pixels
% vw, scan, & slice: Used only to determine the full path for the tSeries file.
%
% djh, 2/17/2001
mrGlobals;

if notDefined('scan'),  scan  = viewGet(vw, 'curScan'); end
if notDefined('slice'), slice = viewGet(vw, 'curSlice'); end

viewType = viewGet(vw,'View Type');

if strcmp(viewType,'Inplane')

    tseriesdir = viewGet(vw,'tSeriesDir', 1);

    if ~exist(fullfile(tseriesdir),'dir')
        mkdir(tseriesdir);
    end

    pathStr = fullfile(tseriesdir,['tSeriesScan',num2str(scan),'.nii.gz']);

    %Let's also make sure that the dataTYPES are updated properly
    %First, check if this datatype exists
    %Then, check if this scan exists
    %Then, change the path for this scan to the new path

    %This is the same code as in duplicateDataType
    curDt = viewGet(vw,'Cur Dt');
    if curDt > numel(dataTYPES)
        newName = [];
        dlg = 'Please give a new name for the new datatype';
        while isempty(newName)
            newName = inputdlg(dlg,'Name new datatype');
            if iscell(newName) && ~isempty(newName)
                newName = deblank(newName{1}); % remove possible blanks
                if existDataType(newName)
                    dlg = 'What you just input is already in dataTYPES. Try again !!!';
                    newName = []; disp(['Warning: ',dlg]);
                end
            else
                dlg = 'You MUST give a NEW name for the new datatype !!!';
                disp(['Warning: ',dlg]);
            end %if
        end %while
        addDataType(newName);
    end %if

    numScans = dtGet(dataTYPES(curDt),'N Scans');

    if numScans < scan
        for newScan = (numScans+1):(scan-numScans)
             %Copy over the scan information from the previous scan
             vw = initScan(vw,curDt,newScan);
        end %for
    end %if

    %We now have a path to save the nifti to, let's make a nifti!
    if ~exist('nii','var')
        % We have no Nifti, we need to create our own
        % We can take the data from loadtSeries
        [~,nii] = loadtSeries(vw,scan,slice);

        % Now we need to change the data, the dimensions and the filepath
        % to reflect the new data that was passed in the tSeries

        % Let's first reshape the data into the proper size

        sizeDim = viewGet(vw,'Functional Slice Dim');
        totalSize = [size(tSeries,1),sizeDim,size(tSeries,3)];
        keepFrames = zeros(numScans, 2);
        keepFrames(1:numScans,2) = -1;
        newtSeries = reshape(tSeries,totalSize);
        newtSeries = permute(newtSeries, [2 3 4 1]); %Put the time at the end
        %Now let's update the nifti
        dim = size(newtSeries);
        nii = niftiSet(nii,'Dim',dim);
        nii = niftiSet(nii,'Data',newtSeries);

    else %if
        dim = niftiGet(nii, 'dim');
    end

    %Now we need to add another dimension to the pixdim if it only has 3
    if numel(niftiGet(nii,'Pix Dim')) < numel(dim)
        %Add another pixdim
        nii = niftiSet(nii, 'Pix Dim',[niftiGet(nii,'Pix Dim') 1]);
    end

	nii = niftiSet(nii,'File Path',pathStr);

    niftiWrite(nii,pathStr);

    dataTYPES(curDt) = dtSet(dataTYPES(curDt),'Inplane Path',pathStr,scan);
    dataTYPES(curDt) = dtSet(dataTYPES(curDt),'Size',dim(1:2),scan);

    %Add in keepFrames information
    dataTYPES(curDt) = dtSet(dataTYPES(curDt),'Keep Frames',keepFrames,scan);

    verbose = prefsVerboseCheck;
    if verbose > 1		% starting to use graded levels of feedback
        fprintf('Saved time series %s. (%s)\n', pathStr, datestr(now));
    end %if

    %Save the new dataTypes variable back to the overall session.
    saveSession;

else

    tseriesdir = tSeriesDir(vw, 1);
    scandir = ['Scan',num2str(scan)];
    if ~exist(fullfile(tseriesdir,scandir),'dir')
        mkdir(tseriesdir,scandir);
    end
    pathStr = fullfile(tseriesdir,scandir,['tSeries',num2str(slice)]);

    if strcmp(viewType,'Flat')
        % In the flat view, we will be getting multiple slices, so go
        % through each slice and save down the tSeries
        % We may sometimes encounter the case where we have 3 or 4
        % dimensions, and we want to save them all. We need to account for
        % that:

        numEle = numel(size(tSeries));
        numSlices = size(tSeries,numEle);

        if numEle == 4

            for i = 1:numSlices
                pathStr = fullfile(tseriesdir,scandir,['tSeries',num2str(i)]);
                tSeriesTmp = tSeries(:,:,i,:); %The slices will be on the 3rd dimension

                tSeriesTmp = single(tSeriesTmp);

                %disp(['Saving: ',pathStr]);
                save(pathStr,'tSeriesTmp');
            end %for

        elseif numEle ==3

            for i = 1:numSlices
                pathStr = fullfile(tseriesdir,scandir,['tSeries',num2str(i)]);
                tSeriesTmp = tSeries(:,:,i);

                tSeriesTmp = single(tSeriesTmp);

                %disp(['Saving: ',pathStr]);
                save(pathStr,'tSeriesTmp');
            end %for

        else
            %We don't know what to do
            error('Incorrect number of elements in tSeries.');
        end %if

    else
        %This is what happens in the Gray view, since only 1 slice
        tSeries = single(tSeries); %#ok<NASGU>

        %disp(['Saving: ',pathStr]);
        save(pathStr,'tSeries');
    end %if

    verbose = prefsVerboseCheck;
    if verbose > 1		% starting to use graded levels of feedback
        fprintf('Saved time series %s. (%s)\n', pathStr, datestr(now));
    end %if

end %if

return