function list = makelist(varargin)

% MAKELIST - generate simulations list
%
% list = makelist(inputFileName, detId);
%   Generate list from file inputFileName line-by-line
% list = makelist(nSim, inputFileName, detId);
%   Generate list from nSim random draws on the lines of file inputFileName
% list = makelist(nSim, simId, ampl, startSamp, internal, external, detId);
%   Generate list with user specified variables; internal and external can 
%   also be set to 'RANDOM' or 'OPTIMAL'
%
% inputFileName string with name of input file.  Each line of the file
%               contains the following (in this order):
%               [simId ampl startSamp1 startSamp2 int1 int2 ext1 ext2 ext3]
% nSim          positive integer indicating how many simulations to generate
% simId         signal type
% ampl          signal amplitude
%               When varargin=6, ampl can be a vector of length 1, 2 or 3
%               *When length(ampl)=1, the amplitude is fixed
%               *When length(ampl)=2, the amplitude is randomly chosen
%               between ampl(1) and ampl(2) in a logarithmic distribution.  
%               N.B. ampl(1)=ampl(2) is equivilent to entering a fixed 
%               amplitude
%               *When length(ampl)=3, the amplitdue is randomly chosen from
%               the discrete linear range ampl(1):ampl(2):ampl(3)
% startSamp     2 component vector defining range of allowed start times in
%               samples since the beginning of data set
% internal      1x2 vector or struct with 2 fields (x & phi) or string
%               'RANDOM' or 'OPTIMAL' representing the internal angles of 
%               the source
% external      1x3 vector or struct with 3 fields (x, phi and psi) or string
%               'RANDOM' or 'OPTIMAL' representing the external angles of 
%               the source
% detId         (optional) detector identifier string; only needed for 
%               'OPTIMAL' external angles
%
% list          Cell array containing simulations list.  Each row is a
%               simulation. Each component of the row represent:
%               [simId ampl startSamp int1 int2 ext1 ext2 ext3], in this 
%               order. N.B. startSamp is now a scalar - start time has been 
%               determined
%
% SEE ALSO: GRAVEN, GETIFO

% $Id: makelist.m,v 1.22 2004/05/18 21:16:21 stuver Exp $

% DETERMINE operating mode from inputs
% ASSIGN variable names based on mode
% GENERATE list according to mode used

list = {};

% Determine operating mode
input = varargin;
mode = whatmode(input);

% Assign variable names
switch mode
    case 1
        inputFileName = varargin{1};
    case 2
        [nSim, inputFileName] = deal(varargin{:});
    case 3
        [inputFileName, detId] = deal(varargin{:});
    case 4
        [nSim, inputFileName, detId] = deal(varargin{:});
    case 5
        [nSim, simId, ampl, startSamp, internal, external] = ...
            deal(varargin{:});
    case 6
        [nSim, simId, ampl, startSamp, internal, external, detId] = ...
            deal(varargin{:});
end

% Generate list based on mode used:
if mode == 1 | mode == 2 | mode == 3 | mode == 4 % File reading modes
    % IF mode reads from file
    %   READ variables from file
    %   IF mode makes nSim draws on lines of file
    %       DRAW nSim times on lines of file
    %   ENDIF
    %   SET angles
    %   SET start times
    %   RETURN list
    % ENDIF
    
    % Check to make sure file exists
    if exist(inputFileName, 'file') ~= 2
        inputFileName
        error(['makelist: inputFileName does not exist as a file in '...
                'the search path'])
    end
    
    % Read file
    [simId, ampl, startSamp1, startSamp2, int1, int2, ext1, ext2, ext3]=...
        ctextread(inputFileName, '%s %f %f %f %s %s %s %s %s %*[^\n]', ...
        'commentstyle', 'shell');
    % The *[^/n] in the last placeholder ignores all remaining columns in a
    % row.  This enables the log file (which has more columns than the list
    % file) to be read in as a list file.
    
    if ampl == -1
        % Make nSim draws on the lines of inputFileName
        if mode == 2 | mode == 4 
            % Number of rows (simulations) in inputFileName
            mfname = size(simId, 1); 
            for k = 1:mfname
                % Read everything into tempList
                tempList(k,:) = {simId(k,:), ampl(k), startSamp1(k), ...
                        startSamp2(k), int1(k,:), int2(k,:), ext1(k,:), ...
                        ext2(k,:), ext3(k,:)};
                % tempList is used to construct a cell array of the original
                % data in inputFileName and is different in form from the
                % output list in that the start time is determined in list
                % (list has one less column than tempList)
            end
            % Make nSim draws on tempList
            [simId, ampl, startSamp1, startSamp2, int1, int2, ext1, ext2, ...
                    ext3] = ndraws(nSim, tempList);
        end
        
        if mode <= 4
            mSim = size(simId,1);
            for kSim = 1:mSim
                tempSimId = simId{kSim,1};
                I = find(tempSimId == ',');
                if length(I) == 0
                    file{kSim,1} = tempSimId(1:end);
                    file{kSim,2} = 'default';
                elseif length(I) == 1
                    file{kSim,1} = tempSimId(1:I(1)-1);
                    file{kSim,2} = tempSimId(I(1)+1:end);
                else
                    simId{kSim,:}
                    error('pregenlist: Invalid simId')
                end
                external{kSim} = {ext1{kSim}, ext2{kSim}, ext3{kSim}};   
            end
            if mode == 2 | mode == 4
                list = pregenlist(nSim, file, [startSamp1(:), startSamp2(:)], external, detId);
                return
            else
                list = pregenlist(file, [startSamp1(:), startSamp2(:)], external, detId);
                return
            end
            
        end
    elseif ampl <= 0 & ampl ~= -1
        ampl
        error('makelist: ampl must be > 0')
    end
    
    % Cast variabiles into char class from cell (this will aid in
    % comparing variables that may or may not be strings)
    [simId, int1, int2, ext1, ext2, ext3] = deal(char(simId), char(int1), ...
        char(int2), char(ext1), char(ext2), char(ext3));
    
    if mode == 2 | mode == 4 % Make nSim draws on the lines of inputFileName
        % Number of rows (simulations) in inputFileName
        mfname = size(simId, 1); 
        for k = 1:mfname
            % Read everything into tempList
            tempList(k,:) = {simId(k,:), ampl(k), startSamp1(k), ...
                    startSamp2(k), int1(k,:), int2(k,:), ext1(k,:), ...
                    ext2(k,:), ext3(k,:)};
            % tempList is used to construct a cell array of the original
            % data in inputFileName and is different in form from the
            % output list in that the start time is determined in list
            % (list has one less column than tempList)
        end
        % Make nSim draws on tempList
        [simId, ampl, startSamp1, startSamp2, int1, int2, ext1, ext2, ...
                ext3] = ndraws(nSim, tempList);
    end
    
    % Determine angles
    internal = {int1, int2};
    external = {ext1, ext2, ext3};    
    if mode == 1 | mode == 2
        [internal, external] = setangles(mode, internal, external);
    else
        [internal, external] = setangles(mode, internal, external, ...
            'null', detId);
    end
    
    % Determine start times
    startSamp = pickstime(startSamp1, startSamp2);
    if isempty(startSamp)
        error('makelist: pickstime returned empty startSamp')
    end
    
    for k=1:size(simId,1)
        % Assemble and return list:
        list(k,:) = {simId(k,:), ampl(k), startSamp(k), internal(k,1), ...
                internal(k,2), external(k,1), external(k,2), external(k,3)};
    end 
end

if mode == 5 | mode == 6 % Direct variable input modes
    % IF variables are directly input into makelist
    %   SET angles
    %   SET start times
    %   SET amplitudes
    %   RETURN list
    % ENDIF
    
    % Sort out angles  
    if mode == 5 
        [internal, external] = setangles(mode, internal, external, nSim);
    else % mode == 6
        [internal, external] = setangles(mode, internal, external, nSim, ...
            detId);
    end
    
    % Set start times
    startSamp = pickstime(startSamp(1), startSamp(2), nSim);
    if isempty(startSamp)
        error('makelist: pickstime returned empty startSamp')
    end
    
    % Generate amplitudes to simulate
    ampl = setampl(ampl, nSim);
    if isempty(ampl)
        error('makelist: setampl returned empty ampl')
    end
    
    % Assemble list:
    for k = 1:nSim
        list(k,:) = {simId, ampl(k), startSamp(k), internal(k,1), ...
                internal(k,2), external(k,1), external(k,2), external(k,3)};
        % Return list
    end
end

return