function viewVolume(varargin)
% function viewVolume(varargin)
%
% Description:
% Utility function that enables users to view a volume given the path
% and name of a volume directory containing the image slices in any image format
% known to Matlab. If no volume directory is given users are presented
% with an open file dialog to choose a volume slice. All images with the
% same extension in the same directory are assumed to compose the volume.
% Specifying path in this case causes the file dialog to open in that
% location which. Keeping the volume directory and the path to it separate
% increases reusability of the function as it makes it useful in the
% context of other programs that maintain the notion of a project.
% Furthermore if both the path and the volume directory are specified, a
% third parameter stipulating the image file type has to be present. For
% instance to invoke the viewer without presenting a file dialog use the
% following function call syntax:

% viewVolume('path', fullfile(pwd, 'demoData'), 'volumedirectory', ..
% '672clippedA128Cubed', 'extension', '.png')

% This will display a volume whose slices are located in
% C:\myVolumes\sampleVolumeSubDir'
%
% Author: Johann Strasser
% Date: 070312

% error('My error');

error(nargchk(0, inf, nargin));

if mod(length(varargin), 2) ~= 0
    % input did not come in parameter/value pairs
    error('Arguments have to come in parameter/value pairs.');
end

path = pwd;
path = 'C:\pg\projectVA\VAToolboxDevDir\srcAndProjects\VATProjects\VAT_arabidopsisGrowthAnalysis\849_256x256x348_s\originalVolumes\849_ts20061101_1817_ x23p00y23p00z23p00_gfp325';
path = 'C:\pg\projectVA\VAToolboxDevDir\srcAndProjects\VATProjects\VAT_arabidopsisGrowthAnalysis\1279_260x260x348\originalVolumes';
path = 'C:\pg\projectVA\VAToolboxDevDir\srcAndProjects\VATProjects\VAT_arabidopsisGrowthAnalysis\825_260x260x348\originalVolumes';
path = 'C:\pg\projectVA\3DShapeModelsDevDir\srcAndProjects\PRJ_ArabidopsisLeafShape_johannTHESIS\Cropped';
volumeDirectory = '';
extension = '';
fullVolumePath = '';
volumeType = 'rgb';
mode = 'haptic';
renderType = 'rgb'; % Otherwise assumed auto, which renderes indexed textrues if single channel (slow!)
planeSpacing = [32, 32, 32];
planeSpacing = [16, 16, 16];
planeSpacing = [8, 8, 8];
planeSpacing = [4, 4, 4];

% For now we ignore any input arguments
for i=1:2:length(varargin)
    switch lower(varargin{i})
        case 'path'
            path = varargin{i + 1};
        case 'volumedirectory'
            volumeDirectory = varargin{i + 1};
        case 'extension'
            extension = varargin{i + 1};
        case 'mode'
            mode = varargin{i + 1};
        case 'rendertype'
            renderType = varargin{i + 1};
        case 'planespacing'
            planeSpacing = varargin{i + 1};
        otherwise
            error(['Unknown parameter name passed to viewVolume. ', ...
                'Parameter name: ',  varargin{i}]);
    end
end

userCancel = 0;

if isequal(volumeDirectory, '')

    imreadSupportedFileTypes = getImreadSupportedTypesFilterSpec();

    [fileName, path] = uigetfile(imreadSupportedFileTypes, ...
        'Choose volume slice', [path, filesep]);

    if isequal(fileName, 0)
        disp('User selected cancel.');
        userCancel = 1;
    else
        [fullVolumePath, name, extension, versn] = fileparts(fullfile(path, fileName));
        [p, volumeDirectory, e, v] = fileparts(fullVolumePath);

    end
else

    % The extension has to be present for the function dir to be able to
    % list image files of a particular type.
    if ~isequal(extension, '')
        fullVolumePath = [path, filesep, volumeDirectory];
    else
        error(['Image file type extension not specified. ']);
    end

end

if ~userCancel

    % The following drawnow flushes the event queue and updates the figure
    % window
    %     drawnow;

    if isequal(extension, '.rawb')
        % Example volume taken from:
        % http://www.bic.mni.mcgill.ca/cgi/brainweb1?alias=subject04_skl&download=1
        fullfilepath = fullfile(fullVolumePath, [name extension]);
        fid = fopen(fullfilepath, 'r');
        byteVolume = uint8(fread(fid, inf, 'int8')); % default apparently uint8
        fclose(fid);
        %dimensions = [362, 434, 362, 3];
        dimensions = [256, 256, 181, 3];
        volume = zeros(dimensions, 'uint8');
        byteVolume = reshape(byteVolume, dimensions(1:3));
        volume(:, :, :, 1) = byteVolume;
        volume(:, :, :, 2) = byteVolume;
        volume(:, :, :, 3) = byteVolume;
    else
        volume = loadVolumeFromSlicesDirTyped('fullVolumePath', fullVolumePath, ...
            'extension', extension);


        if size(volume, 4) ~= 3
            volumeType = 'single';
        end
    end

    if isequal(mode, 'haptic')
  
        vt = getHTTransform();
%         vt.parentTransform = 'transform1';
        vt.name = 'volumeTransform';       
        % Set up transform
        transforms(1) = vt;

        voxelSize = getVoxelSizeFromString('string', volumeDirectory) / 1000;

        % Normalise voxel size to make display size dependent on volume
        % dimensions as opposed to euclidean dimensions. 
        % Aspect ratio is preserved.
        voxelSize = voxelSize / min(voxelSize) / 1000; % / 1000 as with voxelSize previously
        
        % Make volume RGB for hapticToolNative if required
        if isequal(volumeType, 'single')
            
            % Smooth the volume
%             c = class(volume);
%             volume = cast(smooth3(volume, 'gaussian', 3), c);
                       
            volume = repmat(volume, [1, 1, 1, 3]);
            
            % Use only green channel
%             volume(:, :, :, 1) = 0;
%             volume(:, :, :, 3) = 0;            
        end
              
        % Flip dimension to be consistent with Matlab 3D plotting
        volume = flipdim(volume, 1);

        v = getHTVolume();
        v.name = 'volume1';
        v.parentTransform = 'volumeTransform';
        v.volume = volume;
        v.planes = 256;
        v.voxelSize = voxelSize;
        v.hapticChannel = 'green';
        volumes(1) = v;

        ils = getHTIndexedLineSet();
        ils.parentTransform = 'volumeTransform';
        ils.interactionMode = 'edit';
        indexedLineSets(1) = ils;

        %      p = getHTPointSet();
        %      pointSets(1) = p;
        %
        %      ils = getHTIndexedLineSet();
        %      indexedLineSets(1) = ils;

        clipPlanes(i) = getHTClipPlane();
        noOfClipPlanes = 3;
        cpXOffset = 0.03;
        cpXBasePos = 0 - (noOfClipPlanes * cpXOffset / 2);
        cpYBasePos = -size(volume, 2) / 1000 / 2;

        for i = 1:noOfClipPlanes

            cp = getHTClipPlane();
            cp.name = ['clipPlane', num2str(i)];
            cp.parentTransform = 'volumeTransform';
            cp.point = [cpXBasePos + cpXOffset * (i - 1), cpYBasePos, 0];
            cp.normal = [0, 1, 0];
            cp.interactionMode = 'edit';
            clipPlanes(i) = cp;
        end

        if noOfClipPlanes == 0
            clipPlanes = [];
        end

        % Make sure the delete on the progress bar is processed
        drawnow;

        [transformsOut, volumesOut, pointSetsOut, indexedLineSetsOut, clipPlanesOut] =...
            hapticTool(transforms, volumes, [], indexedLineSets, clipPlanes);
%        
%         [transformsOut, volumesOut, pointSetsOut, indexedLineSetsOut, clipPlanesOut] =...
%             hapticTool(transforms, volumes, [], indexedLineSets, []);

    elseif isequal(mode, 'matlab')

        % Use RGB rendering if requested since it is a lot faster than indexed
        if isequal(volumeType, 'single') && isequal(renderType, 'rgb')
            volume = repmat(volume, [1, 1, 1, 3]);
        end
        
        volumeSize = size(volume);
        
        % Set planeSpacing if maximum is exceeded
        
        h = figure;
        maxIntensity = 256;
        jalphamap(h, 'rampup', maxIntensity);
        colormap(gca, jet(maxIntensity));
        
        origModel = renderVolume('Axis', gca, 'CData', volume, ...
            'PlaneSpacing', planeSpacing , 'Texture', '3D');
        box on;
        axis equal;
        axis tight;
        title(['Size == ', mat2str(volumeSize), ')']);
    end
end