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

% Last Modified by GUIDE v2.5 03-Jul-2013 13:32:42

% Begin initialization code - DO NOT EDIT
gui_Singleton = 1;
gui_State = struct('gui_Name',       mfilename, ...
                   'gui_Singleton',  gui_Singleton, ...
                   'gui_OpeningFcn', @fluidicsprogram_OpeningFcn, ...
                   'gui_OutputFcn',  @fluidicsprogram_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 fluidicsprogram is made visible.
function fluidicsprogram_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 fluidicsprogram (see VARARGIN)

% Choose default command line output for fluidicsprogram
handles.output = hObject;
handles.resetfcn = @resetgui;

% Update handles structure
guidata(hObject, handles);
prgmgr = varargin{1};
set(handles.box, 'UserData', prgmgr);
prgm = prgmgr.currentprograms(1);
s = getprogramstrings(prgm);
set(handles.steplist, 'String', s);
%Here we set the currently viewed data from the current step
setguivalues(handles);

% Load in programs from the first program function.
% strings = getprogramstrings(varargin{1}(1));
% set(hObject.steplist, 'String', strings);

% UIWAIT makes fluidicsprogram wait for user response (see UIRESUME)
% uiwait(handles.box);


% --- Outputs from this function are returned to the command line.
function varargout = fluidicsprogram_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 resetgui(handles)
set(handles.steplist, 'Value', 1);
set(handles.program, 'Value', 1);
setstepliststrings(handles);
setguivalues(handles);

function setstepliststrings(handles)
x = get(handles.box, 'UserData');
program = get(handles.program, 'Value');
strings = getprogramstrings(x.currentprograms(program));
set(handles.steplist, 'String', strings);

function updatecurrentstepstring(handles)
updatestepstring(handles, get(handles.steplist, 'Value'));

function updatestepstring(handles, section)
str = getstringfromfluidstepvalue(get(handles.fluidtypeselector, 'Value'));
strings = get(handles.steplist, 'String');
strings{section} = str;
set(handles.steplist, 'String', strings);


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


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

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

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



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


% --- Executes on button press in savebutton.
function savebutton_Callback(~, ~, handles)
% hObject    handle to savebutton (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)
updatecurrentstate(handles);
% write all current items to the system.
% save all current items to the flash memory
obj = get(handles.box, 'UserData');
obj.savesequences();
    

function setguivalues(handles)
prgmmgr = get(handles.box, 'UserData');
sequence = get(handles.program, 'Value');
phase = get(handles.steplist, 'Value');
fluidstep = prgmmgr.currentprograms(sequence).getstep(phase);
setvaluesfromdata(handles, sequence, phase, fluidstep);

function setvaluesfromdata(handles, sequence, phase, fluidstep)

set(handles.program, 'Value', sequence);
set(handles.steplist, 'Value', phase);

set(handles.pumpspeedselector, 'String', num2str(fluidstep.pumpspeed));
set(handles.durationselector, 'String', num2str(fluidstep.duration));

switch fluidstep.av
    case 'AV_VAC'
        set(handles.avacgroup, 'SelectedObject', handles.vacuumbutton);
    case 'AV_AUTO'
        set(handles.avacgroup, 'SelectedObject', handles.autobutton);
    case 'AV_AIR'
        set(handles.avacgroup, 'SelectedObject', handles.airbutton);
    case 'AV_BOTH'
        set(handles.avacgroup, 'SelectedObject', handles.avbothbutton);
    case 'AV_NONE'
        set(handles.avacgroup, 'SelectedObject', handles.avnonebutton);
    otherwise
        set(handles.avacgroup, 'SelectedObject', handles.avnonebutton);
end

switch fluidstep.name
    case 'flow'
        set(handles.fluidtypeselector, 'Value', 1);
    case 'flush'
        set(handles.fluidtypeselector, 'Value', 2);
    case 'flsh'
        set(handles.fluidtypeselector, 'Value', 2);
    case 'collect'
        set(handles.fluidtypeselector, 'Value', 3);
    case 'coll'
        set(handles.fluidtypeselector, 'Value', 3);
    case 'base'
        set(handles.fluidtypeselector, 'Value', 4);
    case 'amplify'
        set(handles.fluidtypeselector, 'Value', 5);
    case 'regenerate'
        set(handles.fluidtypeselector, 'Value', 6);
    case 'regn'
        set(handles.fluidtypeselector, 'Value', 6);
    case 'stop'
        set(handles.fluidtypeselector, 'Value', 7);
    case 'eval'
        set(handles.fluidtypeselector, 'Value', 8);
    otherwise
        set(handles.fluidtypeselector, 'Value', 1);
end

function name = getstringfromfluidstepvalue(value)
switch value
    case 1
        name = 'Flow';
    case 2
        name = 'Flush';
    case 3
        name = 'Inject';
    case 4
        name = 'Baseline';
    case 5
        name = 'Amplify';
    case 6
        name = 'Regenerate';
    case 7
        name = 'Stop';
    case 8
        name = 'Evaluate';
    otherwise
        name = 'Stop';
end

function name = getnamefromfluidstepvalue(value)
switch value
    case 1
        name = 'flow';
    case 2
        name = 'flush';
    case 3
        name = 'coll';
    case 4
        name = 'base';
    case 5
        name = 'amplify';
    case 6
        name = 'regenerate';
    case 7
        name = 'stop';
    case 8
        name = 'eval';
    otherwise
        name = 'stop';
end

function strings = getprogramstrings(program)
strings = cell(1, 15);
for i = 1:15
    switch program.getstep(i).name
        case 'flow'
            strings{i} = 'Flow';
        case 'flsh'
            strings{i} = 'Flush';
        case 'flush'
            strings{i} = 'Flush';
        case 'coll'
            strings{i} = 'Inject';
        case 'collect'
            strings{i} = 'Inject';
        case 'base'
            strings{i} = 'Baseline';
        case 'amplify'
            strings{i} = 'Amplify';
        case 'regen'
            strings{i} = 'Regenerate'; 
        case 'regn'
            strings{i} = 'Regenerate'; 
        case 'regenerate'
            strings{i} = 'Regenerate';
        case 'stop'
            strings{i} = 'Stop';
        case 'eval'
            strings{i} = 'Evaluate';
        otherwise
            disp(['Unfamiliar step name: ' program.getstep(i).name]);
            strings{i} = '???';
    end
end

function updatecurrentstate(handles)
phase = get(handles.steplist, 'Value');
updatecurrentstatewithphase(handles, phase)

function updatecurrentstatewithsequence(handles, sequence)
phase = get(handles.steplist, 'Value');
updatecurrentstatewithphaseandsequence(handles, phase, sequence);

function updatecurrentstatewithphase(handles, phase)
sequence = get(handles.program, 'Value');
updatecurrentstatewithphaseandsequence(handles, phase, sequence);

function updatecurrentstatewithphaseandsequence(handles, phase, sequence)

name = getnamefromfluidstepvalue(get(handles.fluidtypeselector, 'Value'));

duration = str2double(get(handles.durationselector, 'String'));
if isempty(duration) || (duration > 600 || duration < 0)
    duration = 10;
end
pumpspeed = str2double(get(handles.pumpspeedselector, 'String'));
if isempty(pumpspeed) || (pumpspeed > 255 || pumpspeed < 0)
    pumpspeed = 0;
end

switch get(handles.avacgroup, 'SelectedObject')
    case handles.vacuumbutton
        avac = 'AV_VAC';
    case handles.autobutton
        avac = 'AV_AUTO';
    case handles.airbutton
        avac = 'AV_AIR';
    case handles.avbothbutton
        avac = 'AV_BOTH';
    case handles.avnonebutton
        avac = 'AV_NONE';
    otherwise
        avac = 'AV_NONE';
end

pmanager = get(handles.box, 'UserData');
pmanager.updateprogram(sequence, phase, fluidstep(name, duration, pumpspeed, avac));


% --- Executes when user attempts to close box.
function box_CloseRequestFcn(hObject, eventdata, handles)
% hObject    handle to box (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)

% Hint: delete(hObject) closes the figure
set(hObject, 'Visible', 'off');


% --- Executes during object creation, after setting all properties.
function steplist_CreateFcn(hObject, eventdata, handles)
% hObject    handle to steplist (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 program_CreateFcn(hObject, eventdata, handles)
% hObject    handle to program (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    empty - handles not created until after all CreateFcns called

% Hint: popupmenu 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 fluidtypeselector_CreateFcn(hObject, eventdata, handles)
% hObject    handle to fluidtypeselector (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    empty - handles not created until after all CreateFcns called

% Hint: popupmenu 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 durationselector_CreateFcn(hObject, eventdata, handles)
% hObject    handle to durationselector (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 pumpspeedselector_CreateFcn(hObject, eventdata, handles)
% hObject    handle to pumpspeedselector (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 loadbutton.
function loadbutton_Callback(hObject, eventdata, handles)
% hObject    handle to loadbutton (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)
x = get(handles.box, 'UserData');
x.loadsequences();


% --- Executes when selected object is changed in avacgroup.
function avacgroup_SelectionChangeFcn(hObject, eventdata, handles)
% hObject    handle to the selected object in avacgroup 
% eventdata  structure with the following fields (see UIBUTTONGROUP)
%	EventName: string 'SelectionChanged' (read only)
%	OldValue: handle of the previously selected object or empty if none was selected
%	NewValue: handle of the currently selected object
% handles    structure with handles and user data (see GUIDATA)
updatecurrentstate(handles);
