function obj = importFile(obj, filePath, dataCol, headerFlag, delimiter)
%% importFile - overwrite data with tabular data from data file (using importDataTable method)
%
% Usage:
%   As class static method:
%     obj = MDD.ImportFile(filePath) % uppercase method
%     obj = MDD.ImportFile(filePath, dataCol, headerFlag, delimiter) % uppercase method
% 
%   As object method:
%     obj = MDD();
%     obj = obj.importFile(filePath) % lowercase method
%     obj = obj.importFile(filePath, dataCol, headerFlag, delimiter) % lowercase method
%
% Inputs:
%   filePath: path to file
%       Supported filetypes:
%           xls, xlsx, csv, tsv, txt, mat (containing 1 numeric mat variable)
%               Note: xls and xlsx cannot have columns with mixtures of numerics
%                     and strings, except for first row. however, txt and csv
%                     files can.
%
% Inputs (optional):
%   dataCol: col number or header name of column with linear data. the rest of
%            the columns will be treated as axes. Default is col 1.
%   headerFlag: logical value of whether 1st row is header of axis names. the
%               name for dataCol will be ignored. it is only necesary to
%               explicitly set this to true if the type of data (numeric vs. string)
%               of the first row is the same as the second row and the first row
%               should be treated as a header.
%   delimiter: specify if using a delimiter other than space(' '), comma(','), 
%              or tab('\t'). see strsplit documentation for delimiter specification.
%
% Author: Erik Roberts

% Dev notes:
%   Possible types of fileInput from plaintext ascii files:
%   1) struct if numeric with headers
%   2) mat is numeric without headers
%   3) cell array of strings for each row if nonNumeric outside header

%   Possible types of fileInput from xlsx files:
%   1) struct if numeric with headers
%   2) mat is numeric without headers
%   3) struct if nonNumeric outside header
%       a) data - contains numeric data with nans for string entries.
%       b) textdata - contains cell strings of nonnumeric data for all columns.
%                     numeric entries will be empty strings.

% TODO:
%   Add excel file support for mixed columns of strings and numerics
%   Add more error handling

% Input default values
if nargin < 4 || isempty(headerFlag)
    headerFlag = -1; % default: ambiguous about headers
    headerArg = nan;
else
    if headerFlag
        headerArg = 1;
    else
        headerArg = 0;
    end
end

% get file extension
[~,~,ext] = fileparts(filePath);
switch lower(ext) % lowercase
    case {'.csv', '.tsv', '.txt'}
        fid = fopen(filePath);
        i=1;
        while 1
            fileInput{i,1} = fgetl(fid);
            if ~ischar(fileInput{i})
                fileInput(i) = [];
                break
            end
            i = i+1;
        end
        fclose(fid)
        clear fid
    case '.mat'
        % Use importdata to load data
        fileInput = importdata(filePath, nan, headerArg);
    otherwise
        % Use importdata to load data
        fileInput = importdata(filePath, nan, headerArg);
end

if ~iscell(fileInput)
    if isstruct(fileInput)
        allNumericData = fileInput.data;
        textData = fileInput.textdata;
        if isfield(fileInput, 'colheaders')
            colheaders = fileInput.colheaders;
            if headerFlag ~= 0
                axNames = colheaders;
            else
                colheaders = [];
                
                %Fill in rest of textData with empty cells
                if size(textData, 1) < size(allNumericData,1)+1
                    newCell = cell( size(allNumericData,1)+1, size(textData,2)); % make new cell of correct size for textData
                    newCell(1:size(textData,1), :) = textData; % add textData to newCell
                    textData = newCell; % switch textData with newCell
                    clear newCell
                end
            end
            if isequal(colheaders, textData)
                textData = []; % no additional text data
            end
        end
    else % numeric array
        allNumericData = fileInput;
        
        if headerFlag == 1
            axNames = allNumericData(1,:);
            allNumericData = allNumericData(2:end,:);
        end
    end
    
    % TODO: handle csv/xlsx with nonnumeric data
    
    % If axNames not already defined, and header not forced off
    if ~exist('axNames', 'var') && headerFlag ~= 0 % not headerFlag==0 which would force no header
        
        % Check if obvious header exists or forced to get header
        if (exist('textData','var') && size(allNumericData,1) < size(textData,1)) ... % 1st row all string and rest is numeric data?
                || headerFlag==1 ... % force header
                || (isstruct(fileInput) && ~isfield(fileInput, 'colheaders')) ...
                
            axNames = textData(1,:);
            textData = textData(2:end,:);
        end
    end
    
    if exist('textData', 'var') && ~isempty(textData)
        % There is non-header textData, meaning some string data
        
        % Remove nan cols from allNumericData which represent string data
        allNumericData = allNumericData(:, all(~isnan(allNumericData)));
        
        % Find cols of numerics
        numericCols = all(cellfun(@isempty,textData));
        
        % Combine allNumericData with textData
        allData = textData;
        allData(:, numericCols) = num2cell(allNumericData);
    else
        allData = allNumericData;
    end
else
    % implicity choose delimiter if not explicitly given as argument
    if ~exist('delimiter', 'var') || isempty(delimiter)
        [~,~,ext] = fileparts(filePath);
        switch lower(ext) % lowercase
            case '.csv'
                delimiter = ',';
            case '.tsv'
                delimiter = '\t';
            otherwise % likely txt file with unknown delimiter
                delimiter = {',', '\t'};
        end
    end
    
    allData = {};
    nRows = size(fileInput, 1);
    for i = 1:nRows
        allData(i,:) = strsplit(fileInput{i}, delimiter);
    end
    
    % Check if used correct delimiter, or if need to try using ' ' delimiter
    if isequal(fileInput, allData) && all(~isempty(strfind(fileInput, ' ')))
        allData = {};
        delimiter = ' '; % use space delimiter (works with arbitrary number of spaces)
        for i = 1:nRows
            allData(i,:) = strsplit(fileInput{i}, delimiter);
        end
    end
    
    % Check if first row is header (all non-numeric strings and second row has some numeric strings)
    if (all(~isnan(str2double(allData(1,:)))) && ~all(~isnan(str2double(allData(2,:)))) && headerFlag ~= 0) || headerFlag == 1
        axNames = allData(1,:);
        allData = allData(2:end,:);
    end
    
    % Convert string cols to numeric when possible
    numericCols = all(~isnan(str2double(allData)));
    allData(:, numericCols) = num2cell(str2double(allData(:, numericCols)));
end

% Get linearData col
if ~isempty(dataCol)
    if ischar(dataCol)
        dataCol = strcmp(dataCol, axNames); % convert from string to logical array
    elseif isscalar(dataCol)
        dataColInd = false(1, size(allData, 2)); % make logical index array
        dataColInd(dataCol) = true;
    end
else
    dataColInd = false(1, size(allData, 2)); % make logical index array
    dataColInd(1) = true; % assume data in 1st col
end

% Remove data from axis values
linearData = allData(:, dataColInd);
axisVals = allData(:, ~dataColInd);
axisValsCells = cell(1, size(axisVals,2));
for j = 1:size(axisVals,2)
    axisValsCells{j} = axisVals(:,j);
end

%% import data
obj = obj.importDataTable(linearData, axisValsCells);

%% add axis names
if exist('axNames','var')
    axNames = axNames(~dataColInd);
    obj = obj.importAxisNames(axNames);
end


end