function tsgcor_GUI( hTsgGUI )
% tsgcor_GUI 
%
% GUI for correction of TSG data by comparison to samples
% this GUI is a children of tsgqc_GUI
%
%

%% COPYRIGHT & LICENSE
%  Copyright 2007 - IRD US191, all rights reserved.
%
%  This file is part of tsgqc_GUI.
%
%    Datagui 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 2 of the License, or
%    (at your option) any later version.
%
%    tsgqc_GUI 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 Datagui; if not, write to the Free Software
%    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA


%%  Initialization tasks
%   ********************
clc

% Screen limits for the GUI
% -------------------------
set(0,'Units','normalized');
guiLimits = get(0,'ScreenSize');
guiLimits(1) = guiLimits(1) + 0.05;
guiLimits(2) = guiLimits(2) + 0.05;
guiLimits(3) = guiLimits(3) - 0.1;
guiLimits(4) = guiLimits(4) - 0.2;

% Create and then hide the GUI as it is being constructed.
% --------------------------------------------------------
hTsgCorGUI = figure(...
  'Name', 'TSG Correction', ...
  'NumberTitle', 'off', ...
  'Resize', 'on', ...
  'Menubar','none', ...
  'Toolbar', 'none', ...
  'Tag', 'ButtonMotionOff', ...
  'WindowButtonMotionFcn', @MouseMotion, ...
  'CloseRequestFcn', @QuitProgram,...
  'HandleVisibility','callback',...
  'Visible','on',...
  'Units', 'normalized',...
  'Position',guiLimits);
 
% Get the CONSTANTS
% -----------------
cst    = getappdata( hTsgGUI, 'constante');

%  Construct the Menu
%   -----------------
hFileMenu = uimenu(...
  'Parent', hTsgCorGUI,...
  'HandleVisibility','callback',...
  'Label', 'File');

hQuitMenu = uimenu(...
  'Parent',hFileMenu,...
  'Label','Quit',...
  'Separator','on',...
  'Accelerator','Q',...
  'HandleVisibility','callback',...
  'Callback',@QuitMenuCallback);

%%  Construct the Toolbar
%   --------------------
hToolbar       =   uitoolbar(...   % Toolbar for Open and Print buttons
  'Parent',hTsgCorGUI, ...
  'HandleVisibility','callback');
hZoomToggletool  =   uitoggletool(...   % Open Zoom toolbar button
  'Parent',hToolbar,...
  'Separator', 'on', ...
  'TooltipString','Zoom',...
  'CData', iconRead(fullfile(matlabroot, ...
  '/toolbox/matlab/icons/zoom.mat')),...
  'HandleVisibility','callback', ...
  'Tag','PUSHTOOL_ZOOM',...
  'Enable', 'off',...
  'OffCallback', @Zoom_OffMenuCallback,...
  'ONCallback',  @Zoom_OnMenuCallback);
hPanToggletool  =   uitoggletool(...   % Open Pan toolbar button
  'Parent',hToolbar,...
  'TooltipString','Pan',...
  'CData',iconRead(fullfile(matlabroot, ...
  '/toolbox/matlab/icons/pan.mat')),...
  'HandleVisibility','callback', ...
  'Tag','PUSHTOOL_PAN',...
  'Enable', 'off',...
  'OffCallback', @Pan_OffMenuCallback,...
  'ONCallback',  @Pan_OnMenuCallback);
  %'ClickedCallback', @PanMenuCallback);

hBottlePushtool  = uipushtool(...   % Open toolbar button
  'Parent',hToolbar,...
  'TooltipString','Plot the Samples',...
  'Separator', 'on', ...
  'Tag', 'off', ...
  'CData',iconRead(...
  [DEFAULT_PATH_FILE 'tsg_icon' filesep 'bottleicon.mat']),...
  'HandleVisibility','callback', ...
  'ClickedCallback', @BottleMenuCallback);
hStartlimitPushtool  = uipushtool(...   % Open toolbar button
  'Parent',hToolbar,...
  'TooltipString','Start time',...
  'Separator', 'on', ...
  'Tag', 'off', ...
  'CData',iconRead(...
  [DEFAULT_PATH_FILE 'tsg_icon' filesep 'startlimit.mat']),...
  'HandleVisibility','callback', ...
  'ClickedCallback', @TimeLimitCallback);
hEndlimitPushtool  = uipushtool(...   % Open toolbar button
  'Parent',hToolbar,...
  'TooltipString','End time',...
  'Tag', 'off', ...
  'CData',iconRead(...
  [DEFAULT_PATH_FILE 'tsg_icon' filesep 'endlimit.mat']),...
  'HandleVisibility','callback', ...
  'ClickedCallback', @TimeLimitCallback);

% Static text that displays the position, salinity and temperature
% ----------------------------------------------------------------
hInfoText = uicontrol(...
  'Parent', hTsgCorGUI, ...
  'Style', 'text', ...
  'Fontsize', 12, ...
  'Fontweight', 'bold', ...
  'Visible','on',...
  'Units', 'normalized',...
  'String', 'Information sur la position du curseur', ...
  'Position', [.05, .95, .9, .03]);

% Construct the plot axes
% -----------------------
hPlotAxes(1) = axes(...     % the axes for plotting Salinity
  'Parent', hTsgCorGUI, ...
  'Units', 'normalized', ...
  'Visible', 'off', ...
  'HandleVisibility','callback', ...
  'Position',[.25, .6, .7, .32]);
hPlotAxes(2) = axes(...     % the axes for plotting sample
  'Parent', hTsgCorGUI, ...
  'Units', 'normalized', ...
  'Visible', 'off', ...
  'HandleVisibility','callback', ...
  'Position',[.25, .3, .7, .25]);
hPlotAxes(3) = axes(...     % the axes for plotting ship velocity
                'Parent', hTsgCorGUI, ...
                'Units', 'normalized', ...
                'Visible', 'off', ...
                'HandleVisibility','callback', ...
                'Position',[.25, .05, .7, .2]); 

    % Choose the date limits for the correction
    % --------------------------------------------------
    % Create the uipanel
    hpDateLimit = uipanel( ...
                'Parent', hTsgCorGUI, ...
                'Title', 'Date Limits', ...
                'Units', 'normalized', ...
                'FontSize', 11, ...
                'Fontweight', 'bold', ...
                'BackgroundColor', 'white',...
                'Position',[.01 .75 .2 .19]);

    htDateMin = uicontrol( ...
                'Parent', hpDateLimit, ...
                'Style', 'Text', ...
                'String', 'Minimum  (yyyy-mm-dd hh:mm:ss)', ...
                'HorizontalAlignment', 'left', ...
                'Units', 'normalized', ...
                'backgroundcolor', 'white', ...
                'FontSize', 10, ...
                'Position',[.05 .8 .9 .15]);

    hetDateMin = uicontrol( ...
                'Parent', hpDateLimit, ...
                'Style', 'edit', ...
                'Units', 'normalized', ...
                'FontSize', 10, ...
                'Position',[.05 .6 .9 .18]);

    htDateMax = uicontrol( ...
                'Parent', hpDateLimit, ...
                'Style', 'Text', ...
                'String', 'Maximum  (yyyy-mm-dd hh:mm:ss)', ...
                'HorizontalAlignment', 'left', ...
                'Units', 'normalized', ...
                'backgroundcolor', 'white', ...
                'FontSize', 10, ...
                'Position',[.05 .3 .9 .15]);

    hetDateMax = uicontrol( ...
                'Parent', hpDateLimit, ...
                'Style', 'edit', ...
                'Units', 'normalized', ...
                'FontSize', 10, ...
                'Position',[.05 .1 .9 .18]);
                      
            
    % Choose the correction method
    % --------------------------------------------------
    % Create the button group
    hbgMethod = uibuttongroup( ...
                'Parent',hTsgCorGUI, ...
                'Title','Correction Method', ...
                'Units', 'normalized', ...
                'FontSize',11, ...
                'Fontweight', 'bold', ...
                'BackgroundColor','white',...
                'Position',[.01 .6 .2 .14]);
             
    % Create 2 radio buttons in the button group
    hrbLinear = uicontrol( ...
                'Style','pushbutton', ...
                'Parent',hbgMethod, ...
                'Units', 'normalized', ...
                'String','Linear adjustment',...
                'pos',[.05 .55 .9 .4], ...
                'HandleVisibility','callback', ...
                'Callback', @CorLinearCallback);

    hrbMedian = uicontrol( ...
                'Style','pushbutton', ...
                'Parent',hbgMethod, ...
                'Units', 'normalized', ...
                'String','Running median filter',...
                'pos',[.05 .05 .9 .4],...
                'HandleVisibility','callback', ...
                'Callback', @CorMedianCallback);

               
    % Initialize some button group properties 
    set(hbgMethod,'SelectionChangeFcn',@selcbk);
    set(hbgMethod,'SelectedObject',[]);  % No selection
    set(hbgMethod,'Visible','on');
            
    % Construct the context menu to delete samples
    % --------------------------------------------
    hSampleCmenu       = uicontextmenu(...
                            'Parent', hTsgCorGUI, ...
                            'HandleVisibility','callback' );
    hQcSampleNocontrol = uimenu(...
                            'Parent', hSampleCmenu,... 
                            'HandleVisibility','off', ...
                            'Label', 'No control',...
                            'ForegroundColor', 'k',...
                            'Callback', @Qc);
    hQcSampleGood      = uimenu(...
                            'Parent', hSampleCmenu,... 
                            'HandleVisibility','off', ...
                            'Label', 'Good',...
                            'ForegroundColor', 'b',...
                            'Callback', @Qc);
    hQcSampleBad       = uimenu(...
                            'Parent', hSampleCmenu,... 
                            'HandleVisibility','off', ...
                            'Label', 'Bad',...
                            'ForegroundColor', 'r',...
                            'Callback', @Qc);

                          
                          
                          
% Pointer set to watch during reading and plotting
% ------------------------------------------------
set( hTsgCorGUI, 'Pointer', 'watch' );

% Get the data useful to the correction GUI
% -----------------------------------------
tsg    = getappdata( hTsgGUI, 'tsg_data' );

% Merge bucket and external samples
% ---------------------------------
tsg_mergesample( hTsgGUI );



dateMin = datestr(tsg.TIME(1), 31);
dateMax = datestr(tsg.TIME(end), 31);
set( hetDateMin, 'String', dateMin);
set( hetDateMax, 'String', dateMax); 

% dt between 2 tsg measurements
TSG_SAMPLING_TIME = tsg.TIME(2) - tsg.TIME(1);

% Running average of TSG time series over TSG_DT_SMOOTH hour.
[psal_smooth, nval] = ...
      dev_moveaverage(tsg.TIME, tsg.PSAL, cst.TSG_DT_SMOOTH, cst.TSG_STDMAX);

% Compute the sample-TSG differences
sample = dev_diffTsgSample(tsg, psal_smooth, sample, TSG_SAMPLING_TIME);

% Tracé
% -----
tsg_plot_SalTsgSample( hTsgGUI, hPlotAxes );

% Pointer reset to arrow
% ----------------------
set( hTsgCorGUI, 'Pointer', 'arrow' );

% The callback to detect the mouse motion can be set to on
% --------------------------------------------------------
set( hTsgCorGUI, 'Tag', 'ButtonMotionOn');
    
%  Callbacks for tsgcqc_GUI
%  ************************

    %----------------------------------------------------------------------
    function ZoomMenuCallback(hObject, eventdata)
    % Callback function run when the ...    
        
        % Returns a zoom mode object for the figure handle
        % ------------------------------------------------
        hZoom = zoom(hTsgCorGUI);
        
        % Specifies whether this mode is currently enabled on the figure
        % --------------------------------------------------------------
        zoomOnOff = get(hZoom, 'Enable' );
        switch zoomOnOff
            case 'on'
                zoom off
                zoomAdaptiveDateTicks('off');
            case 'off'
                pan off
                set(hTsgCorGUI,'Pointer','arrow');
                set(hEndlimitPushtool, 'Tag', 'off' );
                set(hStartlimitPushtool, 'Tag', 'off' );

                zoom on
                zoomAdaptiveDateTicks('on');
        end
    end

    %----------------------------------------------------------------------
    function PanMenuCallback(hObject, eventdata)
    % Callback function run when the ....    
        
        % Returns a pan mode object for the figure handle
        % -----------------------------------------------
        hPan = pan(hTsgCorGUI);
        
        % Specifies whether this mode is currently enabled on the figure
        % --------------------------------------------------------------
        panOnOff = get(hPan, 'Enable' );
        switch panOnOff
            case 'on'
                pan off
                panAdaptiveDateTicks('off');
            case 'off'
                zoom off
                set(hTsgCorGUI,'Pointer','arrow');
                set(hEndlimitPushtool, 'Tag', 'off' );
                set(hStartlimitPushtool, 'Tag', 'off' );

                pan on
                panAdaptiveDateTicks('on');                
        end
    end

    %----------------------------------------------------------------------
    function TimeLimitCallback(hObject, eventdata)
    % Callback function run when the ....    

        % Desactivate the Zoom and Pan functions.
        % ---------------------------------------
        zoom off; pan off
        panAdaptiveDateTicks('off');zoomAdaptiveDateTicks('off');

        % Retrieve named application data
        % -------------------------------
        tsg = getappdata( hTsgGUI, 'tsg_data');
        
        % Toggle the tag of the Qc pushbutton to 'on' or 'off'
        % ----------------------------------------------------
        switch get(hObject, 'Tag'); 
            case 'off'
                set(hObject, 'Tag', 'on' );
                set( hTsgCorGUI, 'Pointer', 'crosshair');
            case 'on'
                set(hObject, 'Tag', 'off' );
                set(hTsgCorGUI,'Pointer','arrow');
        end

        % Wait for key press
        % ------------------
        [x, y] = ginput(1);
        
        % Write the date in the Editable uicontrol
        % ----------------------------------------
        if hObject == hEndlimitPushtool
            set( hetDateMax, 'String', datestr(x, 31));
        else
            set( hetDateMin, 'String', datestr(x, 31));
        end
        
        set(hTsgCorGUI,'Pointer','arrow');

    end

%----------------------------------------------------------------------
  function BottleMenuCallback(gcbo, eventdata,handles)
    % Callback function run when the QC pushbutton is selected
    
    % Desactivate the Zoom and Pan functions.
    % ---------------------------------------
    zoom off; pan off
    panAdaptiveDateTicks('off');zoomAdaptiveDateTicks('off');
    
    % Toggle the tag of the Qc pushbutton to 'on' or 'off'
    % ----------------------------------------------------
    switch get(hBottlePushtool, 'Tag');
      case 'off'
        set(hBottlePushtool, 'Tag', 'on' );
        set(hPlotAxes(2),'UIContextMenu', hSampleCmenu);
        set(hTsgCorGUI, 'Pointer', 'crosshair');
      case 'on'
        set(hBottlePushtool, 'Tag', 'off' );
        set(hPlotAxes(2),'UIContextMenu', []);
        set(hTsgCorGUI,'Pointer','arrow');
    end

    qualityCode = -1;
    ind = [];
    while strcmp( get(hBottlePushtool, 'Tag'),'on')
      
      k = waitforbuttonpress;
      
      % If the QC pushbutton is pressed we quit the callback
      % ----------------------------------------------------
      if strcmp( get(hBottlePushtool, 'Tag'),'off')
        
        % Desactivate the context menu use to choose the Quality Codes
        % ----------------------------------------------
        set(hSampleCmenu, 'Visible', 'off');
        break
      end

      % Test if the right mouse button is clicked
      % -----------------------------------------
      if strcmp(get(hTsgCorGUI, 'SelectionType'), 'alt') && ~isempty(ind)
        
        % Wait for a QC Context Menu choice : The user choose the
        % quality code
        % -------------------------------------------------------
        uiwait
        qualityCode = 1;
      
      else

        % Mouse motion callback desactivated when a selection is made.
        % Otherwise there is a conflict with the map if it is activated
        % -------------------------------------------------------
        set( hTsgCorGUI, 'Tag', 'ButtonMotionOff');
        
        % Selection of the data within the figure
        % ---------------------------------------
        point1    = get(gca,'CurrentPoint');    % button down detected
        finalRect = rbbox;                      % return figure units
        point2    = get(gca,'CurrentPoint');    % button up detected
        
        point1    = point1(1,1:2);              % extract x and y
        point2    = point2(1,1:2);
        
        p1 = min(point1,point2);
        p2 = max(point1,point2);             % calculate locations
        
        % Retrieve named application data
        % -------------------------------
        sample = getappdata( hTsgGUI, 'sample');
        
        ind = find(sample.DAYD > p1(1,1) & sample.DAYD < p2(1,1) & ...
                   sample.SSPS_DIF > p1(1,2) & sample.SSPS_DIF < p2(1,2));
                        
        % Selection made : Mouse motion callback re-activated
        % ---------------------------------------------------
        set( hTsgCorGUI, 'Tag', 'ButtonMotionOn');
      
      end

      % Plot the data with the color of the chosen quality Code.
      % Is it the right place for this source code ????
      % --------------------------------------------------------
      if qualityCode ~= -1
        
        tsg = getappdata( hTsgGUI, 'tsg_data');
        
        sample.SSPS_QC(ind) =  tsg.qc.Code.ACTIVE;
        
        % Save the modifications
        % ----------------------
        setappdata( hTsgGUI, 'sample', sample);
        
        axes(hPlotAxes(2));
        hold on
        color = ['o' tsg.qc.Color.ACTIVE];
        plot(sample.DAYD(ind), sample.SSPS_DIF(ind), color );
        hold off
      end
    end
  end

%---------------------------------------------------------------------
function Qc(hObject, eventdata)
  % Callback function run when the QC context menu is selected
  
  % Retrieve Default Quality Code and Color
  % ---------------------------------------
  tsg = getappdata( hTsgGUI, 'qcColor');
  
  switch hObject
    case hQcSampleNocontrol
      tsg.qc.Code.ACTIVE   = tsg.qc.Code.NO_CONTROL;
      tsg.qc.Color.ACTIVE  = tsg.qc.Color.NO_CONTROL;
    case hQcSampleGood
      tsg.qc.Code.ACTIVE   = tsg.qc.Code.GOOD;
      tsg.qc.Color.ACTIVE  = tsg.qc.Color.GOOD;
    case hQcSampleBad
      tsg.qc.Code.ACTIVE   = tsg.qc.Code.PROBABLY_BAD;
      tsg.qc.Color.ACTIVE  = tsg.qc.Color.PROBABLY_BAD;
  end

  setappdata( hMainFig, 'tsg_data', tsg );
  
  % uiwait in the QCMenuCallback function
  % -------------------------------------
  uiresume
end

    %---------------------------------------------------------------------
    function MouseMotion(hObject, eventdata)
     
      % Test if the callback can be activated
      % -------------------------------------
      if strcmp( get( hTsgCorGUI, 'Tag'), 'ButtonMotionOn')
          
        % Retrieve named application data
        % -------------------------------
        tsg = getappdata( hTsgGUI, 'tsg_data');
        
        % Get the mouse position
        % ----------------------
        point = get(gcf,'CurrentPoint');
        
        if point(1) > .05 && point(2) > .6 && point(1) < .95 && point(2) < .92
    
            % Get current position of cusor and return its coordinates in
            % axes with handle h_axes
            % -----------------------------------------------------------
            [x, y] = gpos(hPlotAxes(1));
                    
            if x > tsg.TIME(1) && x < tsg.TIME(end)
            
                indCursor = find( tsg.TIME > x);
                % use sprintf with format instead strcat & num2str but flag
                % - don't work with 0, eg %+07.4f
                set( hInfoText, 'String',...
                  sprintf(['%s   -   Latitude = %s   -   Longitude = %s '...
                           '  -   Salinity = %07.4f   -   Temperature = %07.4f'],...
                    datestr(tsg.TIME(indCursor(1)),'dd/mm/yyyy HH:MM'),...
                    dd2dm(tsg.LATITUDE(indCursor(1)),0), ...
                    dd2dm(tsg.LONGITUDE(indCursor(1)),1), ...
                    tsg.PSAL(indCursor(1)), ...
                    tsg.TEMP_TSG(indCursor(1))...
                ));
            
            end
        end
      end
    end

    % -----------------------------------------------------------------
    function SaveMenuCallback(hObject, eventdata)
    % Callback function run when the Save menu item is selected
        
%        [fileName, pathName, filterIndex] = uiputfile('*.txt', ...
%                                            'Save file name');
        
%        fileName = [pathName fileName];
%        error = tsg_writeTsgData( hTsgGUI, fileName );
%        if ~error
            % 
%        end
    end

    % -----------------------------------------------------------------
    function CorLinearCallback(hObject, eventdata)
    % Callback function run when 
    
        msgbox('Method not yet implemented', 'modal' );
    
    end

    % -----------------------------------------------------------------
    function CorMedianCallback(hObject, eventdata)
    % Callback function run when 
    
        msgbox('Method not yet implemented', 'modal' );
        
        % Get the time limits for the correction A TESTER
        % --------------------------------------
        %dateMin = get( hetDateMin, 'String');
        %dateMax = get( hetDateMax, 'String'); 

        % Correction
        % ----------
        % tsg = dev_corMethod1(tsg, sample, dateMin, dateMax, cst.COR_TIME_WINDOWS);
        
        % Update application data 'tsg'
        % ----------------------------
        %tsg    = getappdata( hTsgGUI, 'tsg_data' );
   
    end


    % -----------------------------------------------------------------
    function QuitMenuCallback(hObject, eventdata)
    % Callback function run when the Quit menu item is selected
            
        % If the data have been modified and not save, the program
        % propose to save the data
        % --------------------------------------------------------
        if  strcmp( get( hSaveMenu, 'Tag' ), 'on')
            selection = ...
            questdlg('The file has been modified.  Do you want to save it ?',...
                      'Save before Quit?',...
                      'Yes', 'No', 'Yes');
            if strcmp(selection, 'Yes')
                return;
            else
                QuitProgram;
            end
        else
            selection = ...
                    questdlg(['Quit ' get(hTsgCorGUI, 'Name') '?'],...
                             ['Quit ' get(hTsgCorGUI, 'Name') '?'],...
                              'Yes', 'No', 'Yes');
            if strcmp(selection, 'No')
                return;
            else    
                QuitProgram;
            end
        end

    end
  
  % ----------------------------------------------------------------
  function QuitProgram(hObject, eventdata)

    delete(hTsgCorGUI);

  end
      
end
