classdef rangeDopplerMap < handle
    %UNTITLED2 Summary of this class goes here
    %   Detailed explanation goes here
    
    properties
        mFigure;
        mCipMetaData;
        mDispChan;
        mScaling;
        mRange;
        mTextX;
        mTextY;
        mMap;
        mXPlotLine;
        mYPlotLine;
        mLr
        minY
    end
    
    methods
        function obj = rangeDopplerMap(aFigure,aDispChan,aCipMetaData,aScaling,aRange)
            %rangeDopplerMap Construct an instance of this class
            %   create a class to plot a range doppler map
            %   the constructor does operations that only need to be done
            %   once / instance of the class.
            %   figure = plotRangeDopplerMap(aFigure,aCipMagSqCube,aDispChan,aCipMetaData,aScaling,aRange,aPlots)
            %   arguments:
            %   aFigure -- figure to draw the image on
            
            %   aDispChan -- channel to plot
            %   aCipMetaData -- meta data describing the cube
            %   aScaling -- optional array containg the [min,max] scaling for the data.
            %   default value is selected if this is not included.
            %   aRange -- optional array containing the [min max] range to be plottted.
            %   The full range extent of the cube will be plotted if this is not
            %   included.
            obj.mFigure=aFigure;
            obj.mCipMetaData = aCipMetaData;
            obj.mDispChan = aDispChan;
            obj.mLr = (aDispChan == uint32(radChan.sumLr));

            obj.minY = 0;

            % LR starts at 2000m;
            if obj.mLr == 1
                obj.minY = 2000;
            end

            if ~exist('aScaling',"var")
                aScaling = [8 50];
            end
            obj.mScaling = aScaling;
            obj.mRange = aRange;
            obj.mFigure = aFigure;
    
            if exist('aRange','var')
                startRange = aRange(1);
                endRange = aRange(2);
            else
                startRange=aCipMetaData.cells.rangeZero(aDispChan);
                endRange=aCipMetaData.cells.procEnd(aDispChan);
            end

            yaxis=(0:endRange-startRange).*aCipMetaData.rangeCellSize_m(aDispChan);

            obj.mTextX=-55/2;
            if obj.mLr 
                delta=30;
            else
                delta=2;              
            end
            obj.mTextY=(endRange-startRange-delta)*aCipMetaData.rangeCellSize_m(aDispChan);
            
            obj.mXPlotLine=[-2 2 2 -2 -2];
            if (obj.mLr)
                obj.mYPlotLine=[-2 -2 2 2 -2].*aCipMetaData.rangeCellSize_m(aDispChan);
            else
                obj.mYPlotLine=[-0.5 -0.5 0.5 0.5 -0.5].*aCipMetaData.rangeCellSize_m(aDispChan);
            end
            %%
            
        end
        
        %% plot function
        function [time_s] = plot(obj,aAxis,aCipMagSqCube,aCipMetaData,aPlots,aRealTimeFlag)
            %plot -- update the plot with the latest data and optionally
            %plots.
            %   arguments:
            %   aAxis -- axis to draw the image on
            %   aDispChan -- channel to plot
            %   aCipMagSqCube -- a cip cube in magnitude squared dimmensions of the
            %   aCipMetaData -- meta data describing the cube
            %   aPlots -- optional structure that contains plots to highlight on the
            %   range doppler map.  The structure contains two elemental arrays: Range
            %   and Doppler.  If this argument is omitted, or the arrays are zero
            %   length then no plots are added to the display.
            %   aRealTimeFlag -- flag to provide indication that data
            %   recording is being down sampled to 30 frames / second for
            %   real time video.
            startRange=obj.mRange(1);
            endRange=obj.mRange(2);
            if( startRange == 0 )
               startRange = 1;
            end
            myImage=squeeze(10*log10(aCipMagSqCube(obj.mDispChan,startRange:endRange,:)));
            if (aCipMetaData.wxMode)
                myImage=repelem(myImage,1,4);
            end
            myAxis=aAxis;
            cla(myAxis);

            clim(myAxis,obj.mScaling)
            lJet=jet(256);
    
            scMyImage=sc(myImage,obj.mScaling,lJet);

            xlabel(myAxis,'Doppler (m/s)')
            ylabel(myAxis,'Range (m)')
            yaxis=(0:endRange-startRange).*aCipMetaData.rangeCellSize_m(obj.mDispChan);
            % lim effectively makes it the start, but we're still doing all
            % the plotting?

            
            
            ylim(myAxis, [obj.minY yaxis(end)]);
            % need to be able to 'zoom' to a given range. 
            %ylim(myAxis, [obj.minY 2200]);

            %xlim(myAxis,[floor(aCipMetaData.dopplerBins_mps(1))/2 ceil(aCipMetaData.dopplerBins_mps(end))/2]);
            xlim(myAxis,[floor(aCipMetaData.dopplerBins_mps(1)) ceil(aCipMetaData.dopplerBins_mps(end))]);

            %     set(myAxis,'YDir','normal')
            image(myAxis,'XData',aCipMetaData.dopplerBins_mps,'YData',yaxis,'CData',scMyImage);
            
            %     set(gcf,'Name',['   ' cipMetaData.Filename]);
            set(myAxis,'YDir','normal')
            
            caxis(myAxis,obj.mScaling)
            colormap(obj.mFigure,lJet);
            hcb=colorbar(myAxis);
            title(hcb,'Power (dB)');

            % annotate the image with the cip number and elapsed time...
            %             time_s=aCipMetaData.cipNum*aCipMetaData.priSize*aCipMetaData.numPris/aCipMetaData.sampleRate_sps(uint32(radChan.sumSr));
            time_s = aCipMetaData.cipTime_s;
            
            annotation = " ";
            if exist('aRealTimeFlag','var') && aRealTimeFlag~=0
                annotation = "*";
            end
            ns = aCipMetaData.time;
            wholeSecs = floor(double(ns)/1e9);
            fracSecs = double(ns - uint64(wholeSecs)*1e9)/1e9;
            t = datetime(wholeSecs,'ConvertFrom','posixTime','Format','yyyy.MM.dd HH:mm:ss.SSSSSSSSS') + seconds(fracSecs);
            myText=sprintf('%4d%s %-6.3f sec, Az: %3.3f, El: %3.3f\n%s',aCipMetaData.cipNum,annotation,time_s,aCipMetaData.cipCenterAzimuth_d, aCipMetaData.cipCenterElevation_d,string(t));
            %text(-50,(endRange-startRange-10)*aCipMetaData.rangeCellSize_m(obj.mDispChan),myText,'Color','white');
            textborder(obj.mTextX,obj.mTextY,myText);
            if exist('aPlots','var')
                for ii=1:size(aPlots.range)
                    line(myAxis,(aCipMetaData.dopplerBins_mps(aPlots.doppler(ii))+obj.mXPlotLine),...
                        (aPlots.range(ii)*aCipMetaData.rangeCellSize_m(obj.mDispChan)+obj.mYPlotLine),...
                        'color','green','LineWidth',1);
                    hold(myAxis,'on');
                    plot(myAxis,aCipMetaData.dopplerBins_mps(aPlots.doppler(ii)),...
                        aPlots.range(ii)*aCipMetaData.rangeCellSize_m(obj.mDispChan),'g.');
                end
            end
        end
    end
end

