% IPLOT provides an intelligent plotting tool for LTPDA.
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
% DESCRIPTION: IPLOT provides an intelligent plotting tool for LTPDA.
%
% CALL:               hfig = iplotyy (a1,a2,pl)
%              [hfig, hax] = iplotyy (a1,a2,pl)
%         [hfig, hax, hli] = iplotyy (a1,a2,pl)
%
% INPUTS:      pl  - a parameter list
%              a1  - input analysis object for left y-axis
%              a2  - input analysis object for right y-axis
%
% NOTE: the two input AOs must be the same data type.
%
% OUTPUTS:     hfig - handles to figures
%              hax  - handles to axes
%              hli  - handles to lines
%
% <a href="matlab:utils.helper.displayMethodInfo('ao', 'iplotyy')">Parameters Description</a>
%
% VERSION:     $Id: iplotyy.m,v 1.14 2011/04/08 08:56:15 hewitson Exp $
%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

function varargout = iplotyy(varargin)

  import utils.const.*

  %% Check if this is a call for parameters
  if utils.helper.isinfocall(varargin{:})
    varargout{1} = getInfo(varargin{3});
    return
  end

  utils.helper.msg(msg.PROC3, 'running %s/%s', mfilename('class'), mfilename);

  % Collect input variable names
  in_names = cell(size(varargin));
  for ii = 1:nargin,in_names{ii} = inputname(ii);end

  % Check inputs
  if nargin ~= 2 && nargin ~= 3
    error('### Incorrect inputs');
  end

  % Collect arrays
  if nargin >= 2
    a1 = varargin{1};
    a2 = varargin{2};
  end
  if ~isa(a1, 'ao') || ~isa(a2, 'ao')
    error('### Please input two AOs followed by plists');
  end

  % Collect plists
  if nargin >= 3
    pl = parse(varargin{3:end}, getDefaultPlist);
  else
    pl = getDefaultPlist;
  end

  % Check size of input arrays
  if numel(a1) ~= numel(a2) || numel(a1) ~= 1
    error('### Input two AOs.');
  end

  % get data type of a1
  dtype1 = class(a1.data);
  % get data type of a2
  dtype2 = class(a2.data);
  % check two arrays
  if ~strcmp(dtype1, dtype2)
    error('### The two input AOs should contain the same data type.');
  end

  dtype = dtype1;

  %% Now plot all the objects on separate figures

  switch dtype
    case 'fsdata'
      [hfig, hax, hli] = xy_plot(a1,a2,pl);
    case 'tsdata'
      [hfig, hax, hli] = xy_plot(a1,a2,pl);
    case 'cdata'
      error('### Currently unsupported');
    case 'xydata'
      [hfig, hax, hli] = xy_plot(a1,a2,pl);
    otherwise
      error('### Unsupported data type: %s', dtype);
  end

  %% Deal with outputs
  if nargout == 1
    varargout{1} = hfig;
  end
  if nargout == 2
    varargout{1} = hfig;
    varargout{2} = hax;
  end
  if nargout == 3
    varargout{1} = hfig;
    varargout{2} = hax;
    varargout{3} = hli;
  end

  if nargout > 3
    error('### Incorrect number of outputs');
  end

end

%--------------------------------------------------------------------------
%  XY plot
%--------------------------------------------------------------------------
function [hf, ha, hl] = xy_plot(a1,a2,pl)

  switch class(a1.data)
    case 'fsdata'
      pl = parse(pl, getDefaultPlist('Frequency-series plot'));
      XLabelString = 'Frequency';
      x1 = a1.data.getX;
      y1 = a1.data.getY;
      x2 = a2.data.getX;
      y2 = a2.data.getY;
      % Title string
      titleString = '';
    case 'tsdata'
      pl = parse(pl, getDefaultPlist('Time-series plot'));
      XLabelString = 'Time';
      % Collect T0s
      T0(1) = inf;
      if a1.data.t0.utc_epoch_milli/1000 < T0(1)
        T0(1) = floor(a1.data.t0.utc_epoch_milli/1000);
      end
      T0(2) = inf;
      if a2.data.t0.utc_epoch_milli/1000 < T0(2)
        T0(2) = floor(a2.data.t0.utc_epoch_milli/1000);
      end

      % deal with time-offsets
      toff(1)    = a1.data.t0.utc_epoch_milli/1000 - T0(1);
      toff(2)    = a2.data.t0.utc_epoch_milli/1000 - T0(1);
      torigin(1) = time(T0(1));
      torigin(2) = time(T0(2));
      % need t0 offset for this time-series
      x1 = a1.data.getX + toff(1);
      y1 = a1.data.getY;
      x2 = a2.data.getX + toff(2);
      y2 = a2.data.getY;
      % Title string
      titleString = sprintf('Time origin: %s', char(torigin(1)));
    case 'xydata'
      pl = parse(pl, getDefaultPlist('X-Y plot'));
      XLabelString = 'X';
      x1 = a1.data.getX;
      y1 = a1.data.getY;
      x2 = a2.data.getX;
      y2 = a2.data.getY;
      % Title string
      titleString = '';
  end
  
  % Parameters
  colL   = find(pl, 'LeftColor');
  colR   = find(pl, 'RightColor');
  styleL = find(pl, 'LeftLineStyle');
  styleR = find(pl, 'RightLineStyle');
  yscaleL = find(pl, 'LeftYScale');
  xscaleL = find(pl, 'LeftXScale');
  yscaleR = find(pl, 'RightYScale');
  xscaleR = find(pl, 'RightXScale');
  
  pltfcn = 'plot';
  if strcmp(xscaleL, 'log') && strcmp(xscaleR, 'log') && ...
     strcmp(yscaleL, 'log') && strcmp(yscaleR, 'log')
    pltfcn = 'loglog';
  end
  if strcmp(xscaleL, 'lin') && strcmp(xscaleR, 'lin') && ...
     strcmp(yscaleL, 'log') && strcmp(yscaleR, 'log')
    pltfcn = 'semilogy';
  end
  if strcmp(xscaleL, 'log') && strcmp(xscaleR, 'log') && ...
     strcmp(yscaleL, 'lin') && strcmp(yscaleR, 'lin')
    pltfcn = 'semilogx';
  end
  
  % Make a new figure
  hf = figure;

  % Plot
  [ha,H1,H2] = plotyy(x1,y1,x2,y2,pltfcn);
  hl = [H1 H2];
  % Set grid
  grid(ha(1), 'on');
  grid(ha(2), 'on');

  % Line color
  set(H1, 'Color', colL);
  set(H2, 'Color', colR);
  % Line style
  set(H1, 'LineStyle', styleL);
  set(H2, 'LineStyle', styleR);
  % Axis color
  set(ha(1), 'XColor', 'k', 'YColor', colL);
  set(ha(2), 'XColor', 'k', 'YColor', colR);
  % Axis scales
  set(ha(1), 'YScale', yscaleL);
  set(ha(1), 'XScale', xscaleL);
  set(ha(2), 'YScale', yscaleR);
  set(ha(2), 'XScale', xscaleR);
  
  % Set y label 1
  ylabel(ha(2), [fixlabel(utils.plottools.label(a2.name)) ...
                 ' ' ...
                 fixlabel(char(a1.data.yunits)) ...
                 ]);
  % Set y label 2
  ylabel(ha(1), [fixlabel(utils.plottools.label(a1.name)) ...
                 ' ' ...
                 fixlabel(char(a2.data.yunits))...
                 ]);
  % Set x label
  xlabel(ha(1), [XLabelString ' ' char(a1.data.xunits)]);

  % Print title
  title(titleString);
  
end % End fs_plot


%--------------------------------------------------------------------------
% Get Info Object
%--------------------------------------------------------------------------
function ii = getInfo(varargin)
  if nargin == 1 && strcmpi(varargin{1}, 'None')
    sets = {};
    pl   = [];
  elseif nargin == 1&& ~isempty(varargin{1}) && ischar(varargin{1})
    sets{1} = varargin{1};
    pl = getDefaultPlist(sets{1});
  else
    sets = {'Time-series Plot', 'Frequency-series Plot', 'Y Plot', 'X-Y Plot', '3D Plot'};
    % get plists
    pl(size(sets)) = plist;
    for k = 1:numel(sets)
      pl(k) =  getDefaultPlist(sets{k});
    end
  end
  % Build info object
  ii = minfo(mfilename, 'ao', 'ltpda', utils.const.categories.output, '$Id: iplotyy.m,v 1.14 2011/04/08 08:56:15 hewitson Exp $', sets, pl);
  ii.setModifier(false);
  ii.setArgsmin(2);
  ii.setOutmin(0);
end

%--------------------------------------------------------------------------
% Get Default Plist
%--------------------------------------------------------------------------
function plout = getDefaultPlist(set)
  persistent pl;
  persistent lastset;
  if exist('pl', 'var')==0 || isempty(pl) || ~strcmp(lastset, set)
    pl = buildplist(set);
    lastset = set;
  end
  plout = pl;
end

function out = buildplist(varargin)

  set = '';
  if nargin == 1
    set = varargin{1};
  end
  
  % Get the LTPDA color set for lines
  colors = getappdata(0,'ltpda_default_plot_colors');

  out = plist(...
    'LeftColor', colors{1}, ...
    'RightColor', colors{2}, ...
    'LeftLineStyle', '-', ...
    'RightLineStyle', '-');

  switch lower(set)
    case 'frequency-series plot'
      out.append(...
        'LeftYScale', 'log', ...
        'RightYScale', 'log', ...
        'LeftXScale', 'log', ...
        'RightXScale', 'log');
    case 'time-series plot'
      out.append(...
        'LeftYScale', 'lin', ...
        'RightYScale', 'lin', ...
        'LeftXScale', 'lin', ...
        'RightXScale', 'lin');
    case 'x-y plot'
      out.append(...
        'LeftYScale', 'lin', ...
        'RightYScale', 'lin', ...
        'LeftXScale', 'lin', ...
        'RightXScale', 'lin');
    case '3d plot'
    case 'y plot'
    otherwise
      error('### Unknown set [%s]', set);
  end
end


% Perform some substitutions on the labels
function ss = fixlabel(ss)

  wasCell = true;
  if ~iscell(ss)
    ss = {ss};
    wasCell = false;
  end

  for kk=1:numel(ss)
    s = ss{kk};
  
    % Replace all ^(...) with ^{...}
    j = 1;
    while j<numel(s)
      if strcmp(s(j:j+1), '^(')
        % find next )
        for k=1:numel(s)-j+1
          if s(j+k) == ')'
            s(j+1) = '{';
            s(j+k) = '}';
            break;
          end
        end
      end
      j = j + 1;
    end
    % Replace all .^ with ^
    s = strrep(s, '.^', '^');

    % reduce size
    if length(s) > 25
      addStr = '...';
    else
      addStr = '';
    end
    ssize = min(25, length(s));
    s = [s(1:ssize) addStr];
    
    ss(kk) = {s};
  end


  if ~wasCell
    ss = ss{1};
  end
  
end
