function [p_Lon, p_Lat, p_Par] = MWFBIMAT                               ...
   ( p_NbParam, p_IndParam, p_IndMap, p_FileName )
% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% [p_Lon,p_Lat,p_Par] = MWFBIMAT (p_NbParam,p_IndParam,p_IndMap,p_FileName)
%
% Read a BINARY EXTRACTED FILE (WOCE) and give Longitude, Latitude and values
% for one parameter and one map.
%
% IN  :
%  - p_NbParameter : Number of total parameter(s) in the extracted file 
%                    (asked during extraction process)
%  - p_IndParam    : Index of the wanted parameter
%                    1 <= p_IndParam <= p_NbParameter
%  - p_IndMap      : Index of the wanted map for a file with multiple maps
%                    1 <= p_IndMap <= 15
%                    (asked during extraction process)
%  - p_FileName    : Extracted file name
%
% OUT :
%  - p_Lon         : Extracted matrix for longitudes ( MxN )
%  - p_Lat         : Extracted matrix for latitudes  ( MxN )
%  - p_Par         : Extracted matrix for parameter  ( MxN )
%  M and N are computing by this function.
%
% To use this fonction, you can follow this example :
% - for the extracted file named 'YourExtractedFileName',
% - for 7 extracted parameters in this file,
% - if you want the 5th parameter,
% - you want the first map (Week ou Month),
%
%    FileName        = 'YourExtractedFileName' ;
%    NbParam         = 7                       ;
%    WantedParameter = 5                       ;
%    WantedMap       = 1                       ;
%    [Lon,Lat,Par] = MWFBIMAT (NbParam,WantedParameter,WantedMap,FileName) ;
%
% To show the extracted parameter, you should use the folowing commands :
%    pcolor ( Lon, Lat, Par ) ;
%    shading flat             ;
%    colormap ( jet )         ;
%    colorbar                 ;
% and see the result on the Matlab's figure.
% 
% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

% Local variables declared with l_
% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
l_MapPosition              =  0         ; % map position in the file
l_RowNb                    =  0         ; % number of rows
l_ColNb                    =  0         ; % number of columns
l_MapSize                  =  0         ; % size of a map in bytes / 2
%
l_StartFilePosition        =  0         ; % stores start file position
l_CurrentFilePosition      =  0         ; % stores current file position
l_EndFilePosition          =  0         ; % stores end file position
l_Position                 =  0         ; % positions in a matrix
l_DimLig                   =  0         ; % number of lines
l_DimCol                   =  0         ; % number of columns
%
l_TmpParameters            =  0         ; % all parameters for the wanted map
l_TmpLongitude             =  0         ; % stores longitude
l_TmpLatitude              =  0         ; % stores latitude
l_OldTmpLongitude          =  0         ; % stores old value of longitude
l_OldTmpLatitude           =  0         ; % stores old value of latitude
%
l_Permissions              =  'rb'      ; % permissions to open extrated file
l_FileId                   =  0         ; % opened file identifier
%
l_MatlabMsg                =  ''        ; % matlab error messages
l_Status                   =  0         ; % matlab function return value
% 
l_TmpMatrix                = 0          ; % local matrix

% Error values
% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
l_KO  = -1 ;

% Error messages for this function
% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
l_OpeningFile      = 'Can t open the extracted file'                 ;
l_ClosingFile      = 'Can t close the extracted file'                ;
l_SeekError        = 'Can t seek in the file'                        ;
l_InvalidParam_1   = 'Invalid value for p_NbParam'                   ;
l_InvalidParam_2   = 'Invalid value for p_IndParm'                   ;
l_InvalidParam_3   = 'Invalid value for p_IndMap'                    ;

% Test on parameters given to this function
% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
if ( p_NbParam < 1 | p_NbParam > 15 )
   error ( l_InvalidParam_1 ) ;   
end
%
if ( p_NbParam < p_IndParam | p_IndParam < 1 )
   error ( l_InvalidParam_2 ) ;      
end	
%	
if ( p_IndMap < 1 )
   error ( l_InvalidParam_3 ) ;   	
end

% Open the file for read only and binary mode
% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
[l_FileId, l_MatlabMsg] = fopen ( p_FileName, l_Permissions ) ;
if ( l_FileId == l_KO )
   disp ( l_OpeningFile ) ;
   error ( l_MatlabMsg )  ;
end

% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Main part of the function :
% - find parameters that define the file
% - read the entire map 
% - puts the map into a (p_NbParam+2)xMxN matrix
% - extracts Longitude, latitude and the p_IndParam th parameter
% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

% Find parameters that define the file :
% - number of columns N (longitudes used to define a map)
% - number of rows M (latitudes used to define a map)
% - number of map in the file
% To do this job, the function uses the structure of an extracted file :
% [Latitude,Longitude,Parameter1, ..., ParameterX] with :
% - Longitude stored on an unsigned integer of 2 bytes,
% - others are stored on an integer of 2 bytes.
% the inside loop is on longitude (N)
% the middle loop is on latitude  (M)
% the outside loop is on map
% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

% find file positions
l_Status = fseek ( l_FileId, 0, 'eof' )                ;
if ( l_Status == l_KO )
      error ( l_SeekError )                            ;
end
l_EndFilePosition     = ftell ( l_FileId )             ;
l_Status = fseek ( l_FileId, 0, 'bof' )                ;
if ( l_Status == l_KO )
   error ( l_SeekError )                               ;
end
l_StartFilePosition   = ftell ( l_FileId )             ;
l_CurrentFilePosition = ftell ( l_FileId )             ;

% init search
l_MapPosition     = 0                                  ;
l_OldTmpLatitude  = fread ( l_FileId, 1, 'int16' )     ;
l_OldTmpLongitude = fread ( l_FileId, 1, 'uint16' )    ;
l_NbRow           = 0                                  ;
l_NbCol           = 0                                  ;

% search on longitude
while ( ( l_CurrentFilePosition < l_EndFilePosition )  &                   ...
      ( l_TmpLongitude ~= l_OldTmpLongitude ) )
   l_Status = fseek ( l_FileId, p_NbParam*2, 'cof' )   ;
   l_CurrentFilePosition = ftell ( l_FileId )          ;
   if ( l_CurrentFilePosition+4 < l_EndFilePosition )
      l_TmpLatitude  = fread ( l_FileId, 1, 'int16' )  ;
      l_TmpLongitude = fread ( l_FileId, 1, 'uint16' ) ;      
   else
      l_Status = fseek ( l_FileId, 0, 'eof' )          ;
   end
   l_NbCol        = l_NbCol + 1                        ;
   l_CurrentFilePosition = ftell ( l_FileId )          ;
end

% search on latitude
if ( l_CurrentFilePosition == l_EndFilePosition )
   l_NbRow = 1                                         ;
else
   l_Status = fseek ( l_FileId, 2*2, 'bof' )           ;
   l_CurrentFilePosition = ftell ( l_FileId )          ;
   while ( ( l_CurrentFilePosition < l_EndFilePosition )  &                ...
         ( l_TmpLatitude ~= l_OldTmpLatitude ) )
      l_Status = fseek ( l_FileId, (p_NbParam+2)*2*l_NbCol-2*2             ...
         , 'cof' )                                     ;
      l_CurrentFilePosition = ftell ( l_FileId )       ;
      if ( l_CurrentFilePosition+4 < l_EndFilePosition )
         l_TmpLatitude  = fread ( l_FileId, 1, 'int16');
         l_TmpLongitude = fread ( l_FileId, 1, 'uint16');
      else
         l_Status = fseek ( l_FileId, 0, 'eof' )       ;
      end
      l_NbRow        = l_NbRow + 1                     ;   
      l_CurrentFilePosition = ftell ( l_FileId )       ;  
   end
end

% search on map
l_Status = fseek ( l_FileId, 0, 'bof' )                ;
l_CurrentFilePosition = ftell ( l_FileId )             ;   

while ( ( l_CurrentFilePosition < l_EndFilePosition )    &                 ...
      ( l_MapPosition < p_IndMap ) )
   l_Status = fseek ( l_FileId,                                            ...
      2*l_NbCol*l_NbRow , 'cof' )                      ;
   if ( l_Status == l_KO )
      error ( l_SeekError )                            ;
   end
   l_MapPosition     = l_MapPosition + 1               ;
   l_CurrentFilePosition = ftell ( l_FileId )          ;   
end

% Read the entire map 
% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
l_Status = fseek ( l_FileId,                                                ...
   2*(p_NbParam+2)*l_NbCol*l_NbRow*(l_MapPosition-1),                       ...
   'bof' )                                             ;
if ( l_Status == l_KO )
   error ( l_SeekError )                               ;
end
l_MapSize = (p_NbParam+2)*l_NbCol*l_NbRow             ;
l_TmpMatrix = fread ( l_FileId, l_MapSize, 'int16' )   ;

% Close the file
% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
[l_FileId] = fclose ( l_FileId ) ;
if ( l_FileId == l_KO )
   error ( l_ClosingFile )                             ;
end

% puts the map into a (p_NbParam+2)xMxN matrix
% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
l_TmpMatrix = reshape ( l_TmpMatrix, p_NbParam+2,                           ...
   l_NbCol, l_NbRow ) ;

% extracts Longitude, latitude and the p_IndParam th parameter
% and convert longitude read in signed interger to unsigned interger 
% convert all values : divide by 100
% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
p_Lat = squeeze (l_TmpMatrix (1, :, :) )               ;
p_Lon = squeeze (l_TmpMatrix (2, :, :) )               ;
p_Par = squeeze (l_TmpMatrix (p_IndParam+2, :, :) )    ;
%
[l_Position] = find ( p_Lon < 0 )                      ;
p_Lon (l_Position) = p_Lon (l_Position) + 2^16         ;
%
p_Lat = p_Lat' / 100                                   ;
p_Lon = p_Lon' / 100                                   ;
p_Par = p_Par' / 100                                   ;

% Change a continuous map in longitude (easier to show with pcolor)
% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
l_OldTmpLongitude = p_Lon (1,1)                         ;
l_Position = find ( p_Lon(1,:) <= l_OldTmpLongitude )   ;
[l_DimLig, l_DimCol] = size ( l_Position )              ;

if ( l_DimCol > 1 )
   l_Position = find ( p_Lon>=l_OldTmpLongitude & p_Lon<360 ) ;
   p_Lon ( l_Position ) = p_Lon ( l_Position ) - 360         ;
end

% Back to Matlab
% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
return ;
