function varargout = maingui2(varargin)
% maingui2 M-file for maingui2.fig
%      maingui2, by itself, creates a new maingui2 or raises the existing
%      singleton*.
%
%      H = maingui2 returns the handle to a new maingui2 or the handle to
%      the existing singleton*.
%
%      maingui2('CALLBACK',hObject,eventData,handles,...) calls the local
%      function named CALLBACK in maingui2.M with the given input arguments.
%
%      maingui2('Property','Value',...) creates a new maingui2 or raises the
%      existing singleton*.  Starting from the left, property value pairs are
%      applied to the GUI before maingui2_OpeningFunction gets called.  An
%      unrecognized property name or invalid value makes property application
%      stop.  All inputs are passed to maingui2_OpeningFcn via varargin.
%
%      *See GUI Options on GUIDE's Tools menu.  Choose "GUI allows only one
%      instance to run (singleton)".
%
% See also: GUIDE, GUIDATA, GUIHANDLES

% Edit the above text to modify the response to help maingui2

% Last Modified by GUIDE v2.5 18-Dec-2007 22:49:27

dbstop if error;
dbstop if warning;

% Begin initialization code - DO NOT EDIT
gui_Singleton = 1;
gui_State = struct('gui_Name',       mfilename, ...
                   'gui_Singleton',  gui_Singleton, ...
                   'gui_OpeningFcn', @maingui2_OpeningFcn, ...
                   'gui_OutputFcn',  @maingui2_OutputFcn, ...
                   'gui_LayoutFcn',  [] , ...
                   'gui_Callback',   []);
if nargin && ischar(varargin{1})
    gui_State.gui_Callback = str2func(varargin{1});
end

if nargout
    [varargout{1:nargout}] = gui_mainfcn(gui_State, varargin{:});
else
    gui_mainfcn(gui_State, varargin{:});
end
% End initialization code - DO NOT EDIT


% --- Executes just before maingui2 is made visible.
function maingui2_OpeningFcn(hObject, eventdata, handles, varargin)
% This function has no output args, see OutputFcn.
% hObject    handle to figure
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)
% varargin   command line arguments to maingui2 (see VARARGIN)

% Choose default command line output for maingui2
handles.output = hObject;

% param used for count the number of saved images.
handles.savecount = 0;

% Update handles structure
guidata(hObject, handles);

% UIWAIT makes maingui2 wait for user response (see UIRESUME)
% uiwait(handles.figure1);


% --- Outputs from this function are returned to the command line.
function varargout = maingui2_OutputFcn(hObject, eventdata, handles) 
% varargout  cell array for returning output args (see VARARGOUT);
% hObject    handle to figure
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)

% Get default command line output from handles structure
varargout{1} = handles.output;

% --- Executes on button press in load_data.
function load_data_Callback(hObject, eventdata, handles)
% hObject    handle to load_data (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)
[fname, pname, idx] = uigetfile({'graph*kstarno.mat', 'Data file (*.mat)'}, 'Open file');
if idx > 0
    load(fname);
    % 0. select the sufficient statistics which are in the model
    switch get(handles.select_variable, 'Value')
        case 1          % edge v.s. triangle
            A = triMat;
        otherwise       % edge v.s. 2-star
            A = starMat';
    end

    % 1. get the empirical distribution of sufficient statistic, for
    % example, edges and triangles.
    ind = find(A~=0);
    x = zeros(length(ind), 1);
    y = zeros(length(ind), 1);
    f = zeros(length(ind), 1);
    for i=1:length(ind)
        [j, k] = ind2sub(size(A), ind(i));
        x(i) = k-1;
        y(i) = j-1;
        f(i) = A(j,k);
    end
      
    % 2. store the points and frequencies in the handles
    handles.x = x;
    handles.y = y;
    handles.f = f;
    guidata(hObject, handles);
    
    % 3. draw the entropy plot
    draw_entropy(handles);    
end



% --- Executes on button press in select_point.
function select_point_Callback(hObject, eventdata, handles)
% hObject    handle to select_point (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)

% 0. get the data and the parameters from the input
[t3, t0] = ginput(1);
x = handles.x;
y = handles.y;
f = handles.f;

% 1. draw the CDF
draw_cdf(handles, t0, t3);

% % 2. save the current figure if you want to
% fname = ['xxxx', num2str(handles.savecount,'%04d'), '.bmp'];
% save_frame(handles, fname);
% handles.savecount = handles.savecount + 1;
% guidata(hObject, handles);


% --- Executes on selection change in select_variable.
function select_variable_Callback(hObject, eventdata, handles)
% hObject    handle to select_variable (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)

% Hints: contents = get(hObject,'String') returns select_variable contents as cell array
%        contents{get(hObject,'Value')} returns selected item from select_variable


% --- Executes during object creation, after setting all properties.
function select_variable_CreateFcn(hObject, eventdata, handles)
% hObject    handle to select_variable (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    empty - handles not created until after all CreateFcns called

% Hint: popupmenu controls usually have a white background on Windows.
%       See ISPC and COMPUTER.
if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
    set(hObject,'BackgroundColor','white');
end




% --- Executes on button press in copy_out.
function copy_out_Callback(hObject, eventdata, handles)
% hObject    handle to copy_out (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)
figure;
copyobj(handles.axes1, gcf);
view(-150, 25);


% -------------------------------- %
function save_frame(handles, fname)

% FUNCTION TO SAVE THE FIGURE TO AN IMAGE FILE

F = getframe(handles.figure1);
[X, map] = frame2im(F);
imwrite(X, fname);


% -------------------------------- %
function save_movie(ncount)

% FUNCTION TO MAKE A MOVIE FROM A SET OF IMAGES

mov = avifile('xxxx.avi', 'quality', 100, 'fps', 10, 'compression', 'Cinepak');
for k=1:ncount
    im = imread(['xxxx', num2str(k,'%04d'), '.bmp']);
    F = im2frame(im);
    mov = addframe(mov,F);
end
mov = close(mov);


% -------------------------------- %
function draw_cdf(handles, t0, t3)

% 0. get the sufficient statistics and the frequecies from the handles
x = handles.x;
y = handles.y;
f = handles.f;

% 1.1. calculate the probabilities, not normalized
p = exp(t0.*x + t3.*y) .* f;
p = p ./ max(p);

% 1.2. calculate the mean of the distribution
a = sum(p);
b = sum( p .* x ) / a;
c = sum( p .* y ) / a;

% 2.1. draw the point on the entropy plot
axes(handles.axes1);
hold on;
delete(findobj('Marker', 'o'));
delete(findobj('Marker', '+'));
plot(t3, t0, 'Color', 'k', 'Marker', '+', 'MarkerSize', 18);
plot(t3, t0, 'Color', 'k', 'Marker', 'o', 'MarkerFaceColor', 'w');

% 2.2. draw the CDF 
axes(handles.axes2);
hold off;
for i=1:length(x)
    plot(x(i), y(i), 'o', 'MarkerFaceColor', (1-p(i))*ones(1,3));
    % text(x(i)+0.2, y(i)+0.2, num2str(p(i)/sum(p), '%.2f'));
    hold on;
end
k = convhull(x, y);     % get convex hull of the set of points
plot(x(k), y(k), 'g-');
title(['Probability plot with param \theta=', num2str(t0,'%.1f'), '; \tau=', num2str(t3,'%.1f')]);
plot(b, c, 'r*', 'MarkerSize', 10); 
xlabel('number of edges'); 
switch get(handles.select_variable, 'Value')
    case 1
        ylabel('number of triangles');
    otherwise
        ylabel('number of 2-stars');
end


% -------------------------------- %
function draw_entropy(handles)

% 0.1. get the points and frequencies stored in the handles
x = handles.x;
y = handles.y;
f = handles.f;

% 0.2. set the range of parameters
%t0 = [-10:0.1:30];
%t3 = [-30:0.1:10];
t0 = [-10:0.1:25];
t3 = [-25:0.1:10];


% 1. calculate the entropy
e = [];
for i=1:length(t0)
    for j=1:length(t3)
        a = sum( exp(t0(i).*x + t3(j).*y) .* f );
        e(i,j) = - sum( exp(t0(i).*x + t3(j).*y) ./ a  .* (t0(i).*x + t3(j).*y - log(a)) .* f );
    end
end

% set to zero NA's
e(isnan(e))=0;

% 2. draw the entropy plot
[u, v] = meshgrid(t3, t0);
axes(handles.axes1);
hold off;
surfc(u, v, e);
shading interp;
view(90, -90);
title('Entropy plot');
switch get(handles.select_variable, 'Value')
    case 1
        xlabel('triangle param (\tau)');
    otherwise
        xlabel('2-star param (\tau)');
end     
ylabel('edge param (\theta)');

% 3. draw the normal fan of the convex polytope of the sufficient
% statistics
k = convhull(x, y);     % get the convex hull of the set of points
slp = diff([x(k), y(k)], 1, 1);
slp(:,1) = - slp(:,1);
for i=1:size(slp,1)
    xend = t3(end)*(sign(slp(i,1))*0.5+0.5) + ...
        t3(1)*(0.5-sign(slp(i,1))*0.5);
    yend = t0(end)*(sign(slp(i,2))*0.5+0.5) + ...
        t0(1)*(0.5-sign(slp(i,2))*0.5);
    if slp(i,1)/xend>=slp(i,2)/yend
        slp(i,:) = [xend, xend*slp(i,2)/slp(i,1)];
    else
        slp(i,:) = [yend*slp(i,1)/slp(i,2), yend];
    end
end
axes(handles.axes1);
for i=1:size(slp,1)
    line([0, slp(i,1)], [0, slp(i,2)], 'Color', [1,1,1], ...
        'LineStyle', '--', 'LineWidth', 2);
end

% % 4. save the entropy and cdf plots when the parameters are on the
% % ridges of the entropy    
% imax = 20;
% ncount = 1;
% for k=1:size(slp,1)
%     for i=1:imax
%         draw_cdf(handles, slp(k,2)*(i-1)/imax, slp(k,1)*(i-1)/imax);
%         fname = ['xxxx', num2str(ncount,'%04d'), '.bmp'];
%         save_frame(handles, fname);
%         ncount = ncount + 1;
%     end
% end
