function internal = setinternal(mode, preInternal, varargin)

% SETINTERNAL - set the internal angles for makelist
%
% internal = setinternal(mode, preInternal)
%   internal drawn from file and cannot be 'OPTIMAL'
% internal = setinternal(mode, preInternal, nSim)
%   internal can be 'OPTIMAL'
%
% mode      operating mode of makelist
% preInternal  intermediate internal angles 
% nSim      (optional) number of angles to generate
%
% internal  determined internal angles

% $Id: setinternal.m,v 1.2 2004/05/10 20:26:14 stuver Exp $

% DETERMINE how internal angles where input to makelist from mode
% IF internal angles were read from file
%   DETERMINE if makelist needs to set angles
%   IF angle needs to be set
%       SET angle
%   ELSEIF angle does not need to be set
%       TYPECAST from string to double
%   ENDIF
%   RETURN determined internal angles
% ELSEIF internal angles were not read from a file
%   DETERMINE class of internal
%   IF string
%       SET angles either randomly or to optimal orientation
%   ELSEIF double
%       COPY internal nSim times
%   ELSEIF struct
%       COPY inernal nSim times
%   ENDIF
%   RETURN determined internal angles
% ENDIF

internal = [];

% If internal was read from a file
if mode == 1 | mode == 2 | mode == 3 | mode == 4
    % There are 2 types of internal angles that need to be looked at 
    % individually.
    % Each of these angle types may be a list.  Each angle on the list must 
    % be looked at individually.
    
    % Sort internal into the two angle types
    [int1, int2] = deal(preInternal{1}, preInternal{2});

    % Look at every angle in each angle type
    for k = 1:size(int1, 1)     
        % Examine int1
        if strcmp(upper(int1(k,:)), 'RANDOM') | ...
            strcmp(upper(int1(k,:)), 'RANDOM ')
            % Set first internal angle randomly
            tempInt1(k,1) = randomangle(1, 'x');
        elseif strcmp(upper(int1(k,:)), 'OPTIMAL')
            % Optimize first internal angle
            tempInt1(k,1) = 1;
        else
            % Typecast first internal angle
            tempInt1(k,1) = str2double(int1(k,:));
            % Check for error
            if isnan(tempInt1(k,1))
                int1 = int1(k,:)
                error('makelist -> setinternal: Error reading int1')
            end
        end 
        % Examine int2
        if strcmp(upper(int2(k,:)), 'RANDOM') | ...
            strcmp(upper(int2(k,:)), 'RANDOM ')
            % Set second internal angle randomly
            tempInt2(k,1) = randomangle(1, 'phi');
        elseif strcmp(upper(int2(k,:)), 'OPTIMAL')
            % Optimize second internal angle
            tempInt2(k,1) = 0;
        else
            % Typecase second internal angle
            tempInt2(k,1) = str2double(int2(k,:)); 
            % Check for error
            if isnan(tempInt2(k,1))
                int2 = int2(k,:)
                error('makelist -> setinternal: Error reading int2')
            end
        end
    end
    % Return determined internal angles
    internal = [tempInt1, tempInt2];
    
% If internal was not read from a file
elseif mode == 5 | mode == 6
    
    % Set nSim from varargin
    if length(varargin) >= 1
        nSim = varargin{1};
    else
        error(['makelist -> setinternal: Need to know number of '...
                'internal angles to generate (nSim)'])
    end
    
    if strcmp(class(preInternal), 'char') % internal is a string
        if strcmp(upper(preInternal), 'RANDOM')
            % Set all (int1 & int2) internal angles randomly nSim times
            internal = [randomangle(nSim, 'x'), randomangle(nSim, 'phi')];
            % Return determined internal angles
        elseif strcmp(upper(preInternal), 'OPTIMAL')
            % Generate nSim optimized internal angles
            internal = repmat([1, 0], nSim, 1);
            % Return determined internal angles        
        else
            internal = preInternal
            error(['makelist -> setinternal: internal must be 1x2 vector '...
                    'or string ''RANDOM'' or ''OPTIMAL'''])
        end
    elseif strcmp(class(preInternal), 'double') % internal is a double
        % Copy internal angles nSim times
        internal = repmat(preInternal, nSim, 1);
        % Return determined internal angles
    elseif strcmp(class(preInternal), 'struct') % internal is a struct
        if ~isfield(preInternal, 'x') | ~isfield(preInternal, 'phi')
            internal = preInternal
            error(['makelist -> setinternal: The internal struct must '...
                    'have fields x and phi'])
        end
        % Copy internal angles nSim times
        internal = repmat([preInternal.x, preInternal.phi], nSim, 1);
        % Return determined internal angles
    else 
        internal = preInternal
        error(['makelist -> setinternal: Class type of internal must ' ...
                'be double, struct or char'])
    end
    
end

% Check ranges on the angles
check = find(abs(internal(:,1)) > 1);
if ~isempty(check)
    int1 = internal(:,1)
    error(['makelist -> setinternal: The first internal angle is out of ' ...
            'range: (-1 1)'])
end

check = find(internal(:,2) < -pi | internal(:,2) > pi);
if ~isempty(check)
    int2 = internal(:,2)
    error(['makelist -> setinternal: The second internal angle is out of '...
        'range: (-pi pi)'])
end
    
return