function SectorCompareTool(varargin)
% function SectorCompareTool(varargin)
%
% A tool that takes a list of binary images and a corresponding list of rgb
% images and then lets the user click on sectors in any image. As the user
% clicks on a sector, the best fitted ellipse for that sector will be
% shown. If the user then clicks on another sector, the corresponding
% ellipse for that sector is displayed and the growth tensor that
% corresponds to the two ellipses is then calculated and shown in another
% figure.
%
% Inputs:
%
%  'bimgfilenames' - a cell array containing the full pathnames of the
%                    binary images (usually tif no compression).
%
%  'imgfilenames' - a cell array containing the full pathnames of the
%                   rgb images.
%
% Dr. Andrew I. Hanna, CMP & JIC, 2008.

error(nargchk(0,inf,nargin));
if checkSATDir(pwd) == 0
    fprintf('You are not in a valid SectorAnalysisToolbox Project directory\n');
    return;
end
data = parseargs(varargin);

% Open, move, and get the handles from the figure file.
ad.figMain = openfig(mfilename, 'reuse');
movegui(ad.figMain, 'center');
set(ad.figMain, 'Visible', 'on');
ad.handles = guihandles(ad.figMain);
set(ad.figMain, 'Color', get(ad.handles.panelA, 'BackgroundColor'));

ad = setupcallbacks(ad);
ad = initadstructure(ad, data);

% Remove the save icon from the toolbar
%customtoolbar(ad.figMain);
setappdata(0,'SectorCompareToolData',ad);
changeSectorA(ad.handles.sectorsA);
changeSectorB(ad.handles.sectorsB);
try
    uiwait(ad.figMain);
catch
    if ishandle(ad.figMain)
        delete(ad.figMain)
    end
end
value = 0;
return;

%%
function ad = setupcallbacks(ad)
% Set all the callback functions
set(ad.handles.sectorsA, 'callback', {@changeSectorA});
set(ad.handles.sectorsB, 'callback', {@changeSectorB});
set(ad.handles.compbtn, 'callback', {@compareSectors});
set(ad.handles.transslider, 'callback', {@adjustTransValue});

return
%%
function ad = initadstructure(ad, data)

ad.pathnames.StagedDirString =  'Staged';
ad.data.sectorA = initdata();
ad.data.sectorB = initdata();
ad.handles.gtaxes = -1;
ad.handles.sectorah = -1;
ad.handles.sectorbh = -1;

ad.data.ellipvec = {};

ad.data.sector_files = data.bimgfilenames;
ad.data.rgb_files = data.imgfilenames;
rgbfilenames = cell(1, length(ad.data.rgb_files));
for i=1:length(ad.data.rgb_files)
   [junk, rgbfilenames{i}] = fileparts(ad.data.rgb_files{i});
end
set(ad.handles.sectorsA, 'String', rgbfilenames);
set(ad.handles.sectorsB, 'String', rgbfilenames);
return
%%
function data = initdata()
data.pathname = '';
data.filename = '';
data.bwim = [];
data.im = [];
data.L = [];
data.boundaries = {};
return
%%
function data = loadData(imfilename, bwfilename)
wh = waitbar(0, 'Loading...');
if exist(bwfilename, 'file')
    waitbar(0.2, wh);
    data.bwim = imread(bwfilename);
    waitbar(0.4, wh);
    data.L = bwlabel(data.bwim);

end
waitbar(0.5, wh);
if exist(imfilename, 'file')
    data.im = imread(imfilename);
end
delete(wh);
return
%%
function changeSectorA(popup, evd)
ad = getappdata(0, 'SectorCompareToolData');
val = get(popup, 'Value');
data = loadData(ad.data.rgb_files{val}, ad.data.sector_files{val});
ad.data.sectorA = data;
setappdata(0, 'SectorCompareToolData', ad);
updateSectorA();
return

%%
function changeSectorB(popup, evd)
ad = getappdata(0, 'SectorCompareToolData');
val = get(popup, 'Value');
str = get(popup, 'String');
data = loadData(ad.data.rgb_files{val}, ad.data.sector_files{val});
ad.data.sectorB = data;
setappdata(0, 'SectorCompareToolData', ad);
updateSectorB();
return
%%
function updateSectorA(popup, evd)
ad = getappdata(0, 'SectorCompareToolData');
cla(ad.handles.sectorAaxes);
if ~isempty(ad.data.sectorA.im)
    showImage(ad.data.sectorA.im, ad.handles.sectorAaxes);
end
if ~isempty(ad.data.sectorA.bwim)
    ad.handles.sectorah = showSectors(ad.data.sectorA.bwim, ad.handles.sectorAaxes, get(ad.handles.transslider, 'Value'));
end

setappdata(0, 'SectorCompareToolData', ad);
compareSectors(ad.handles.compbtn);
return
%%
function adjustTransValue(slider, evd)
ad = getappdata(0, 'SectorCompareToolData');
if ishandle(ad.handles.sectorah)
    set(ad.handles.sectorah, 'AlphaData', get(slider, 'Value'));
end
if ishandle(ad.handles.sectorbh)
    set(ad.handles.sectorbh, 'AlphaData', get(slider, 'Value'));
end
setappdata(0, 'SectorCompareToolData', ad);
return
%%
function updateSectorB(popup, evd)
ad = getappdata(0, 'SectorCompareToolData');
cla(ad.handles.sectorBaxes);
if ~isempty(ad.data.sectorB.im)
    showImage(ad.data.sectorB.im, ad.handles.sectorBaxes);
end

if ~isempty(ad.data.sectorB.bwim)
    ad.handles.sectorbh = showSectors(ad.data.sectorB.bwim, ad.handles.sectorBaxes, get(ad.handles.transslider, 'Value'));
end
setappdata(0, 'SectorCompareToolData', ad);
compareSectors(ad.handles.compbtn);
return
%%
function imh = showSectors(im, ah, transval)
imh = [];
if transval<0
    return;
end
hold(ah, 'on');
im = uint8(im*255);
im = repmat(im, [1 1 3]);
imh = imagesc(im, 'Parent', ah, 'HitTest', 'off');
set(imh, 'AlphaData', transval);
axis(ah, 'image', 'ij');
return
%%
function showImage(im, ah)
imagesc(im, 'Parent', ah, 'HitTest', 'off');
axis(ah, 'image', 'ij');
return
%%
function compareSectors(btn, evd)
ad = getappdata(0, 'SectorCompareToolData');
if get(btn, 'Value')==1
    set(ad.handles.sectorAaxes, 'ButtonDownFcn', {@sectorAClicked});
    set(ad.handles.sectorBaxes, 'ButtonDownFcn', {@sectorBClicked});
else
    set(ad.handles.sectorAaxes, 'ButtonDownFcn', '');
    set(ad.handles.sectorBaxes, 'ButtonDownFcn', '');
end
setappdata(0, 'SectorCompareToolData', ad);
%%
function sectorAClicked(ah, evd)
ad = getappdata(0, 'SectorCompareToolData');
if isempty(ad.data.sectorA.L)
    return;
end
pt = get(ah, 'CurrentPoint');
pt = round(pt(1,1:2));
id = ad.data.sectorA.L(pt(2), pt(1));
if id>0
    [gt, mu] = label2GT(ad.data.sectorA.L==id);
    plotGT(ah, gt, mu);
    if length(ad.data.ellipvec)<3
        ad.data.ellipvec = cat(2, ad.data.ellipvec, gt);
    end
end
setappdata(0, 'SectorCompareToolData', ad);
if length(ad.data.ellipvec)==2
    compareEllipses();
end
%%
function sectorBClicked(ah, evd)
ad = getappdata(0, 'SectorCompareToolData');
if isempty(ad.data.sectorB.L)
    return;
end
pt = get(ah, 'CurrentPoint');
pt = round(pt(1,1:2));
id = ad.data.sectorB.L(pt(2), pt(1));
if id>0
    [gt, mu] = label2GT(ad.data.sectorB.L==id);
    plotGT(ah, gt, mu);
    if length(ad.data.ellipvec)<3
        ad.data.ellipvec = cat(2, ad.data.ellipvec, gt);
    end
end
setappdata(0, 'SectorCompareToolData', ad);
if length(ad.data.ellipvec)==2
        compareEllipses();
end
%%
function compareEllipses()
ad = getappdata(0, 'SectorCompareToolData');
ellipses = ad.data.ellipvec;
E1 = ellipses{1}.growthTensor;
E2 = ellipses{2}.growthTensor;
[smax1, smin1, theta1] = gtlib_growthTensor2Params(E1);
[smax2, smin2, theta2] = gtlib_growthTensor2Params(E2);
ungrow_smax = smax2/smax1;
ungrow_smin = smin2/smin1;
ad.data.D = gtlib_growthParams2Tensor(ungrow_smax, ungrow_smin, theta2);


D2 = zeros(3,3);
D2(1:2, 1:2) = E2(1:2,1:2)*inv(E1(1:2,1:2));
% keep it symmetric
%D2 = (D2 + D2')/2;

D2*E1
E2
ad.data.D = D2;

%[U, S, V] = svd(D2);
%[a, b, c] = gtlib_growthTensor2Params(D2)

ad.data.ellipvec = {};
setappdata(0, 'SectorCompareToolData', ad);
plotDiffGT();
return
%%
function plotDiffGT()
ad = getappdata(0, 'SectorCompareToolData');
if ~ishandle(ad.handles.gtaxes)
    figh = figure;
    set(figh, 'Position', [0 100 300 300]);
    ad.handles.gtaxes = gca;
end
ah = ad.handles.gtaxes;
gt = ad.data.D;
cla(ah); 
gtlib_plotGrowthTensor('growth_tensor', gt, 'colour', 'g', 'Parent',ah , 'linewidth', 3);
[smax, smin, theta] = gtlib_growthTensor2Params(gt);
axis(ah, 'image', 'ij');
t = sprintf('Gmax: %3.3f, Gmin: %3.3f, Theta: %3.3f', smax, smin, theta);
fprintf('%s\n', t);
title(ah, t, 'FontSize', 8);
setappdata(0, 'SectorCompareToolData', ad);
return
%%
function [gt, mu] = label2GT(B)
[x, y] = find(B >0);
X = [y, x];
mu = mean(X);
gt = fitGrowthTensor(X);
return
%%
function plotGT(ah, gt, pt)
hold(ah, 'on');
col = rand(1,3);
col = [0 1 0];
gtlib_plotGrowthTensor('growth_tensor', gt.growthTensor, 'offset', pt, 'colour', col);
return
%%
function data = parseargs(varargin)
varargin = varargin{1};

if mod(length(varargin),2) ~= 0
    % input args have not com in pairs, woe is me
    error(['Arguments to ', mfilename, ' must come param/value in pairs.'])
end
data.bimgfilenames = {};
data.imgfilenames = {};
for i=1:2:length(varargin)
    switch lower(varargin{i})
        case 'bimgfilenames'
            data.bimgfilenames = varargin{i+1};
        case 'imgfilenames'
            data.imgfilenames = varargin{i+1};
        otherwise
            error(['Unknown parameter name passed to ', mfilename, '.  Name was ' varargin{i}])
    end
end
if length(data.bimgfilenames) ~= length(data.imgfilenames)
    error('Number of binary images must match number of rgb images');
end
if isempty(data.bimgfilenames)
    error('Number of binary images must be >0');
end
return;
