function [Channel,landmark]=elpos2bs(fnamein,fnameout,type)
%ELPOS2BS - this function converts electrode position files into BrainStorm Channel format
% function [Channel,landmark]=elpos2bs(fnamein,fnameout,type)
% fnamein = input file name
% fnameout = output filename for BrainStorm format. If fnameout=[], no file
% is saved
% type = input data format 
%      = 'elp' simple BESA ASCII format
%      = 'dat' NeuroScan for BESA electrode format
%      = 'res' NeuroScan for Curry format
%      = 'sfp' ZEBRIS ASCII format
% Channel = returns brainstorm Channel structure
%           Channel.Loc = elctrode position. default = [0;0;0];
%           Channel.Orient = Channel orientiation. Does not apply for electrodes. default =[1;0;0];
%           Channel.Weight = Channel weighting. default=1;
%           Channel.Type = Channel type. default='EEG'
%           Channel.Comment =Channel comment. default='';
%           Channel.Name = Channel name. default='';
%           Channel.System = Channel system. default='';
% landmark = the brainstorm landmark structure
%            landmark.Loc(1:3,1:n) = landmark locations 
%            landmark.Name={1:n} list of landmark names

%<autobegin> ---------------------- 12-Oct-2004 11:38:10 -----------------------
% --------- Automatically Generated Comments Block Using AUTO_COMMENTS ---------
%
% CATEGORY: Unknown Category
%
% Subfunctions in this file, in order of occurrence in file:
%   [ix]=scan_reference(Channel) % search for possible reference channel
%   [Channel,landmark]=elp2bsint(fnamein,unitCorrection)
%   [Channel,landmark]=dat2bsint(fnamein,unitCorrection)
%   [Channel,landmark]=res2bsint(fnamein,unitCorrection)
%   [Channel,landmark]=sfp2bsint(fnamein,unitCorrection)
%
% At Check-in: $Author: Mosher $  $Revision: 6 $  $Date: 10/12/04 10:19a $
%
% This software is part of BrainStorm Toolbox Version 2.0 (Alpha) 11-Oct-2004
% 
% Principal Investigators and Developers:
% ** Richard M. Leahy, PhD, Signal & Image Processing Institute,
%    University of Southern California, Los Angeles, CA
% ** John C. Mosher, PhD, Biophysics Group,
%    Los Alamos National Laboratory, Los Alamos, NM
% ** Sylvain Baillet, PhD, Cognitive Neuroscience & Brain Imaging Laboratory,
%    CNRS, Hopital de la Salpetriere, Paris, France
% 
% See BrainStorm website at http://neuroimage.usc.edu for further information.
% 
% Copyright (c) 2004 BrainStorm by the University of Southern California
% This software distributed  under the terms of the GNU General Public License
% as published by the Free Software Foundation. Further details on the GPL
% license can be found at http://www.gnu.org/copyleft/gpl.html .
% 
% FOR RESEARCH PURPOSES ONLY. THE SOFTWARE IS PROVIDED "AS IS," AND THE
% UNIVERSITY OF SOUTHERN CALIFORNIA AND ITS COLLABORATORS DO NOT MAKE ANY
% WARRANTY, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO WARRANTIES OF
% MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, NOR DO THEY ASSUME ANY
% LIABILITY OR RESPONSIBILITY FOR THE USE OF THIS SOFTWARE.
%<autoend> ------------------------ 12-Oct-2004 11:38:10 -----------------------



% ----------------------------- Script History ---------------------------------
% (c) 2004 Felix Darvas, Ph.D. , SIPI University of Southern California
% JCM 12-Oct-2004 Header comments
% ----------------------------- Script History ---------------------------------


% setting defaults


%ask for units
str = {'meters' 'centimeters' 'millimeters'};
[unit,v] = listdlg('PromptString','Select units of channel file','selectionmode','single','Liststring',str);
if(unit == 1) %meters
    unitCorrection = 1;
end
if(unit == 2) %centimeters
    unitCorrection = 100;
end
if(unit == 3) %millimeters
    unitCorrection = 1000;
end



Channel=struct('Loc',zeros(3,1),'Orient',[1;0;0],'Weight',1,'Type','EEG','Comment','','Name','','System','');


if(strcmp(type,'elp'))
    [Channel,landmark]=elp2bsint(fnamein,unitCorrection); % getting channel info in ELP format. It is still not clear, were we place the reference information!
end

if(strcmp(type,'dat'))
    [Channel,landmark]=dat2bsint(fnamein,unitCorrection); % getting channel info in DAT format. It is still not clear, were we place the reference information!
end

if(strcmp(type,'res'))
     [Channel,landmark]=res2bsint(fnamein,unitCorrection); % getting channel info in DAT format. It is still not clear, were we place the reference information!
end
if(strcmp(type,'sfp'))
     [Channel,landmark]=sfp2bsint(fnamein,unitCorrection); % getting channel info in SFP format. It is still not clear, were we place the reference information!
end

fusion=[Channel landmark];
ixlandmark=zeros(1,length(fusion));
ixlandmark(length(Channel)+1:end)=1;
ixlm=find(ixlandmark>0);
ps=sprintf('found %i predefined landmarks',length(landmark));
[Selection,ok] = listdlg('ListString',{fusion.Name},'InitialValue',ixlm,'PromptString',ps,'Name','Landmark definition');
landmark=[];
for i=1:length(Selection)
    landmark.Loc(1:3,i)=fusion(Selection(i)).Loc(1:3,1);
    landmark.Name{i}=fusion(Selection(i)).Name;
end
fusion(Selection)=[];
Channel=fusion;
ix=scan_reference(Channel); % search for a possible reference electrode;

if(ix>0)
    % there is a reference electrode candidate
    Channel(ix).Type='EEG REF';
%     for i=1:length(Channel)
%         Channel(i).Loc(:,2)=Channel(ix).Loc(:,1); % follow BS convention and set 2nd position in channel to reference position.
%     end
else
    % there is no apparent reference. Assume average reference.
    for i=1:length(Channel)
        Channel(i).Comment='AVERAGE REF';
        %Channel(i).Loc(:,2)=Channel(i).Loc(:,1); % dont know what to do with average ref? Assume every channel is reference.
    end
end
if(~isempty(fnameout))
    save(fnameout,'Channel');
end
return

function [ix]=scan_reference(Channel) % search for possible reference channel
ix=-1;
ref_found=0;
% look for names like 'ref' first
for i=1:length(Channel)
    label=Channel(i).Name;
    label=lower(label);
    if(findstr(label,'ref'))
        if(ref_found==0)
            ix=i;
            ref_found==1;
        else
            label2=Channel(ix).Name;
            outs=sprintf('there are ambiguous electrode labels in %s and %s! Will keep %s as reference.',label,label2,label);
            error(outs);
        end
    end
end
% check for 'cz'
if(ref_found==0)
    for i=1:length(Channel)
        label=Channel(i).Name;
        label=lower(label);
        if(strcmp(label,'cz'))
            if(ref_found==0)
                ix=i;
                ref_found==1;
            else
                label2=Channel(ix).Name;
                outs=sprintf('there are ambiguous electrode labels in %s and %s! Will keep %s as reference.',label,label2,label);
                error(outs);
            end
        end
    end
end




% importing 'elp' format
function [Channel,landmark]=elp2bsint(fnamein,unitCorrection)
Channel=struct('Loc',zeros(3,1),'Orient',[1;0;0],'Weight',1,'Type','EEG','Comment','','Name','','System','');
%landmark=struct('Loc',zeros(3,1),'Orient',[0;0;0],'Weight',1,'Type','EEG','Comment','','Name','','System','')
landmark=[];
fpin=fopen(fnamein);
if(fpin>0)
    k=1;
    while(~feof(fpin))
        label{k}=fscanf(fpin,'%s',1);
        pos{k}=fscanf(fpin,'%e',[1 3]);
        k=k+1;
    end
    fclose(fpin);
else
    msg=sprintf('File %s does not exist',fnamein);
    error(msg);
    Channel=[];
    return 
end
Channel=struct('Loc',zeros(3,1),'Orient',[0;0;0],'Weight',1,'Type','EEG','Comment','converted from ELP','Name','EEG 01','System','Neuroscan SynAmp');
for i=1:k-2;
    Channel(i).Loc(:,1)=pos{i}'/unitCorrection;
    Channel(i).Orient=[0;0;0];
    Channel(i).Weight=1;
    Channel(i).Type='EEG';
    Channel(i).Comment='';
    Channel(i).Name=label{i};
    Channel(i).System='Neuroscan SynAmp';
end





% importing 'dat' format
function [Channel,landmark]=dat2bsint(fnamein,unitCorrection)
Channel=struct('Loc',zeros(3,1),'Orient',[0;0;0],'Weight',1,'Type','EEG','Comment','','Name','','System','');
%landmark=struct('Loc',zeros(3,1),'Orient',[0;0;0],'Weight',1,'Type','EEG','Comment','','Name','','System','')
landmark=[];
fpin=fopen(fnamein);
if(fpin>0)
    k=1;
    while(~feof(fpin))
        label{k}=fscanf(fpin,'%s',1);
       hi=fscanf(fpin,'%i',1);
       if(~isempty(hi))
            typ(k)=hi;
        end
        pos{k}=fscanf(fpin,'%e',[1 3]);
        k=k+1;
    end
    fclose(fpin);
else
    msg=sprintf('File %s does not exist',fnamein);
    error(msg);
    Channel=[];
    return 
end
ix=find(typ==69 | typ==88);
Channel=struct('Loc',zeros(3,1),'Orient',[0;0;0],'Weight',1,'Type','EEG','Comment','converted from ELP','Name','EEG 01','System','Neuroscan SynAmp');
for i=1:length(ix);
    Channel(i).Loc(:,1)=pos{ix(i)}'/unitCorrection;
    Channel(i).Orient=[0;0;0];
    Channel(i).Weight=1;
    Channel(i).Type='EEG';
    Channel(i).Comment='';
    Channel(i).Name=label{ix(i)};
    Channel(i).System='Neuroscan SynAmp';
end
ix=find(typ>75 & typ<83);
for i=1:length(ix);
    landmark(i).Loc(:,1)=pos{ix(i)}'/unitCorrection;
    landmark(i).Orient=[0;0;0];
    landmark(i).Weight=1;
    landmark(i).Type='LANDMARK';
    landmark(i).Comment='';
    landmark(i).Name=label{ix(i)};
    landmark(i).System='Neuroscan SynAmp';
end






% importing 'res' format
function [Channel,landmark]=res2bsint(fnamein,unitCorrection)
Channel=struct('Loc',zeros(3,1),'Orient',[0;0;0],'Weight',1,'Type','EEG','Comment','','Name','','System','');
%landmark=struct('Loc',zeros(3,1),'Orient',[0;0;0],'Weight',1,'Type','EEG','Comment','','Name','','System','')
landmark=[];
fpin=fopen(fnamein);
if(fpin>0)
    k=1;
    while(~feof(fpin))
        hi=fscanf(fpin,'%i',1);
       if(~isempty(hi))
            typ(k)=hi;
        end
        pos{k}=fscanf(fpin,'%e',[1 3]);
        dummy=fscanf(fpin,'%i',1);
        label{k}=fscanf(fpin,'%s',1);
        k=k+1;
    end
    fclose(fpin);
else
    msg=sprintf('File %s does not exist',fnamein);
    error(msg);
    Channel=[];
    return 
end
Channel=struct('Loc',zeros(3,1),'Orient',[0;0;0],'Weight',1,'Type','EEG','Comment','','Name','','System','Neuroscan SynAmp');
ix=find(typ==0);
for i=1:length(ix);
    Channel(i).Loc(:,1)=pos{ix(i)}'/unitCorrection;
    Channel(i).Orient=[0;0;0];
    Channel(i).Weight=1;
    Channel(i).Type='EEG';
    Channel(i).Comment='';
    Channel(i).Name=label{ix(i)};
    Channel(i).System='Neuroscan SynAmp';
end
ix=find(typ<0);
for i=1:length(ix);
    landmark(i).Loc(:,1)=pos{ix(i)}'/unitCorrection;
    landmark(i).Orient=[0;0;0];
    landmark(i).Weight=1;
    landmark(i).Type='LANDMARK';
    landmark(i).Comment='';
    landmark(i).Name=label{ix(i)};
    landmark(i).System='Neuroscan SynAmp';
end





function [Channel,landmark]=sfp2bsint(fnamein,unitCorrection)
Channel=struct('Loc',zeros(3,1),'Orient',[0;0;0],'Weight',1,'Type','EEG','Comment','','Name','','System','');
%landmark=struct('Loc',zeros(3,1),'Orient',[0;0;0],'Weight',1,'Type','EEG','Comment','','Name','','System','')
landmark=[];
fpin=fopen(fnamein);
if(fpin>0)
    k=1;
    while(~feof(fpin))
        label{k}=fscanf(fpin,'%s',1);
        pos{k}=fscanf(fpin,'%e',[1 3]);
        k=k+1;
    end
    fclose(fpin);
else
    msg=sprintf('File %s does not exist',fnamein);
    error(msg);
    Channel=[];
    return 
end
Channel=struct('Loc',zeros(3,1),'Orient',[0;0;0],'Weight',1,'Type','EEG','Comment','','Name','','System','Neuroscan SynAmp');
ix=1:k-2;
for i=1:length(ix);
    Channel(i).Loc(:,1)=pos{ix(i)}'/unitCorrection;
    Channel(i).Orient=[0;0;0];
    Channel(i).Weight=1;
    Channel(i).Type='EEG';
    Channel(i).Comment='';
    Channel(i).Name=label{ix(i)};
    Channel(i).System='SFP';
end
