function varargout = SMSeriesGUI(varargin)
gui_Singleton = 1;
gui_State = struct('gui_Name',       mfilename, ...
                   'gui_Singleton',  gui_Singleton, ...
                   'gui_OpeningFcn', @SMSeriesGUI_OpeningFcn, ...
                   'gui_OutputFcn',  @SMSeriesGUI_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


function DeactiveCtr(handle)

handle.btnInitializing.Enable = 'off';
handle.popChannelList.Enable = 'off';
handle.edIntTime.Enable = 'off';
handle.edAvgTime.Enable = 'off';
handle.radInternalTrg.Enable = 'off';
handle.radExternalTrg.Enable = 'off';
handle.radFreeRunPre.Enable = 'off';
handle.radFreeRunNext.Enable = 'off';
handle.radSWTrigger.Enable = 'off';
handle.radFalling.Enable = 'off';
handle.radRising.Enable = 'off';
handle.btnPixel.Enable = 'off';
handle.btnFactory.Enable = 'off';
handle.btnPixel.Enable = 'off';
handle.btnUserCal.Enable = 'off';
handle.btnGetData.Enable = 'off';
handle.btnSave.Enable = 'off';


function SMSeriesGUI_OpeningFcn(hObject, eventdata, handles, varargin)

global SPFunc
global axXlabel

SPFunc = SPlibrary();
SPFunc.LoadLibrary() %This function is load a sp dll from MATLAB

btnCheckConnection_Callback(hObject, eventdata, handles);

axXlabel = 'Pixel';

xlabel(axXlabel);
ylabel('Intensity(a.u)');

handles.output = hObject;
guidata(hObject, handles);


function varargout = SMSeriesGUI_OutputFcn(~, ~, handles) 

varargout{1} = handles.output;


function btnCheckConnection_Callback(~, ~, handles)

global SPFunc

DeactiveCtr(handles)

% 0 = SP_ORDER_BY_USBPORTNUM
% The "SP_ORDER_BY_USBPORTNUM" in the spTestAllChannels argument means
% that the DLL will determine the connection information by the order of the USB port connection.
SPFunc.sTotChnl = SPFunc.TestAllChannels(0);
if(SPFunc.sTotChnl > 0)    
    handles.btnInitializing.Enable = 'on';
    set(handles.edChkConnection,'String',strcat('The total USB ports connected are ',num2str(SPFunc.sTotChnl)))
else
    set(handles.edChkConnection,'String','There is no USB connection.')
end


function btnInitializing_Callback(~, ~, handles)

global SPFunc

global WavelengthTable

strList = strings(1,SPFunc.sTotChnl);

%spFunction spSetupAllChannels() : setup channel
sRtn = SPFunc.SetupAllChannels();
if (sRtn < 0)
    set(handles.edInitialzing,'String',strcat('There is an error on testing.'));
    DeactiveCtr(handles)
    return
end

%Connected Channel interface check  
for n = 1:SPFunc.sTotChnl    
    
    %spFunction spGetModel() : get model type of connected device    
    SPFunc.sDevType(n) = SPFunc.GetModel(n-1);    
    if (SPFunc.sDevType(n) < 0)
        set(handles.edInitialzing,'String',strcat('There is an error on get the model ch# ',num2str(n-1)))
        DeactiveCtr(handles)
        return
    end
    
    if (SPFunc.sDevType(n) == 0)          % SM2XX
        SPFunc.sTotPixelNum(n) = 2080;
        SPFunc.sRealPixelNum(n) = 2048;   % The first 32 pixels are optical blank pixels. 
        SPFunc.sStartOpticalBlank(n) = 32;% The real data is 2048 for Sony ILX 511.
        SPFunc.strModel(n) = 'SM2XX';
        
    elseif (SPFunc.sDevType(n) == 1)      % SM440
        SPFunc.sTotPixelNum(n) = 3680;
        SPFunc.sRealPixelNum(n) = 3648;   % The first 32 pixels are optical blank pixels.
        SPFunc.sStartOpticalBlank(n) = 32;% The real data is 3648 for TOSHIBA TCD1304AP.
        SPFunc.strModel(n) = 'SM440';
    
    elseif (SPFunc.sDevType(n) == 2)      % SM303
        SPFunc.sTotPixelNum(n) = 1024;   
        SPFunc.sRealPixelNum(n) = 1024;   %There is no optical blank
        SPFunc.sStartOpticalBlank(n) = 0;
        SPFunc.strModel(n) = 'SM303';
  
    elseif (SPFunc.sDevType(n) == 3)      % SM304
        SPFunc.sTotPixelNum(n) = 512;     
        SPFunc.sRealPixelNum(n) = 512;    % There is no optical blank
        SPFunc.sStartOpticalBlank(n) = 0; % The real data is 512 for Hamamatsu G9212 InGaAs array detector.
        SPFunc.strModel(n) = 'SM304';
   
    elseif (SPFunc.sDevType(n) == 4)      % SM642
        SPFunc.sTotPixelNum(n) = 2080;
        SPFunc.sRealPixelNum(n) = 2048;   % The first 10 pixels are optical blank pixels. 
        SPFunc.sStartOpticalBlank(n) = 10;% The real data is 2048 HAMAMATSU S10420.
        SPFunc.strModel(n) = 'SM642';
  
    elseif (SPFunc.sDevType(n) == 6)      % SM303-S10141
        SPFunc.sTotPixelNum(n) = 2080;    % The first 10 pixels are optical blank pixels. 
        SPFunc.sRealPixelNum(n) = 2048;   % The real data is 2048 for Hamamatsu S10141 CCD.
        SPFunc.sStartOpticalBlank(n) = 10;% The last 22 pixels are dummy
        SPFunc.strModel(n) = 'SM303-S10141';
    
    elseif (SPFunc.sDevType(n) == 7)      % SM445
        SPFunc.sTotPixelNum(n) = 3680;
        SPFunc.sRealPixelNum(n) = 3648;   % The last 22 pixels are dummy
        SPFunc.sStartOpticalBlank(n) = 32;% The real data is 3648 for TOSHIBA TCD1304AP.
        SPFunc.strModel(n) = 'SM445';
    end
    
    WavelengthTable = 1:SPFunc.sRealPixelNum(n);
    %set(handles.axDataGraph,);
    SPFunc.sAvgTime(n) = 1;
    SPFunc.lIntTime(n) = 25;
    SPFunc.sTrgMode(n) = 11;
    SPFunc.sIntMode(n) = 1;
    SPFunc.sExtMode(n) = 0;     
    
    %spFunction spInitGivenChannel() : initialized the setting variables in given channel    
    sRtn = SPFunc.InitGivenChannel(SPFunc.sDevType(n),n-1);
    if (sRtn < 0)
        set(handles.edInitialzing,'String',strcat('There is an error on initializing the ch#. ',num2str(n-1)))
        DeactiveCtr(handles)
        return
    end
       
    % spFunction spSetTrgEx() : set the trigger mode
    % sTrgMode -> 11: internal trigger mode, 12 : external trigger mode
    sRtn = SPFunc.SetTrgEx(SPFunc.sTrgMode(n),n-1);
    if (sRtn < 0)
        set(handles.edInitialzing,'String',strcat('There is an error on set trigger mode the ch#. ',num2str(n-1)))
        DeactiveCtr(handles)
        return
    end
    
    if( SPFunc.sDevType(n) == 1 || SPFunc.sDevType(n) == 7 )        
        % spFunction spDbSetIntEx() : set the integration time(SM440,SM445)
        sRtn = SPFunc.SetDblIntEx(SPFunc.lIntTime(n),n-1);
    else
        % spFunction spSetIntEx() : set the integration time
        sRtn = SPFunc.SetIntEx(SPFunc.lIntTime(n),n-1);
    end    
    if (sRtn < 0)
        set(handles.edInitialzing,'String',strcat('There is an error on set Integration time the ch#. ',num2str(n-1)))
        DeactiveCtr(handles)
        return
    end
    
    temp = strcat('ch#',num2str(n-1));
    strList(n) = strcat(temp,strcat(' : ',SPFunc.strModel(n)));     
end
handles.popChannelList.String = strList;

handles.edInitialzing.String = 'All connected channels work OK.';
handles.edIntTime.String = num2str(SPFunc.lIntTime(1));
handles.edAvgTime.String = num2str(SPFunc.sAvgTime(1));
handles.radInternalTrg.Value = 1;
handles.radFreeRunPre.Value = 1;
handles.popChannelList.Enable ='on';
handles.edIntTime.Enable = 'on';
handles.edAvgTime.Enable = 'on';
handles.radInternalTrg.Enable = 'on';
handles.radExternalTrg.Enable = 'on';
handles.radFreeRunPre.Enable = 'on';
if not(SPFunc.sDevType(1) == 0 || SPFunc.sDevType(1) == 1 || SPFunc.sDevType(1) == 7)
    handles.radFreeRunNext.Enable = 'on';
end
if not(SPFunc.sDevType(1) == 1 || SPFunc.sDevType(1) == 7)
    handles.radSWTrigger.Enable = 'on';
end
handles.btnFactory.Enable = 'on';
handles.btnPixel.Enable = 'on';
handles.btnUserCal.Enable = 'on';
handles.btnGetData.Enable = 'on';
handles.btnSave.Enable = 'on';


function popChannelList_Callback(~, ~, handles)

global SPFunc

SelCh = handles.popChannelList.Value;

handles.edIntTime.String = num2str(SPFunc.lIntTime(SelCh));
handles.edAvgTime.String = num2str(SPFunc.sAvgTime(SelCh));

if(SPFunc.sTrgMode(SelCh) == 11)
    handles.radFreeRunPre.Enable = 'on';
    if not(SPFunc.sDevType(SelCh) == 0 || SPFunc.sDevType(SelCh) == 1 || SPFunc.sDevType(SelCh) == 7)
        handles.radFreeRunNext.Enable = 'on';
    else
        handles.radFreeRunNext.Enable = 'off';
    end
    
    if not(SPFunc.sDevType(SelCh) == 0 || SPFunc.sDevType(SelCh) == 1 || SPFunc.sDevType(SelCh) == 7)
        handles.radSWTrigger.Enable = 'on';
    else
        handles.radSWTrigger.Enable = 'off';
    end
    handles.radFalling.Enable = 'off';
    handles.radRising.Enable = 'off';
    
    handles.radInternalTrg.Value = 1;    
    
    if(SPFunc.sIntMode(SelCh) == 0)
        handles.radSWTrigger.Value = 1;
    elseif(SPFunc.sIntMode(SelCh) == 1)
        handles.radFreeRunPre.Value = 1;
    elseif(SPFunc.sIntMode(SelCh) == 2)
        handles.radFreeRunNext.Value = 1;
    end
else    
    handles.radFreeRunPre.Enable = 'off';
    handles.radFreeRunNext.Enable = 'off';
    handles.radSWTrigger.Enable = 'off';
    handles.radFalling.Enable = 'on';
    if not(SPFunc.sDevType(SelCh) == 0 || SPFunc.sDevType(SelCh) == 1 || SPFunc.sDevType(SelCh) == 7)
        handles.radRising.Enable = 'on';
    else
        handles.radRising.Enable = 'off';
    end    
    
    handles.radExternalTrg.Value = 1;
    
    if(SPFunc.sExtMode(SelCh) == 0)
         handles.radFalling.Value = 1;
    elseif(SPFunc.sExtMode(SelCh) == 1)
        handles.radRising.Value = 1;
    end    
end


function edIntTime_Callback(~, ~, handles)
global SPFunc

SelCh = handles.popChannelList.Value;

SPFunc.lIntTime(SelCh) = str2num(handles.edIntTime.String);

if( SPFunc.sDevType(SelCh) == 1 || SPFunc.sDevType(SelCh) == 7 )
    % spFunction spSetIntEx() : set the integration time
    sRtn = SPFunc.SetIntEx(SPFunc.lIntTime(SelCh),SelCh-1);
else
    % spFunction spDbSetIntEx() : set the integration time(SM440,SM445)
    sRtn = SPFunc.SetDblIntEx(SPFunc.lIntTime(SelCh),SelCh-1);
end    
if (sRtn < 0)
    set(handles.edInitialzing,'String',strcat('There is an error on set Integration time the ch#. ',num2str(SelCh-1)))
    DeactiveCtr(handles)
    return
end


function edAvgTime_Callback(~, ~, handles)

global SPFunc

SelCh = handles.popChannelList.Value;

SPFunc.sAvgTime(SelCh) = str2num(handles.edAvgTime.String);


function radInternalTrg_Callback(~, ~, handles)

global SPFunc

SelCh = handles.popChannelList.Value;

if not(SPFunc.sTrgMode(SelCh) == 11)
    handles.radFreeRunPre.Enable = 'on';    
    if not(SPFunc.sDevType(SelCh) == 0 || SPFunc.sDevType(SelCh) == 1 || SPFunc.sDevType(SelCh) == 7)
        handles.radFreeRunNext.Enable = 'on';
    else
        handles.radFreeRunNext.Enable = 'off';
    end
    if not(SPFunc.sDevType(SelCh) == 0 || SPFunc.sDevType(SelCh) == 1 || SPFunc.sDevType(SelCh) == 7)
        handles.radSWTrigger.Enable = 'on';
    else
        handles.radSWTrigger.Enable = 'off';
    end
    handles.radFalling.Enable = 'off';
    handles.radRising.Enable = 'off';

    handles.radFreeRunPre.Value = 1; 

    SPFunc.sTrgMode(SelCh) = 11;

    % spFunction spSetTrgEx() : set the trigger mode
    % sTrgMode -> 11: internal trigger mode, 12 : external trigger mode
    sRtn = SPFunc.SetTrgEx(SPFunc.sTrgMode(SelCh),SelCh-1);
    if (sRtn < 0)
        set(handles.edInitialzing,'String',strcat('There is an error on set trigger mode the ch#. ',num2str(SelCh-1)))
        DeactiveCtr(handles)
        return
    end
end


function radExternalTrg_Callback(~, ~, handles)

global SPFunc

SelCh = handles.popChannelList.Value;

if not(SPFunc.sTrgMode(SelCh) == 12)
    handles.radFreeRunPre.Enable = 'off';
    handles.radFreeRunNext.Enable = 'off';    
    handles.radSWTrigger.Enable = 'off';
    handles.radFalling.Enable = 'on';
    if not(SPFunc.sDevType(SelCh) == 0 || SPFunc.sDevType(SelCh) == 1 || SPFunc.sDevType(SelCh) == 7)
        handles.radRising.Enable = 'on';
    else
        handles.radRising.Enable = 'off';
    end
    
    handles.radFalling.Value = 1; 

    SPFunc.sTrgMode(SelCh) = 12;
    
    % spFunction spSetTrgEx() : set the trigger mode
    % sTrgMode -> 11: internal trigger mode, 12 : external trigger mode
    sRtn = SPFunc.SetTrgEx(SPFunc.sTrgMode(SelCh),SelCh-1);
    if (sRtn < 0)
        set(handles.edInitialzing,'String',strcat('There is an error on set trigger mode the ch#. ',num2str(SelCh-1)))
        DeactiveCtr(handles)
        return
    end
end


function radFreeRunPre_Callback(~, ~, handles)

global SPFunc

SelCh = handles.popChannelList.Value;

if not(SPFunc.sIntMode(SelCh) == 1)
    
    SPFunc.sIntMode(SelCh) = 1;
    
    % spFunction spSetIntMode() : set the internal mode
    % sIntMode -> 0: software trigger, 1 : free run previous, 2 : free run next    
    sRtn = SPFunc.SetIntMode(SPFunc.sIntMode(SelCh),SPFunc.lIntTime(SelCh),SelCh-1);
    if (sRtn < 0)
        set(handles.edInitialzing,'String',strcat('There is an error on internal mode the ch#. ',num2str(SelCh-1)))
        DeactiveCtr(handles)
        return
    end
end


function radFreeRunNext_Callback(~, ~, handles)

global SPFunc

SelCh = handles.popChannelList.Value;

if not(SPFunc.sIntMode(SelCh) == 2)
    
    SPFunc.sIntMode(SelCh) = 2;
    
    % spFunction spSetIntMode() : set the internal mode
    % sIntMode -> 0: software trigger, 1 : free run previous, 2 : free run next    
    sRtn = SPFunc.SetIntMode(SPFunc.sIntMode(SelCh),SPFunc.lIntTime(SelCh),SelCh-1);
    if (sRtn < 0)
        set(handles.edInitialzing,'String',strcat('There is an error on internal mode the ch#. ',num2str(SelCh-1)))
        DeactiveCtr(handles)
        return
    end
end


function radSWTrigger_Callback(~, ~, handles)

global SPFunc

SelCh = handles.popChannelList.Value;

if not(SPFunc.sIntMode(SelCh) == 0)
    
    SPFunc.sIntMode(SelCh) = 0;
    
    % spFunction spSetIntMode() : set the internal mode
    % sIntMode -> 0: software trigger, 1 : free run previous, 2 : free run next    
    sRtn = SPFunc.SetIntMode(SPFunc.sIntMode(SelCh),SPFunc.lIntTime(SelCh),SelCh-1);
    if (sRtn < 0)
        set(handles.edInitialzing,'String',strcat('There is an error on internal mode the ch#. ',num2str(SelCh-1)))
        DeactiveCtr(handles)
        return
    end
end


function radFalling_Callback(~, ~, handles)
global SPFunc

SelCh = handles.popChannelList.Value;

if not(SPFunc.sExtMode(SelCh) == 0)
    
    SPFunc.sExtMode(SelCh) = 0;
    
    % spFunction spSetExtEdgeMode() : set the external mode
    % sExtMode -> 0: falling edge, 1 : rising edge
    sRtn = SPFunc.SetExtEdgeMode(SPFunc.sExtMode(SelCh),SelCh-1);
    if (sRtn < 0)
        set(handles.edInitialzing,'String',strcat('There is an error on external mode the ch#. ',num2str(SelCh-1)))
        DeactiveCtr(handles)
        return
    end
end


function radRising_Callback(~, ~, handles)

global SPFunc

SelCh = handles.popChannelList.Value;

if not(SPFunc.sExtMode(SelCh) == 1)
    
    SPFunc.sExtMode(SelCh) = 1;
    
    % spFunction spSetExtEdgeMode() : set the external mode
    % sExtMode -> 0: falling edge, 1 : rising edge   
    sRtn = SPFunc.SetExtEdgeMode(SPFunc.sExtMode(SelCh),SelCh-1);
    if (sRtn < 0)
        set(handles.edInitialzing,'String',strcat('There is an error on external mode the ch#. ',num2str(SelCh-1)))
        DeactiveCtr(handles)
        return
    end
end

function btnPixel_Callback(~, ~, handles)

global SPFunc
global WavelengthTable
global Data
global axXlabel

SelCh = handles.popChannelList.Value;

WavelengthTable = 1:SPFunc.sRealPixelNum(SelCh);

plot(handles.axDataGraph,WavelengthTable,Data,'r');

set(handles.axDataGraph,'XLim',[WavelengthTable(1) WavelengthTable(SPFunc.sRealPixelNum(SelCh))],'xgrid','on','ygrid','on');
axXlabel = 'Pixle';
xlabel(axXlabel);
ylabel('Intensity(a.u)');

function btnFactory_Callback(~, ~, handles)

global SPFunc
global WavelengthTable
global Data
global axXlabel

SelCh = handles.popChannelList.Value;

plWLTable = libpointer('doublePtr',zeros(1,SPFunc.sRealPixelNum(SelCh)));

% spFunction spGetWLTable() : get WLTable in EEPROM
sRtn = SPFunc.GetWLTable(plWLTable,SelCh-1);    
if (sRtn < 0)
    set(handles.edInitialzing,'String',strcat('There is an error on get WLTable the ch#. ',num2str(SelCh-1)))
    DeactiveCtr(handles)
    return
end

temp = get(plWLTable);

WavelengthTable = temp.Value;

plot(handles.axDataGraph,WavelengthTable,Data,'r');

set(handles.axDataGraph,'XLim',[WavelengthTable(1) WavelengthTable(SPFunc.sRealPixelNum(SelCh))],'xgrid','on','ygrid','on');
axXlabel = 'Wavelength(nm)';
xlabel(axXlabel);
ylabel('Intensity(a.u)');

function btnUserCal_Callback(~, ~, handles)

% Spectrometer wavelength vs. pixel number Calibration Data set
% This set was given as an example.
% The customer has to use the proper calibration data set per each channel
global SPFunc
global WavelengthTable
global Data
global axXlabel

SelCh = handles.popChannelList.Value;

if(SPFunc.sDevType(SelCh) == 0)
    filename = 'UserCal\CalData_SM2XX.txt';
elseif(SPFunc.sDevType(SelCh) == 1 || SPFunc.sDevType(SelCh) == 7)
    filename = 'UserCal\CalData_SM4XX.txt';
elseif(SPFunc.sDevType(SelCh) == 2)
    filename = 'UserCal\CalData_SM303.txt';
elseif(SPFunc.sDevType(SelCh) == 3)
    filename = 'UserCal\CalData_SM304.txt';
elseif(SPFunc.sDevType(SelCh) == 4)
    filename = 'UserCal\CalData_SM642.txt';
elseif(SPFunc.sDevType(SelCh) == 6)    
    filename = 'UserCal\CalData_SM303-S10141.txt';
end

fileID = fopen(filename);

filetext = fgetl(fileID);
tempstr = strsplit(filetext);
ipoint = str2num(cell2mat(tempstr(2)));

filetext = fgetl(fileID);
filetext = fgetl(fileID);

dWavelength = zeros(1,ipoint);
dPixelNo = zeros(1,ipoint);

for n = 1:ipoint
    filetext = fgetl(fileID);
    tempstr = strsplit(filetext);
    
    dWavelength(n) = str2num(cell2mat(tempstr(1)));
    dPixelNo(n) = str2num(cell2mat(tempstr(2)));
end

pdcoefs = libpointer('doublePtr',zeros(1,5)); 
pdWL = libpointer('doublePtr',dWavelength);
pdPx = libpointer('doublePtr',dPixelNo);

% spFunction spPolyFit() : polynomial fitting
SPFunc.PolyFit(pdPx,pdWL,ipoint,pdcoefs,3);

pdCalWL = libpointer('doublePtr',zeros(1,1));

for n = 1:SPFunc.sRealPixelNum(SelCh)
    % spFunction spPolyFit() : polynomial calculation
    SPFunc.PolyCalc(pdcoefs,3,n,pdCalWL);
    WavelengthTable(n) = pdCalWL.Value(1);
end

plot(handles.axDataGraph,WavelengthTable,Data,'r');

set(handles.axDataGraph,'XLim',[WavelengthTable(1) WavelengthTable(SPFunc.sRealPixelNum(SelCh))],'xgrid','on','ygrid','on');
axXlabel = 'Wavelength(nm)';
xlabel(axXlabel);
ylabel('Intensity(a.u)');


function btnGetData_Callback(~, ~, handles)

global SPFunc
global WavelengthTable
global axXlabel
global Data

SelCh = handles.popChannelList.Value;

plData = libpointer('int32Ptr',zeros(1,SPFunc.sTotPixelNum(SelCh)));
lData = zeros(1,SPFunc.sTotPixelNum(SelCh));

for n = 1:SPFunc.sAvgTime(SelCh)
    if(SPFunc.sTrgMode(SelCh) == 11)
        % spFunction spReadDataEx() : read data from the CCD
        sRtn = SPFunc.ReadDataEx(plData,SelCh-1);    
    elseif(SPFunc.sTrgMode(SelCh) == 12)        
        while 1            
            % spFunction spReadDataEx() : read data from the CCD
            sRtn = SPFunc.ReadDataEx(plData,SelCh-1);
            if not( sRtn ==-99)
                break;
            end
        end
    end
    if (sRtn < 0)
        set(handles.edInitialzing,'String',strcat('There is an error on get CCD data the ch#. ',num2str(SelCh-1)))
        DeactiveCtr(handles)
        return
    end
    for m = 1:SPFunc.sTotPixelNum(SelCh)
        lData(m) = lData(m) + plData.Value(m)/SPFunc.sAvgTime(SelCh);
    end
end

if not( SPFunc.sStartOpticalBlank(SelCh) == 0)
    Data = lData(SPFunc.sStartOpticalBlank(SelCh):SPFunc.sRealPixelNum(SelCh) + SPFunc.sStartOpticalBlank(SelCh)-1);
else
    Data = lData(1:SPFunc.sRealPixelNum(SelCh));
end

plot(handles.axDataGraph,WavelengthTable,Data,'r');

set(handles.axDataGraph,'XLim',[WavelengthTable(1) WavelengthTable(SPFunc.sRealPixelNum(SelCh))],'xgrid','on','ygrid','on');
xlabel(axXlabel);
ylabel('Intensity(a.u)');


function btnSave_Callback(~, ~, handles)

global SPFunc
global WavelengthTable
global Data

SelCh = handles.popChannelList.Value;

save_filename = strcat(SPFunc.strModel(SelCh),'-Data.txt');
OUT=fopen(save_filename,'wt');
fprintf(OUT, 'Pixel\tWavelength(nm)\tIntensity\n');

for n = 1:SPFunc.sRealPixelNum(SelCh)
    fprintf(OUT, '%d\t%0.1f\t%d\n',n,WavelengthTable(n),Data(n));
end

fclose(OUT);


function figure1_CloseRequestFcn(hObject, eventdata, handles)

global SPFunc

SPFunc.unLoadLibrary();

delete(hObject);
