function mat_new = expandMatrix(mat, exp_coeff)
%EXPANDMATRIX   Enlarge a matrix interpolating edge values.
%
% DESCRIPTION:
%       expandMatrix enlarges an input matrix interpolating the new values
%       from the matrix edges.
%
% USAGE:
%       mat_new = expandMatrix(mat, exp_coeff)
%
% INPUTS:
%       mat         - the matrix to enlarge
%       exp_coeff   - the number of elements to add in each dimension
%                     in 1D:    [x] or [x_start, x_end]
%                     in 2D:    [x, z] or [x_start, x_end, z_start, z_end]
%                     in 3D:    [x, y, z] or [x_start, x_end, y_start, y_end, z_start, z_end]
%
% ABOUT:
%       author      - Bradley Treeby
%       date        - 13th October 2009
%       last update - 7th December 2009
%       
% This function is part of the k-Wave Toolbox (http://www.k-wave.org)
% Copyright (C) 2009, 2010 Bradley Treeby and Ben Cox

% This file is part of k-Wave. k-Wave is free software: you can
% redistribute it and/or modify it under the terms of the GNU Lesser
% General Public License as published by the Free Software Foundation,
% either version 3 of the License, or (at your option) any later version.
% 
% k-Wave is distributed in the hope that it will be useful, but WITHOUT ANY
% WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
% FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License for
% more details. 
% 
% You should have received a copy of the GNU Lesser General Public License
% along with k-Wave. If not, see <http://www.gnu.org/licenses/>. 

switch numDim(mat)
    
    case 1
        
        % extract expansion coefficients
        if length(exp_coeff) == 2
            x1_size = exp_coeff(1);
            x2_size = exp_coeff(2);
        elseif length(exp_coeff) == 1
            x1_size = exp_coeff(1);
            x2_size = exp_coeff(1);
        else
            error('exp_coeff must be a 1 or 2 element array');
        end
        
        % create a new expanded matrix
        x = length(mat);
        x_new = x + x1_size + x2_size;
        mat_new = ones(x_new, 1);
        
        % create indexes to allow the original matrix to be placed into the
        % expanded matrix
        x1 = x1_size + 1;
        x2 = x_new - x2_size;
        mat_new(x1:x2) = mat;
        
        % replace the remaining values by extending the edges
        mat_new(1:x1-1) = mat(1);
        mat_new(x2+1:end) = mat(end); 
        
    case 2

        % extract expansion coefficients
        if length(exp_coeff) == 4
            x1_size = exp_coeff(1);
            x2_size = exp_coeff(2);
            z1_size = exp_coeff(3);
            z2_size = exp_coeff(4);
        elseif length(exp_coeff) == 2
            x1_size = exp_coeff(1);
            x2_size = exp_coeff(1);
            z1_size = exp_coeff(2);
            z2_size = exp_coeff(2);    
        else
            error('exp_coeff must be a 2 or 4 element array');
        end

        % create a new expanded matrix
        [z x] = size(mat);
        x_new = x + x1_size + x2_size;
        z_new = z + z1_size + z2_size;
        mat_new = ones(z_new, x_new);

        % create indexes to allow the original matrix to be placed into the
        % expanded matrix
        x1 = x1_size + 1;
        x2 = x_new - x2_size;
        z1 = z1_size + 1;
        z2 = z_new - z2_size;
        mat_new(z1:z2, x1:x2) = mat; 

        % replace the remaining values by extending the edges
        mat_new(1:z1-1, x1:x2) = repmat(mat(1, :), z1_size, 1);
        mat_new(z2+1:end, x1:x2) = repmat(mat(end, :), z2_size, 1);
        mat_new(z1:z2, 1:x1-1) = repmat(mat(:, 1), 1, x1_size);
        mat_new(z1:z2, x2+1:end) = repmat(mat(:, end), 1, x2_size);
        mat_new(1:z1-1, 1:x1-1) = mat(1, 1)*ones(z1_size, x1_size);
        mat_new(1:z1-1, x2+1:end) = mat(1, end)*ones(z1_size, x2_size);
        mat_new(z2+1:end, 1:x1-1) = mat(end, 1)*ones(z2_size, x1_size);
        mat_new(z2+1:end, x2+1:end) = mat(end, end)*ones(z2_size, x2_size);
        
    case 3
        
        
    otherwise
        error('Input matrix must be 1, 2, or 3 dimensional');
end