function gsp_plot_signal(G,signal,param)
%GSP_PLOT_SIGNAL  Plot a graph signal in 2D or 3D
%   Usage:  gsp_plot_signal(G,signal);
%           gsp_plot_signal(G,signal,param);
%
%   Input parameters:
%         G          : Graph structure.
%         signal     : Graph signal.
%         param      : Optional variable containing additional parameters.
%   Output parameters:
%         none
%
%   'gsp_plot_signal(G,f)' plots a graph signal in 2D or 3D, using the adjacency 
%   matrix (G.A), the plotting coordinates (G.coords), the 
%   coordinate limits (G.plotting.limits), the edge width (G.plotting.edge_width), the 
%   edge color (G.plotting.edge_color), the edge style (G.plotting.edge_style), and the 
%   vertex size (G.vertex_size).
%
%   Example:
%
%          G = gsp_ring(15);
%          f = sin((1:15)*2*pi/15);
%          gsp_plot_signal(G,f)
%
%   Additional parameters
%   ---------------------
%    param.show_edges : Set to 0 to only draw the vertices. (default G.Ne < 10000 )
%    param.cp         : Camera position for a 3D graph.
%    param.vertex_size*: Size of circle representing each signal component.
%    param.colorbar   : Set to 0 to not show the colorbar
%    param.climits    : Limits of the colorbar
%    param.vertex_highlight*: Vector of indices of vertices to be highlighted
%    param.bar        : 1 Display bar for the graph. 0 Display color
%                          points. (default 0);
%    param.bar_width  : Width of the bar (default 1)
%    param.clear      : Clear axes (default 1)
%
%   See also: gsp_plot_graph gsp_plot_signal_spectral
%
%
%   Url: https://epfl-lts2.github.io/gspbox-html/doc/plotting/gsp_plot_signal.html

% Copyright (C) 2013-2016 Nathanael Perraudin, Johan Paratte, David I Shuman.
% This file is part of GSPbox version 0.7.5
%
% This program is free software: you can redistribute it and/or modify
% it under the terms of the GNU General Public License as published by
% the Free Software Foundation, either version 3 of the License, or
% (at your option) any later version.
%
% This program 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 General Public License for more details.
%
% You should have received a copy of the GNU General Public License
% along with this program.  If not, see <http://www.gnu.org/licenses/>.

% If you use this toolbox please kindly cite
%     N. Perraudin, J. Paratte, D. Shuman, V. Kalofolias, P. Vandergheynst,
%     and D. K. Hammond. GSPBOX: A toolbox for signal processing on graphs.
%     ArXiv e-prints, Aug. 2014.
% http://arxiv.org/abs/1408.5781


% Author :  Nathanael Perraudin, David I Shuman
% Testing: test_plotting

  

% Handling optional inputs
if nargin < 3
   param = struct;
end


if ~numel(G.coords)
    error('There is no coordinates associated to this graph!');
end

if sum(abs(imag(signal(:))))>1e-10
   error('GSP_PLOT_SIGNAL: can not display complex signal') 
end

signal = real(signal);

if ~isfield(param,'show_edges'), param.show_edges = G.Ne < 5000; end
if ~isfield(param,'bar'), param.bar = 0; end
if ~isfield(param,'clear'), param.clear = 1; end
if ~isfield(param,'bar_width'), param.bar_width = 1; end
if ~isfield(param,'vertex_highlight'), param.vertex_highlight = 0; end
if ~isfield(param,'vertex_size'), 
    if ~isfield(G.plotting,'vertex_size')
        param.vertex_size=500; 
    else
        param.vertex_size=G.plotting.vertex_size*10;
    end
else
    param.vertex_size = param.vertex_size*10; 
end

if ~isfield(param,'colorbar'), param.colorbar = 1; end
if ~isfield(param,'cp')
    if isfield(G.plotting, 'cp')
       param.cp = G.plotting.cp; 
    else
       param.cp=[-6   -3  160]; 
    end
    
end

if ~isfield(G,'coords')
    error('GSP_PLOT_SIGNAL: Cannot plot a graph without coordinate!')
end

% Clear axes
if param.clear
    cla;
end
G = gsp_graph_default_plotting_parameters(G);

hold on;


if param.show_edges
    gsp_plot_edges(G,param);
end

if size(G.coords,2) == 2
    if param.bar
        ind = find(signal < 0);
        plot3([G.coords(ind,1)'; G.coords(ind,1)'],...
            [G.coords(ind,2)'; G.coords(ind,2)'],...
            [zeros(1,length(ind)); reshape(signal(ind),1,[])],...
            G.plotting.edge_style, 'LineWidth',param.bar_width,'color','k');
        ind = find(signal >= 0);
        plot3([G.coords(ind,1)'; G.coords(ind,1)'],...
            [G.coords(ind,2)'; G.coords(ind,2)'],...
            [zeros(1,length(ind)); reshape(signal(ind),1,[])],...
            G.plotting.edge_style, 'LineWidth',param.bar_width,'color','b');
        if any(param.vertex_highlight > 0)
            vh = param.vertex_highlight;
            plot3([G.coords(vh,1)'; G.coords(vh,1)'],...
                [G.coords(vh,2)'; G.coords(vh,2)'],...
                [zeros(1,length(vh)); reshape(signal(vh),1,[])],...
                G.plotting.edge_style, 'LineWidth',2*param.bar_width,'color','m');

        end   
    else
        scatter(G.coords(:,1),G.coords(:,2), ...
            param.vertex_size, signal, '.');
        if any(param.vertex_highlight > 0)
            vh = param.vertex_highlight;
            scatter(G.coords(vh,1),G.coords(vh,2), ...
                param.vertex_size/3, 'ok','LineWidth',3);

        end   
    end


else %if size(G.coords,2) == 3
    scatter3(G.coords(:,1),G.coords(:,2),G.coords(:,3),...
                    param.vertex_size,signal,'.');
    if any(param.vertex_highlight > 0)
        vh = param.vertex_highlight;
        scatter3(G.coords(vh,1),G.coords(vh,2),G.coords(vh,3), ...
            param.vertex_size/3, 'ok');

    end             

end


axis(G.plotting.limits);

if size(G.coords,2)==3 || param.bar
    set(gca,'CameraPosition',param.cp);
end

if ~param.bar
    if isfield(param, 'climits')
        caxis(param.climits);
    %else
        % no need to do anything, the following happens anyway!
        %set(gca,'CLimMode','auto');
    end

    if param.colorbar
        colorbar;
    end
end
colormap(jet)
axis off;
hold off;

% TODO: use special presets of the following style for more graphs:
if isfield(G, 'type')
    if strcmp(G.type, 'non_uniform') ||...
       strcmp(G.type, 'sub-non_uniform') ||...
       strcmp(G.type, 'non_uniform_patch') ||...
       strcmp(G.type, 'sub-non_uniform_patch')
        axis equal; axis tight;% axis on;
    end
end
end

