function [data,fig] = analysis_plot (data,column,titlename,filename,prompt_for_label)
% analysis_plot: generates the analysis plot
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% build basic input "plotdata" structure

plotdata.fig_name='GPS & ACCEL Analysis';
plotdata.title=titlename;
plotdata.filename=filename;
plotdata.window='normal';
plotdata.auto_print=data.config.print;
plotdata.auto_save=2*data.config.file_save;
plotdata.auto_close=data.config.auto_close;
plotdata.path=data.current_path;
%plotdata.errfid=data.config.errfid;

% if only accel data is loaded turn off position display
if (data.GPS.loaded==0)
   data.config.disp_position=0;
elseif ((data.GPS.loaded==1)&(isempty(data.GPS.position)==1))
   data.config.disp_position=0;
end;

% determine plot type
if ((data.config.single_axes==0)&(data.config.disp_position==0))
   plotdata.plot_type=1;
elseif ((data.config.single_axes==1)&(data.config.disp_position==0))
   plotdata.plot_type=2;
elseif ((data.config.single_axes==0)&(data.config.disp_position==1))
   plotdata.plot_type=4;
elseif ((data.config.single_axes==1)&(data.config.disp_position==1))
   plotdata.plot_type=5;
else
   err_text='What the hell did you do to get this!?!? (ref: analysis plot 1)';
   fault(err_text,data);
   return;
end;

% Y-label (single axes plotting only) - prompt for label
if ((plotdata.plot_type==2)|(plotdata.plot_type==5))
   if (prompt_for_label==1)
      if (isempty(data.config.single_label)==0)
         current_text={data.config.single_label};
      else
         current_text={'Y-Axes Label'};
      end;
      AddOpts.Resize='off';
      AddOpts.WindowStyle='modal';
      AddOpts.Interpreter='tex';
      prompt={'Label for the Y-Axes:'};
      title='Y-Axes Label';
      answer=inputdlg(prompt,title,1,current_text,AddOpts);
      if (isempty(answer)==0)
         plotdata.yaxes_label=char(answer);
         data.config.single_label=plotdata.yaxes_label;
      elseif (isempty(answer)==1)
         return;
      end;
   else
      plotdata.yaxes_label=data.config.single_label;
   end;
end;

% build plot input data
[plotdata,data] = build_time_plots (plotdata,data,column);

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% generate the display map (if needed)

% generate track display map
if ((plotdata.plot_type==4)|(plotdata.plot_type==5))
   % add track outline
   plotdata.display.trail.array=[data.GPS.position(:,1)  data.GPS.position(:,8)  data.GPS.position(:,9)];
   plotdata.display.trail.color_inactive='b';
   plotdata.display.trail.color_active='r';
   plotdata.display.trail.linetype_active='-';
   plotdata.display.trail.linetype_inactive=':';
   plotdata.display.trail.active_scale=10;
   [j01r,j01c]=find(isnan(plotdata.display.trail.array)==1);       % remove NaN's
   if (isempty(j01r)==0)
      plotdata.display.trail.array(j01r,:)=[];
   end;
   % DO A CHECK & IF THERE WAS A GPS OUTAGE, INSERT TIME: "INF" & COORDINATES: "NAN"
   dTime=plotdata.display.trail.array(2:end,1)-plotdata.display.trail.array(1:end-1,1);
   j02=find(dTime>1);
   if (isempty(j02)==0)
      junk_mat=[];
      last_value=1;
      for (i=1:size(j02,1))
         new_data=plotdata.display.trail.array(last_value:j02(i),:);
         junk_mat(end+1:size(junk_mat,1)+size(new_data,1),:)=new_data;
         if (size(new_data,2)==3)
            junk_mat(end+1,:)=[inf nan nan];
         elseif (size(new_data,2)==4)
            junk_mat(end+1,:)=[inf nan nan nan];
         end;
         last_value=j02(i)+1;
         new_data=[];
      end;
      new_data=plotdata.display.trail.array(last_value:end,:);
      junk_mat(end+1:size(junk_mat,1)+size(new_data,1),:)=new_data;
      plotdata.display.trail.array=junk_mat;
   end;
   
   % decimate map data to 1 second positions
   int_seconds=find(plotdata.display.trail.array(:,1)==round(plotdata.display.trail.array(:,1)));
   if (size(int_seconds,1)<0.05*size(plotdata.display.trail.array(:,1),1))
      int_seconds=find(plotdata.display.trail.array(:,1)==round(plotdata.display.trail.array(:,1))+0.05);
   end;
   if (size(int_seconds,1)<0.05*size(plotdata.display.trail.array(:,1),1))
      fprintf('Problem decimating to integer seconds on position trail!  Skipping decimation.\n');
   else
      breaks=find(isinf(plotdata.display.trail.array(:,1))==1);
      keep_rows=unique(sort([int_seconds;breaks-1;breaks;breaks+1]));
      plotdata.display.trail.array=plotdata.display.trail.array(keep_rows,:);
   end;
   
   % add background
   plotdata.display.background.array{1}=[];
   plotdata.display.background.color{1}='k';
   plotdata.display.background.linetype{1}='-';
   
   % limits
   plotdata.display.xaxes.label=data.GPS.field_names{7};
   plotdata.display.yaxes.label=data.GPS.field_names{8};
   plotdata.display.xaxes.limits=[floor(min(data.GPS.position(:,8)))  ceil(max(data.GPS.position(:,8)))];
   plotdata.display.yaxes.limits=[floor(min(data.GPS.position(:,9)))  ceil(max(data.GPS.position(:,9)))];
   plotdata.display.xaxes.ticks=[];
   plotdata.display.yaxes.ticks=[];
   plotdata.display.xaxes.prec=0;
   plotdata.display.yaxes.prec=0;
   
   % verify that there is a trail to plot
   if (isempty(plotdata.display.trail.array)==1)
      err_text='There is no trail information to be plotted, an analysis plot cannot be generated!';
      fault(err_text,data);
      return;
   end;
   
   if (size(plotdata.display.trail.array,1)<=1)
      plotdata.plot_type=plotdata.plot_type-3;
   end;
end;

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% pass plotdata to "zplot"

fig=zplot(plotdata);

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
return;

function [plotdata,data] = build_time_plots (plotdata,data,column)
% build_time_plots: generates the time plots
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% build plot input data

% plot colors
colour{1}='b';
colour{2}='g';
colour{3}='r';
colour{4}='c';
colour{5}='m';

% plot linetypes
linetype{1}='-';
linetype{2}='-.';
linetype{3}=':';
linetype{4}='--';

% set x-axes
if (data.config.field_location(column(1),1)==7)
   % set x-axis limits, ticks, precision, & label
   plotdata.x_label_type=0;
   plotdata.xaxes.label='Elevation (degrees)';
   plotdata.xaxes.limits=[0 90];
   plotdata.xaxes.ticks=10;
   plotdata.xaxes.prec=0;
elseif (data.config.field_location(column(1),1)==10)
   plotdata.plot_scale=3;
   plotdata.x_label_type=0;
   plotdata.xaxes.label=data.temp.PSD.x_label;
   plotdata.xaxes.limits=data.temp.PSD.x_limits(1:2);
   plotdata.xaxes.ticks=[];
   plotdata.xaxes.prec=0;
elseif (data.config.field_location(column(1),1)==11)
   plotdata.plot_scale=2;
   plotdata.x_label_type=0;
   plotdata.xaxes.label=data.temp.AMP.x_label;
   plotdata.xaxes.limits=data.temp.AMP.x_limits(1:2);
   plotdata.xaxes.ticks=data.temp.AMP.x_limits(3);
   plotdata.xaxes.prec=0;
elseif (data.GPS.loaded==0)
   % set x-axis limits, ticks, precision, & label
   plotdata.x_label_type=0;
   plotdata.xaxes.label='Data Time (seconds)';
   plotdata.xaxes.limits=[data.config.time_range(1)  data.config.time_range(end)];
   plotdata.xaxes.ticks=[];
   plotdata.xaxes.prec=0;
else
   % set x-axis limits, ticks, precision, & label
   plotdata.x_label_type=4;
   plotdata.time_zone=data.GPS.time_zone;
   plotdata.dAT=data.GPS.dAT;
   plotdata.gps_week=data.GPS.week;
   if (plotdata.time_zone==0)
      plotdata.xaxes.label=sprintf('GPS seconds (week %.f) & UTC Time',plotdata.gps_week);
   else
      plotdata.xaxes.label=sprintf('GPS seconds (week %.f) & Local Time (UTC + %.0f)',plotdata.gps_week,plotdata.time_zone);
   end;
   plotdata.xaxes.limits=[data.config.time_range(1)  data.config.time_range(end)];
   plotdata.xaxes.ticks=[];
   plotdata.xaxes.prec=0;
end;

% build plot data
maximum=[];
minimum=[];
ticks=[];
precision=[];
plots=size(column,2);
for (i=1:plots)
   % y-axes data labels (multi-axes) or legend text (single axes)
   plotdata.yaxes{i}.label=data.config.field_names{column(i)};
   
   % plot variables
   if (data.config.field_location(column(i),1)==1)
      xdata=data.accel.accel(:,1);
      ydata=data.accel.accel(:,data.config.field_location(column(i),2));
   elseif (data.config.field_location(column(i),1)==2)
      xdata=data.GPS.position(:,1);
      if (min(data.config.field_location(column(i),:)==[2 7 1])==1)
         ydata=data.GPS.position(:,data.config.field_location(column(i),2))-4;
      else
         ydata=data.GPS.position(:,data.config.field_location(column(i),2));
      end;
   elseif (data.config.field_location(column(i),1)==3)
      xdata=data.GPS.observables.time(:,1);
      ydata=data.GPS.observables.time(:,data.config.field_location(column(i),2));
   elseif (data.config.field_location(column(i),1)==4)
      xdata=data.GPS.observables.time(:,1);
      ydata=data.GPS.observables.SV{data.config.field_location(column(i),3)}(:,data.config.field_location(column(i),2));
   elseif (data.config.field_location(column(i),1)==5)
      xdata=data.GPS.observables.cycle_slip.slip_count(:,1);
      if (data.config.field_location(column(i),2)==1)
         ydata=data.GPS.observables.cycle_slip.slip_count(:,2);
      elseif (data.config.field_location(column(i),2)==2)
         ydata=data.GPS.observables.cycle_slip.slip_count(:,3);
      end;
   elseif (data.config.field_location(column(i),1)==6)
      if (data.config.field_location(column(i),2)==1)
         xdata=data.GPS.observables.cycle_slip.L1_valid(:,1);
         ydata=data.GPS.observables.cycle_slip.L1_valid(:,2);
      elseif (data.config.field_location(column(i),2)==2)
         if (isempty(data.GPS.observables.cycle_slip.L1_slip)==1)
            xdata=[inf;inf];
            ydata=[inf;inf];
         else
            xdata=data.GPS.observables.cycle_slip.L1_slip(:,1);
            ydata=data.GPS.observables.cycle_slip.L1_slip(:,2);
         end;
      elseif (data.config.field_location(column(i),2)==3)
         xdata=data.GPS.observables.cycle_slip.L2_valid(:,1);
         ydata=data.GPS.observables.cycle_slip.L2_valid(:,2);
      elseif (data.config.field_location(column(i),2)==4)
         if (isempty(data.GPS.observables.cycle_slip.L2_slip)==1)
            xdata=[inf;inf];
            ydata=[inf;inf];
         else
            xdata=data.GPS.observables.cycle_slip.L2_slip(:,1);
            ydata=data.GPS.observables.cycle_slip.L2_slip(:,2);
         end;
      end;
   elseif (data.config.field_location(column(i),1)==7)
      if (data.config.field_location(column(i),2)==1)
         if (isempty(data.GPS.observables.cycle_slip.L1_slip)==1)
            xdata=[inf;inf];
            ydata=[inf;inf];
         else
            xdata=data.GPS.observables.cycle_slip.L1_slip(:,3);
            ydata=data.GPS.observables.cycle_slip.L1_slip(:,2);
         end;
      elseif (data.config.field_location(column(i),2)==2)
         if (isempty(data.GPS.observables.cycle_slip.L2_slip)==1)
            xdata=[inf;inf];
            ydata=[inf;inf];
         else
            xdata=data.GPS.observables.cycle_slip.L2_slip(:,3);
            ydata=data.GPS.observables.cycle_slip.L2_slip(:,2);
         end;
      end;
   elseif (data.config.field_location(column(i),1)==8)
      xdata=data.accel.accel(:,1);
      ydata=data.temp.accel_mag;
   elseif (data.config.field_location(column(i),1)==9)
      if (data.config.field_location(column(i),2)==1)
         xdata=data.temp.pos_dT(:,1);
         ydata=data.temp.pos_dT(:,2);
      elseif (data.config.field_location(column(i),2)==2)
         xdata=data.temp.obs_dT(:,1);
         ydata=data.temp.obs_dT(:,2);
      end;
   elseif (data.config.field_location(column(i),1)==10)
      xdata=data.temp.PSD.array{i}(:,1);
      ydata=data.temp.PSD.array{i}(:,2);
   elseif (data.config.field_location(column(i),1)==11)
      xdata=data.temp.AMP.array{i}(:,1);
      ydata=data.temp.AMP.array{i}(:,2);
   end;
   
   % remove NaN
   [j01r,j01c]=find(isnan([xdata ydata])==0);
   if (isempty(j01r)==0)
      nxdata=xdata(j01r,1);
      nxdata=xdata;
      nydata=ydata(j01r,:);
      nydata=ydata;
   end;
   
   % DO A CHECK & IF THERE WAS AN OUTAGE, INSERT "NAN"
   dTime=xdata(2:end,1)-xdata(1:end-1,1);
   j02=find(dTime>data.config.field_ranges(column(i),7));
   if (isempty(j02)==0)
      junk_mat=[];
      array=[xdata  ydata];
      last_value=1;
      for (j=1:size(j02,1))
         new_data=array(last_value:j02(j),:);
         junk_mat(end+1:size(junk_mat,1)+size(new_data,1),:)=new_data;
         if (size(array,2)==2)
            junk_mat(end+1,:)=[nan nan];
         elseif(size(array,2)==3)
            junk_mat(end+1,:)=[nan nan nan];
         end;
         last_value=j02(j)+1;
         new_data=[];
      end;
      new_data=array(last_value:end,:);
      junk_mat(end+1:size(junk_mat,1)+size(new_data,1),:)=new_data;
      xdata=junk_mat(:,1);
      ydata=junk_mat(:,2:end);
      junk_mat=[];
      array=[];
   end;
   xdata=[data.config.time_range(1);nan;xdata;nan;data.config.time_range(end)];
   if (size(ydata,2)==1)
      ydata=[ydata(1,1);nan;ydata;nan;ydata(end,1)];
      plotdata.array{i}=[xdata  ydata];
   elseif(size(ydata,2)==2)
      ydata=[ydata(1,:);[nan nan];ydata;[nan nan];ydata(end,:)];
      plotdata.array{i}=[xdata  ydata];
   end;
   clear xdata ydata;
   
   % verify that there is a trail to plot
   if (plotdata.array{i}(1,1)==plotdata.array{i}(end,1))
      err_text=sprintf('There is no data contained in the plot variable %s',plotdata.yaxes{i}.label);
      fault(err_text,data);
      return;
   end;
   
   % set y-limits
   if ((isnan(data.config.field_ranges(column(i),1))==0)&(isnan(data.config.field_ranges(column(i),2))==0))
      plotdata.yaxes{i}.limits=[data.config.field_ranges(column(i),1)  data.config.field_ranges(column(i),2)];
   else
      plotdata.yaxes{i}.limits=[min(plotdata.array{i}(:,2))  max(plotdata.array{i}(:,2))];
      if (plotdata.yaxes{i}.limits(1)==plotdata.yaxes{i}.limits(end))
         plotdata.yaxes{i}.limits(1)=plotdata.yaxes{i}.limits(1)-1;
         plotdata.yaxes{i}.limits(end)=plotdata.yaxes{i}.limits(end)+1;
      end;
   end;
   
   % set y-ticks
   plotdata.yaxes{i}.ticks=data.config.field_ranges(column(i),3);
   
   % set y-precision
   if (isnan(data.config.field_ranges(column(i),4))==0)
      plotdata.yaxes{i}.prec=data.config.field_ranges(column(i),4);
   else
      plotdata.yaxes{i}.prec=0;
   end;
   
   % set y-labels (if applicable)
   if (isempty(data.config.field_labels{column(i)})==0)
      plotdata.yaxes{i}.tick_labels=data.config.field_labels{column(i)};
   end;
   
   % set colors & linetypes
   if ((plotdata.plot_type==1)|(plotdata.plot_type==4))
      if (size(plotdata.array{i},2)==2)
         plotdata.color{i}='b';         % plot colors
         plotdata.linetype{i}='-';      % plot linetypes
      elseif(size(plotdata.array{i},2)>2)
         for (j=2:size(plotdata.array{i},2))
            plotdata.color{i}{j-1}=colour{j};           % plot colors
            plotdata.linetype{i}{j-1}=linetype{1};      % plot linetypes
         end;
         plotdata.color{i}=plotdata.color{i}';
         plotdata.linetype{i}=plotdata.linetype{i}';
      end;
   elseif ((plotdata.plot_type==2)|(plotdata.plot_type==5))
      % plot colors & linetypes
      if ((data.config.field_location(column(i),1)==6)|(data.config.field_location(column(i),1)==7)|(min(data.config.field_location(column(i),:)==[2 7 1])==1))
         plotdata.color{i}=data.colour{i};
         plotdata.linetype{i}=data.linetype{i};
         plotdata.linescale{i}=data.linescale{i};
      else
         plotdata.color{i}=colour{round(size(colour,2)*(i/size(colour,2)-fix(i/size(colour,2)))+1)};
         plotdata.linetype{i}=linetype{round(size(linetype,2)*(i/size(linetype,2)-fix(i/size(linetype,2)))+1)};
      end;
      
      % set limits & precision
      maximum=max([maximum  plotdata.yaxes{i}.limits(2)]);
      minimum=min([minimum  plotdata.yaxes{i}.limits(1)]);
      ticks=max([ticks  plotdata.yaxes{i}.ticks]);
      precision=max([precision  plotdata.yaxes{i}.prec]);
      if (i==plots)
         plotdata.yaxes{i}.limits=[minimum  maximum];
         plotdata.yaxes{i}.ticks=[ticks];
         plotdata.yaxes{i}.prec=precision;
      end;
   end;
end;

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
return;
