function h = dex0(matin, dataaspectratio)

%%
dimsizes = size(matin);
if nargin < 2
    dataaspectratio = nan(1, numel(dimsizes));
end

h = buildUI(dimsizes);
    
set(h.Cf, 'Name', ['', inputname(1)])
set(h.Cf, 'DeleteFcn', @(varargin) close(h.Imfig))
set([h.Bg(1) h.Bg(2)], 'SelectionChangeFcn', @callback)
set(h.Play, 'Callback', @(hObject, varargin) play(hObject, h))
set(h.Sl, 'Callback', @callback)
set(h.tbAutosc, 'ClickedCallback', @(varargin) autos(0.99, h.Im));
set(h.tbImcontrast, 'ClickedCallback', @(varargin) @(varargin) imcontrast(h.Im));

callback(NaN);
refreshImage

axes(h.Ax); colormap gray
oldxydim = getXyDim(h);

drawnow, focuslink([h.Imfig h.Cf]);

    function refreshImage(varargin)
        axes(h.Ax)
        axis tight off
        xydim = getXyDim(h);
        if ~any(isnan(dataaspectratio(xydim)))
            daspect(h.Ax, [dataaspectratio(xydim) 1])
        else
            daspect(h.Ax, 'auto')
        end
        set(h.Ax, 'Clipping', 'off')
    end

    function callback(hObject, varargin)
        switch(hObject)
            case num2cell(h.Sl) %any slider handle
                val = round(get(hObject, 'Value'));
                set(hObject, 'Value', val, 'TooltipString', num2str(val));
                set(h.CurrSliceLabel(h.Sl == hObject), 'String', num2str(val));
            case {h.Bg(1), h.Bg(2)}
                xydim = getXyDim(h);
                if xydim(1) == xydim(2)
                	set(h.Bg(xydim==oldxydim),'SelectedObject', h.Rb{xydim==oldxydim}(oldxydim(xydim~=oldxydim)));
                end
                oldxydim = getXyDim(h);
                displayimage
                refreshImage
        end
        displayimage
    end
    
    function displayimage
        im = squeeze(subsref(matin, getSubsStruct(h)));
        if ~isreal(im), im = cimage(im); end
        xydim = getXyDim(h);
        if xydim(2) < xydim(1), im = im'; end
        set(h.Im, 'CData', im);
        drawnow
        %if 
    end

    function play(hObject, h)
        fps = 10;
        sliderhandle = h.Sl(get(hObject, 'UserData'));
        maxframes = get(sliderhandle, 'Max');
        tic
        while (get(hObject, 'Value') == 1)
            val = round(get(sliderhandle, 'Value')+1);
            if val > maxframes, set(sliderhandle, 'Value', 1), displayimage, break, end
            set(sliderhandle, 'Value', val)
            displayimage
            pause(1/fps - toc), tic
        end
        set(hObject, 'Value', 0)
    end
end

function h = buildUI(dimsizes)
    h.SlicePlot = NaN;
    h.Imfig = figure('Position', [0 0 512 512], 'Visible', 'off');
    h.Ax = axes('Parent', h.Imfig); set(h.Ax, 'Position', [0 0 1 1], 'Clipping', 'off')
    movegui(h.Imfig, 'northwest'); imfigpos = get(h.Imfig, 'Position');
    set(h.Imfig, 'Visible', 'on')
    h.Cf = figure;
    h.Im = imagesc(NaN, 'Parent', h.Ax);
    
    spacing = 22;
    cfheight = length(dimsizes)*spacing+5;
    
    %fpos = get(h.Cf, 'Position'); 
    fpos = [imfigpos(1) imfigpos(2)-80-length(dimsizes)*spacing 400 cfheight];
    set(h.Cf, 'Position', fpos, 'MenuBar', 'none', 'Name', 'dex', 'Resize', 'off', 'NumberTitle', 'off');
    %iptwindowalign(h.Imfig, 'bottom', h.Cf, 'top'), iptwindowalign(h.Imfig, 'left', h.Cf, 'left')
    %set(h.Cf, 'WindowButtonUpFcn', @(varargin) set(h.Cf, 'WindowButtonMotionFcn', ''))
    set(h.Cf, 'BusyAction', 'cancel', 'WindowButtonMotionFcn', @cursorMotion)
    
    h.Tb = uitoolbar(h.Cf);
    icon_imcontrast = uint8(cat(3, ...
        [255 255 255 255 255 255 255 255 255 255 251 235 254 255 255 255;255 255 255 137 89 247 231 100 117 248 174 39 178 255 255 255;255 255 250 32 0 190 97 1 1 105 107 0 120 255 255 255;255 255 245 41 0 138 19 7 5 9 63 0 124 255 255 255;255 255 247 46 4 104 1 76 107 1 12 0 128 255 255 255;255 255 246 48 4 63 1 137 220 9 1 0 130 255 255 255;255 255 246 50 0 25 1 187 255 79 1 0 130 255 255 255;255 255 252 61 0 2 9 215 255 142 1 0 132 255 255 255;255 255 255 84 0 1 40 241 255 170 1 0 132 255 255 255;255 255 255 80 0 1 79 255 255 205 1 0 54 131 81 80;138 87 72 12 0 1 174 255 255 255 66 0 1 1 1 1;21 1 1 1 0 78 255 255 255 255 144 0 30 113 130 172;180 137 166 62 0 133 255 255 255 255 181 0 50 255 255 255;255 255 255 114 0 143 255 255 255 255 202 0 6 239 255 255;255 255 255 207 134 223 255 255 255 255 241 69 88 250 255 255;255 255 255 255 255 255 255 255 255 255 255 247 248 255 255 255], ...
        [255 255 255 255 255 255 255 255 255 255 251 235 254 255 255 255;255 255 255 137 89 247 231 99 116 248 174 39 178 255 255 255;255 255 250 32 0 190 96 0 0 104 107 0 120 255 255 255;255 255 245 41 0 138 18 6 4 8 63 0 124 255 255 255;255 255 247 46 4 103 0 75 106 0 12 0 128 255 255 255;255 255 246 48 4 62 0 137 220 8 0 0 130 255 255 255;255 255 246 50 0 24 0 187 255 78 0 0 130 255 255 255;255 255 252 61 0 1 8 215 255 142 0 0 132 255 255 255;255 255 255 84 0 0 39 241 255 170 0 0 132 255 255 255;255 255 255 80 0 0 78 255 255 205 0 0 53 131 80 79;138 86 71 12 0 0 174 255 255 255 66 0 0 0 0 0;20 0 0 0 0 78 255 255 255 255 144 0 30 112 130 172;180 137 166 62 0 133 255 255 255 255 181 0 50 255 255 255;255 255 255 114 0 143 255 255 255 255 202 0 6 239 255 255;255 255 255 207 134 223 255 255 255 255 241 69 88 250 255 255;255 255 255 255 255 255 255 255 255 255 255 247 248 255 255 255], ...
        [255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255;255 255 255 255 255 254 231 99 116 249 255 255 255 255 255 255;255 255 255 255 255 236 96 0 0 106 238 255 255 255 255 255;255 255 255 255 255 207 18 6 4 8 205 255 255 255 255 255;255 255 255 255 255 180 0 75 106 0 165 255 255 255 255 255;255 255 255 255 255 144 0 137 220 8 149 255 255 255 255 255;255 255 255 255 255 109 0 187 255 78 146 255 255 255 255 255;255 255 255 255 255 97 8 215 255 142 148 255 255 255 255 255;255 255 255 255 255 101 39 241 255 170 150 255 254 255 255 255;255 255 255 255 255 98 78 255 255 205 145 255 183 131 80 80;139 86 71 188 255 105 174 255 255 255 196 255 130 0 0 2;22 0 0 141 255 204 255 255 255 255 250 255 211 114 130 173;181 137 166 222 255 255 255 255 255 255 255 255 255 255 255 255;255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255;255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255;255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255]));
    icon_autos = uint8(cat(3, ...
        [255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255;255 255 255 255 255 255 255 252 247 252 255 255 255 255 255 255;255 255 255 255 255 255 255 245 242 244 255 255 255 255 255 255;255 255 255 255 255 255 254 243 242 242 252 255 255 255 255 255;255 255 252 249 249 250 248 242 242 242 246 251 250 252 255 255;255 253 243 242 242 242 242 242 242 242 242 242 242 242 252 255;255 253 242 242 242 242 242 242 242 242 242 242 242 242 253 255;255 255 249 242 242 242 242 242 242 242 242 242 243 251 255 255;255 255 255 247 242 242 242 242 242 242 242 244 253 255 255 255;255 255 255 255 247 242 242 242 242 242 242 248 255 255 255 255;255 255 255 255 250 242 242 242 242 242 242 246 255 255 255 255;255 255 255 255 244 242 242 242 242 242 242 242 252 255 255 255;255 255 255 250 242 242 242 244 248 242 242 242 247 255 255 255;255 255 255 250 242 242 242 251 255 250 242 242 248 255 255 255;255 255 255 254 245 243 250 255 255 255 250 248 254 255 255 255;255 255 255 255 254 254 255 255 255 255 255 255 255 255 255 255],...
        [255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255;255 255 255 255 255 255 255 224 158 223 255 255 255 255 255 255;255 255 255 255 255 255 255 133 101 126 254 255 255 255 255 255;255 255 255 255 255 255 248 110 101 101 220 255 255 255 255 255;255 255 223 183 183 192 173 101 101 101 151 208 198 218 253 255;255 237 111 101 101 101 101 101 101 101 101 101 101 101 219 255;255 234 106 101 101 101 101 101 101 101 101 101 101 103 228 255;255 255 184 101 101 102 101 101 101 101 101 101 107 207 255 255;255 255 255 158 101 101 101 101 102 101 101 120 225 255 255 255;255 255 255 255 165 101 101 101 102 101 101 176 255 255 255 255;255 255 255 255 199 101 101 101 101 101 101 152 255 255 255 255;255 255 255 250 126 101 101 101 101 101 101 101 216 255 255 255;255 255 255 193 101 101 101 123 171 106 101 101 161 255 255 255;255 255 255 190 101 101 101 205 255 194 101 101 173 255 255 255;255 255 255 242 135 114 192 255 255 255 201 167 241 255 255 255;255 255 255 255 248 246 255 255 255 255 255 255 255 255 255 255],...
        [255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255;255 255 255 255 255 255 255 211 115 209 255 255 255 255 255 255;255 255 255 255 255 255 255 80 34 70 254 255 255 255 255 255;255 255 255 255 255 255 245 47 34 34 205 255 255 255 255 255;255 255 209 152 151 164 138 34 34 34 105 188 174 202 252 255;255 229 49 34 34 34 34 34 34 34 34 34 34 34 203 255;255 226 42 34 34 34 34 34 34 34 34 34 34 37 217 255;255 255 154 34 34 35 34 34 34 34 34 34 43 187 255 255;255 255 255 116 34 34 34 34 35 34 34 62 213 255 255 255;255 255 255 255 126 34 34 34 36 34 34 142 255 255 255 255;255 255 255 255 175 34 34 34 34 34 34 108 255 255 255 255;255 255 255 248 70 34 34 34 34 34 34 34 199 255 255 255;255 255 255 166 34 34 34 65 135 42 34 34 121 255 255 255;255 255 255 162 34 34 34 183 255 167 34 34 137 255 255 255;255 255 255 236 83 53 165 255 255 255 177 128 235 255 255 255;255 255 255 255 245 242 255 255 255 255 255 255 255 255 255 255]));    
    h.tbAutosc = uipushtool('CData', icon_autos);
    h.tbImcontrast = uipushtool('CData', icon_imcontrast, 'ClickedCallback', @(varargin) imcontrast(h.Im));

    h.Bg(1) = uibuttongroup('BorderType', 'none', 'HitTest', 'on', 'Units', 'pixels', 'Position',[2 0 20 cfheight], 'Clipping', 'off');
    h.Bg(2) = uibuttongroup('BorderType', 'none', 'HitTest', 'on', 'Units', 'pixels', 'Position',[20 0 20 cfheight], 'Clipping', 'off');
    
    for iDim = 1:length(dimsizes)        
        ds = dimsizes(iDim);
        h.Rb{1}(iDim) = uicontrol(h.Cf, 'Style', 'Radiobutton', 'Position', [0 fpos(4)-spacing*(iDim) 20 20], 'Parent', h.Bg(1), 'UserData', iDim);
        h.Rb{2}(iDim) = uicontrol(h.Cf, 'Style', 'Radiobutton', 'Position', [0 fpos(4)-spacing*(iDim) 20 20], 'Parent', h.Bg(2), 'UserData', iDim);
        h.Sl(iDim) = uicontrol(h.Cf, 'Style', 'Slider', ...
            'SliderStep', [1/(max([ds 2])-1) 1/(max([ds 2])-1)], 'Value', 1, 'Min', 1, 'Max', dimsizes(iDim), ...
            'Position', [130 fpos(4)-spacing*(iDim)+1 230 15], 'HitTest', 'on');
        h.DimLabel(iDim) = uicontrol(h.Cf, 'Style', 'text', 'Position', [40 fpos(4)-spacing*(iDim) 30 15], ...
            'String', ['dim:', num2str(iDim)], 'HorizontalAlignment', 'left');
        h.CurrSliceLabel(iDim) = uicontrol(h.Cf, 'Style', 'text', 'Position', [70 fpos(4)-spacing*(iDim) 30 15], ...
            'String', '1', 'HorizontalAlignment', 'right');
        h.SliceNumLabel(iDim) = uicontrol(h.Cf, 'Style', 'text', 'Position', [100 fpos(4)-spacing*(iDim) 30 15], ...
            'String', ['/', num2str(dimsizes(iDim))], 'HorizontalAlignment', 'left');
        h.Play(iDim) = uicontrol(h.Cf, 'Style', 'togglebutton', 'Position', [365 fpos(4)-spacing*(iDim)+1 30 15], 'String', 'Play', 'UserData', iDim);
        %set(hLabel(iDim), 'BackgroundColor', get(h.Cf, 'Color'))
        if dimsizes(iDim) <= 1, set([h.Sl(iDim) h.Play(iDim)], 'enable', 'off'), end
    end 
    set(h.Bg(1),'SelectedObject',h.Rb{1}(1))
    set(h.Bg(2),'SelectedObject',h.Rb{2}(2))
    
    function cursorMotion(varargin)
        if isempty(gco) || ~any(h.Sl == gco), return, end
        persistent oldvalue, if isempty(oldvalue), oldvalue = 0; end
        val = round(get(gco, 'Value'));
        if val ~= oldvalue
            slcallback = get(gco, 'Callback');
            slcallback(gco);
            oldvalue = val;
        end
    end
end

function subsStruct = getSubsStruct(h, xydim)
    if nargin < 2, xydim = getXyDim(h); end
    subsStruct.type='()';
    subsStruct.subs = num2cell(getSelectedDims(h));
    subsStruct.subs(xydim) = {':'};
end

function selectedDims = getSelectedDims(h)
    selectedDims = (round(cell2mat(get(h.Sl, 'Value'))));
end

function xydim = getXyDim(h)
    xydim(1) = get(get(h.Bg(1),'SelectedObject'), 'UserData');
    xydim(2) = get(get(h.Bg(2),'SelectedObject'), 'UserData');
end