function [Suffix, Description] = Fabsurf(FileName, Path, Type,h)

%%% Outputs Suffix and Description for file selection querry
if nargin == 0
    Suffix ='*0.spc';
    Description ='B&H SPC files recorded with FabSurf (*0.spc)';
    return;
end

global UserValues TcspcData FileInfo
FileInfo.FileType = 'FabsurfSPC';
%%% Reads info file generated by Fabsurf
FileInfo.Fabsurf=FabsurfInfo(fullfile(Path,FileName{1}));
%%% General FileInfo
FileInfo.NumberOfFiles=numel(FileName);
FileInfo.Type=Type;
FileInfo.MI_Bins=4096;
FileInfo.ImageTimes= 0;
FileInfo.TACRange = 40E-9;
FileInfo.FileName=FileName;
FileInfo.Path=Path;
%%% Initializes microtime and macotime arrays
if strcmp(UserValues.Detector.Auto,'off')
    TcspcData.MT=cell(max(UserValues.Detector.Det),max(UserValues.Detector.Rout));
    TcspcData.MI=cell(max(UserValues.Detector.Det),max(UserValues.Detector.Rout));
else
    TcspcData.MT=cell(10,10); %%% default to 10 channels
    TcspcData.MI=cell(10,10); %%% default to 10 channels
end


Totaltime=0;
%%% Reads all selected files
for i=1:numel(FileName)
    %%% Calculates ImageTimes in clock ticks for concaternating
    %%% files
    Info=FabsurfInfo(fullfile(Path,FileName{i}),1);
    if isempty(Info)
        continue; %%% Skip file
    end
    FileInfo.SyncPeriod=FileInfo.Fabsurf.RepRate/1000;
    FileInfo.Lines=FileInfo.Fabsurf.Imagelines;
    FileInfo.Pixels=FileInfo.Fabsurf.Imagelines;
    FileInfo.ClockPeriod=FileInfo.SyncPeriod;
    FileInfo.ScanFreq=FileInfo.Fabsurf.ScanFreqCorrected;
    ImageTimes=round(Info.Imagetime/1000/FileInfo.SyncPeriod);
    %%% Checks, which cards to load
    if strcmp(UserValues.Detector.Auto,'off')
        card = unique(UserValues.Detector.Det);
    else
        card = 1:10; %%% consider up to 10 cards
    end
    %%% check for disabled detectors
    for j = card
        if sum(UserValues.Detector.Det==j) > 0
            if all(strcmp(UserValues.Detector.enabled(UserValues.Detector.Det==j),'off'))
                card(card==j) = [];
            end
        end
    end
    %%% Checks, which and how many card exist for each file
    for j=card;
        if ~exist(fullfile(Path,[FileName{i}(1:end-5) num2str(j-1) '.spc']),'file')
            card(card==j)=[];
        end
    end
    
    %%% Reads data for each tcspc card
    for j = card
        %%% Update Progress
        Progress((i-1)/numel(FileName)+(j-1)/numel(card)/numel(FileName),h.Progress.Axes, h.Progress.Text,['Loading File ' num2str((i-1)*numel(card)+j) ' of ' num2str(numel(FileName)*numel(card))]);
        
        %%% Reads Macrotime (MT, as double) and Microtime (MI, as uint 16) from .spc file
        [MT, MI, ~] = Read_BH(fullfile(Path, [FileName{i}(1:end-5) num2str(j-1) '.spc']),Inf, 'SPC-140/150/130');
        %%% Finds, which routing bits to use
        if strcmp(UserValues.Detector.Auto,'off')
            Rout = unique(UserValues.Detector.Rout(UserValues.Detector.Det==j));
        else
            Rout = 1:10; %%% consider up to 10 routing channels
        end
        Rout(Rout>numel(MI)) = [];
        
        %%% check for disabled routing bits
        for r = Rout
            if sum((UserValues.Detector.Det==j)&(UserValues.Detector.Rout == r)) > 0
                if all(strcmp(UserValues.Detector.enabled((UserValues.Detector.Det==j)&(UserValues.Detector.Rout == r)),'off'))
                    Rout(Rout==r) = [];
                end
            end
        end
        
        %%% Concatenates data to previous files and adds ImageTimes
        %%% to consecutive files
        if any(~cellfun(@isempty,MI(:)))
            skip = false;
            for k = Rout
                %%% Removes photons detected after "official"
                %%% end of file are discarded
                MI{k}(MT{k}>ImageTimes)=[];
                MT{k}(MT{k}>ImageTimes)=[];
                TcspcData.MT{j,k}=[TcspcData.MT{j,k}; Totaltime + MT{k}];   MT{k}=[];
                TcspcData.MI{j,k}=[TcspcData.MI{j,k}; MI{k}];   MI{k}=[];
            end
        else %%% file was empty!
            skip = true;
        end
        if skip
            continue;
        end
        %%% Determines last photon for each file
        for k=find(~cellfun(@isempty,TcspcData.MT(j,:)));
            FileInfo.LastPhoton{j,k}(i)=numel(TcspcData.MT{j,k});
        end
        
        %                 %%% Determines, if linesync was used
        %                 if isempty(Linetimes) && ~isempty(Header.PixelMarker)
        %                     Linetimes=[0 Header.PixelMarker];
        %                 elseif isempty(Linetimes) && ~isempty(Header.LineMarker)
        %                     Linetimes=[0 Header.LineMarker];
        %                 elseif isempty(Linetimes) && ~isempty(Header.FrameMarker)
        %                     Linetimes=[0 Header.FrameMarker];
        %                 end
    end
    %%% Creates linebreak entries
    %             if isempty(Linetimes)
    %                 FileInfo.LineTimes(:,i)=linspace(0,FileInfo.ImageTimes/FileInfo.SyncPeriod,FileInfo.Lines+1)+Totaltime;
    %             elseif numel(Linetimes)==FileInfo.Lines+1
    %                 FileInfo.LineTimes(:,i)=Linetimes+Totaltime;
    %             elseif numel(Linetimes)<FileInfo.Lines+1
    %                 %%% I was to lazy to program this case out yet
    %             end
    %%% Calculates total time to get one trace from several
    %%% files
    Totaltime=Totaltime + ImageTimes;
    FileInfo.ImageTimes(end+1) = Totaltime*FileInfo.ClockPeriod;
    
end
FileInfo.MeasurementTime = Totaltime*FileInfo.ClockPeriod;
for i=1:(numel(FileInfo.ImageTimes)-1)
    FileInfo.LineTimes(i,:) = linspace(FileInfo.ImageTimes(i),FileInfo.ImageTimes(i+1),FileInfo.Lines+1);
end



function Header = FabsurfInfo(FullFileName,ToRead)
% SCANNING AND GENERAL PARAMETERS:   
%   1   Time per Image [ms]            
%   2   Image Size:                     
%   3   Lines per Image
%   4   MT cal, ms
%   5   #Frames use
%   6   Objective Magnification
%       
% SCAN & TRACK PARAMETERS:  
%   7   Measurement Time
%   8   Threshold Right
%   9   Threshold Left
%   10  # of particles
%       
% CIRCULAR SCAN PARAMETERS:  
%   11  Scan Frequency
%   12  Scan Frequency Corrected
%   13  Scan Radius
%   14  Scanning Mode
%       
% POSITION PARAMETERS:   
%   15  OffSetX
%   16  OffSetY
%   17  LStep_X
%   18  LStep_Y
%   19  Cursor 1 X Position
%   20  Cursor 1 Y Position
%   21  Cursor 2 X Position
%   22  Cursor 2 Y Position
%   23  Current Z Plane
%   24  Current Piezo Z-position
%   25  Current Z-Position             
%      
%   26  Additional Information

%%% Parameters to be looked for are defined here
for i=1
Params{1}='Time per Image';
Params{2}='Image Size';
Params{3}='Lines per Image';
Params{4}='MT cal, ms';
Params{5}='#Frames use';
Params{6}='Objective Magnification';
Params{7}='Measurement Time';
Params{8}='Threshold Right';
Params{9}='Threshold Left';
Params{10}='# of particles';
Params{11}='Scan Frequency:';
Params{12}='Scan Frequency Corrected';
Params{13}='Scan Radius';
Params{14}='Scanning Mode';
Params{15}='OffSetX';
Params{16}='OffSetY';
Params{17}='LStep_X';
Params{18}='LStep_Y';
Params{19}='Cursor 1 X Position';
Params{20}='Cursor 1 Y Position';
Params{21}='Cursor 2 X Position';
Params{22}='Cursor 2 Y Position';
Params{23}='Current Z Plane';
Params{24}='Current Piezo Z-position';
Params{25}='Current Z-Position';
Params{26}='Additional Information';
end
%%% Header fieldnames are defined here
for i=1
Outputname{1}='Imagetime';
Outputname{2}='Imagesize';
Outputname{3}='Imagelines';
Outputname{4}='RepRate';
Outputname{5}='FramesUsed';
Outputname{6}='Objective';
Outputname{7}='MTime';
Outputname{8}='THR';
Outputname{9}='THL';
Outputname{10}='NoP';
Outputname{11}='ScanFreq';
Outputname{12}='ScanFreqCorrected';
Outputname{13}='ScanRadius';
Outputname{14}='ScanMode';
Outputname{15}='OffSetX';
Outputname{16}='OffSetY';
Outputname{17}='LStepX';
Outputname{18}='LStepY';
Outputname{19}='C1X';
Outputname{20}='C1Y';
Outputname{21}='C2X';
Outputname{22}='C2Y';
Outputname{23}='ZPlane';
Outputname{24}='PiezoPos';
Outputname{25}='ZPos';
Outputname{26}='Additional';
    
end
%%% Replacement parameters, if file is not found/complete are defined here
for i=1
% Replace{1}=UserValues.InfoParams.Imagetime;
% Replace{2}=UserValues.InfoParams.Imagesize;
% Replace{3}=UserValues.InfoParams.Lines;
% Replace{4}=1000/UserValues.InfoParams.MicroTime;
% Replace{5}=UserValues.InfoParams.FramesUsed;
% Replace{6}=60;
% Replace{7}=UserValues.InfoParams.TrackTime;
% Replace{8}=-1;
% Replace{9}=-1;
% Replace{10}=-1;
% Replace{11}=UserValues.InfoParams.ScanFreq;
% Replace{12}=UserValues.InfoParams.ScanFreqCor;
% Replace{13}=1;
% Replace{14}='Circle';
% Replace{15}=0;
% Replace{16}=0;
% Replace{17}=0;
% Replace{18}=0;
% Replace{19}=0;
% Replace{20}=0;
% Replace{21}=0;
% Replace{22}=0;
% Replace{23}=1;
% Replace{24}=0;
% Replace{25}=0;
% Replace{26}='';    
end
%%% Read all if not defined differntly
if  ~exist('ToRead','var')
    ToRead=1:26;
end

%%% Checks if and which infofile belongs to filename
fid(1) = fopen([FullFileName(1:end-9) '_info' FullFileName(end-8:end-6) '.txt']);
fid(2) = fopen([FullFileName(1:end-9) '_MeasureCursor_info' FullFileName(end-8:end-6) '.txt']);
fid(3) = fopen([FullFileName(1:end-9) '_Scanning_info' FullFileName(end-8:end-6) '.txt']);
fid(4) = fopen([FullFileName(1:end-9) '_Track_info' FullFileName(end-8:end-6) '.txt']);
fid(5) = fopen([FullFileName(1:end-9) '_MeasureCursorSeries_info' FullFileName(end-8:end-6) '.txt']);
fid(6) = fopen([FullFileName(1:end-10) '_info' FullFileName(end-9:end-6) '.txt']);
fid(7) = fopen([FullFileName(1:end-10) '_MeasureCursor_info' FullFileName(end-9:end-6) '.txt']);
fid(8) = fopen([FullFileName(1:end-10) '_Scanning_info' FullFileName(end-9:end-6) '.txt']);
fid(9) = fopen([FullFileName(1:end-10) '_Track_info' FullFileName(end-9:end-6) '.txt']);
fid(10) = fopen([FullFileName(1:end-10) '_MeasureCursorSeries_info' FullFileName(end-9:end-6) '.txt']);
fid(11) = fopen([FullFileName(1:end-10) '_ZScan_info' FullFileName(end-9:end-6) '.txt']);
fid(12) = fopen([FullFileName(1:end-10) '_ZTrack_info' FullFileName(end-9:end-6) '.txt']);
fid(13) = fopen([FullFileName(1:end-10) '_MFD_info' FullFileName(end-9:end-6) '.txt']);
%%% HydraHarp
fid(14) = fopen([FullFileName(1:end-8) '_info' FullFileName(end-7:end-4) '.txt']);
fid(15) = fopen([FullFileName(1:end-8) '_MeasureCursor_info' FullFileName(end-7:end-4) '.txt']);
fid(16) = fopen([FullFileName(1:end-8) '_Scanning_info' FullFileName(end-7:end-4) '.txt']);
fid(17) = fopen([FullFileName(1:end-8) '_Track_info' FullFileName(end-7:end-4) '.txt']);
fid(18) = fopen([FullFileName(1:end-8) '_MeasureCursorSeries_info' FullFileName(end-7:end-4) '.txt']);
fid(19) = fopen([FullFileName(1:end-8) '_ZScan_info' FullFileName(end-7:end-4) '.txt']);
fid(20) = fopen([FullFileName(1:end-8) '_ZTrack_info' FullFileName(end-7:end-4) '.txt']);
fid(21) = fopen([FullFileName(1:end-8) '_MFD_info' FullFileName(end-7:end-4) '.txt']);

i=1;
FID=-1;
while i<22
    if fid(i)~=-1; 
        FID=fid(i); 
        break;
    end;
    i=i+1;
end

%%% Looks for Parameters defined in Params and saves string in Output
Output=cell(26,1);
if FID ~= -1
    T=textscan(FID,'%s', 'delimiter', '\n','whitespace', '');
    T=T{1};
    for i=ToRead;
        if any(ToRead==i)
            j=1;
            while j<numel(T)
                if ~isempty(strfind(T{j},Params{i}))
                    Output{i} = T{j}(strfind(T{j},':')+1:end);
                    j=numel(T);
                end
                j=j+1;
            end
        end
    end 
    %%% Writes value of Output into Header fieldnames defined by Outputname
    Header=struct;
    for i=[1:13 15:25]
        if strfind(Output{i},',')
            Output{i} = strrep(Output{i},',','.');
        end
        
        if ~isempty(Output{i})
            eval(['Header.' Outputname{i} '= str2double(Output{' num2str(i) '});']);
        else
            eval(['Header.' Outputname{i} '= [];']);
            %eval(['Header.' Outputname{i} '= str2double(Replace{' num2str(i) '});']);
        end
        
    end
    
    %%% Writes string of Output into Header fieldnames defined by Outputname
    for i=[14 26]
        if ~isempty(Output{i})
            eval(['Header.' Outputname{i} '= Output{' num2str(i) '};']);
        else
            eval(['Header.' Outputname{i} '= [];']);
            %         eval(['Header.' Outputname{i} '= Replace{' num2str(i) '};']);
        end
    end
    try
        fclose('all');
    end
else 
    Header=[];
    disp('ERROR: Could not find info txt file');
end


