function imaligns_fits(RefIm,ListIm,RefCat,ListCat,varargin)
%--------------------------------------------------------------------------
% imaligns_fits function                                           ImBasic
% Description: Align images relative to a reference image using stars
%              detected in the image.
% Input  : - Reference FITS image.
%          - A FITS images or images to register to the reference image.
%            This can be a string (including wild cards), or cell array
%            of strings. See create_list.m for details.
%          - Reference catalog. Default is empty matrix (i.e., []).
%            If empty than will generate a reference catalog using
%            SExtractor. Otherwise, a SExtractor reference catalog should
%            be provided either as a string containing a FITS binary table
%            name, or a matrix, or a structure in which one of the fields
%            is the catalog matrix.
%            In case this is a structure then the field name containing
%            the catalog name is taken from the optional paramter
%            'CatName', and a field name containing the column names is
%            taken from the optional parameter 'ColName'. If 'ColName'
%            field is not given than the default value of the Col
%            structure is taken from the 'Col' optional parameter.
%          - Like the previous parameter, but for the list of images.
%            This must be a cell array of FITS table catalog names or an
%            empty matrix.
%            The order of files must be identical to the order of files
%            in the ListIm (second) input parameter.
%          * Arbitrary number of pairs of input parameters: keyword,value,...
%            Available keywords are:
%            'OutPrefix'- Add prefix before output image names,
%                         default is empty string (i.e., '').
%            'OutDir'   - Directory in which to write the output images,
%                         default is empty string (i.e., '').

%            'CopyHead' - Copy header from original image {'y' | 'n'}.
%                         Default is 'y'.
%            'AddHead'  - Cell array with 3 columns containing additional
%                         keywords to be add to the header.
%                         See cell_fitshead_addkey.m for header structure
%                         information. Default is empty matrix.
%            'DataType' - Output data type (see fitswrite.m for options), 
%                         default is float32.
%            'CCDSEC'   - Image sction for image to be rotated. If given
%                         then the image will be croped before rotation.
%                         This could be string containing image keyword 
%                         name (e.g., 'CCDSEC'), or a vector of 
%                         [Xmin, Xmax, Ymin, Ymax].
%            'Save'     - Save FITS image to disk {'y' | 'n'}.
%                         Default is 'y'.
%            'Col'      - Default columns in the catalog containing the
%                         XWIN_IMAGE, YWIN_IMAGE and MAG_AUTO columns.
%                         Default is [1 2 3].
%            'ColName'  - Column name in the catalog structure containing
%                         the column structure. Default is 'Col'.
%            'CatName'  - Catalog name in the catalog structure containing
%                         the catalog matrix. Default is 'Cat'.
% Output  : - 
% Tested : Matlab 7.13
%     By : Eran O. Ofek                     April 2012
%    URL : http://wise-obs.tau.ac.il/~eran/matlab.html
% Example: Out=imaligns_fits(...
%--------------------------------------------------------------------------

Def.RefCat  = [];
Def.ListCat = [];
if (nargin==2),
    RefCat    = Def.RefCat;
    ListCat   = Def.ListCat;
elseif (nargin==3),
    ListCat   = Def.ListCat;
else
    % do nothing
end

DefV.OutPrefix   = '';
DefV.OutDir      = '';
DefV.CopyHead    = 'y';
DefV.AddHead     = [];
DefV.DataType    = 'float32';
DefV.Save        = 'y';
DefV.ColName     = 'Col';
DefV.CatName     = 'Cat';
DefV.Col         = [1 2 3];


InPar = set_varargin_keyval(DefV,'y','use',varargin{:});

%-----------------------------------------------------------------------
%--- If no RefCat is provided then generate catalog using SExtractor ---
%-----------------------------------------------------------------------
ParSex = {'XWIN_IMAGE','YWIN_IMAGE','MAG_AUTO'};
if (isempty(RefCat)),
    [TmpRefCat,~,RefCol] = run_sextractor(RefIm,[],ParSex);
    RefTable    = TmpRefCat{1};
else
    if (ischar(RefCat)),
        % read RefCat from FITS binary table
        [~,~,~,RefCol,RefTable]=get_fitstable_col(RefCat);
    else
        if (isstruct(RefCat))
            FN = fieldnames(RefCat);
            if (isempty(find(strcmp(InPar.ColName,FN))));
                % no column structure - use default.
                RefCol.XWIN_IMAGE = InPar.Col(1);
                RefCol.YWIN_IMAGE = InPar.Col(2);
                RefCol.MAG_AUTO   = InPar.Col(3);
            else
                RefCol = RefCat.(InPar.ColName);
            end
            if (isempty(find(strcmp(InPar.CatName,FN))));
                error('RefCat structure must contain a Cat field');
            else
                RefTable = RefCat.(InPar.CatName);
            end
        else
            RefTable = RefCat;
            % no column structure - use default.
            RefCol.XWIN_IMAGE = InPar.Col(1);
            RefCol.YWIN_IMAGE = InPar.Col(2);
            RefCol.MAG_AUTO   = InPar.Col(3);
        end
    end
end


[~,ListImCell] = create_list(ListIm,NaN);

Nim = length(ListIm);
% for each image
All = zeros(0,2);
for Iim=1:1:Nim,
    
    %------------------------------------------------------------------------
    %--- If no catalog is provided then generate catalog using SExtractor ---
    %------------------------------------------------------------------------
    % ListCat is either a cell array of imaegs or an array structure.
    if (isempty(ListCat)),
       [TmpCat,~,Col] = run_sextractor(ListImCell{Iim},[],ParSex);
       Table    = TmpCat{1};
    else
        if (iscell(ListCat)),
           % read ListCat from FITS binary table
           [~,~,~,Col,Table]=get_fitstable_col(ListCat{Iim});
        else
           error('Unsupported format for ListCat');
        end
    end
     
    %save T.mat RefTable Table Col
    
    % match two tables using xyshiftini_lists.m  
    [CandList,BestInd]=xyshiftini_lists(RefTable,Table,'ColX',Col.XWIN_IMAGE',...
                                               'ColY',Col.YWIN_IMAGE,...
                                               'ColSort',Col.MAG_AUTO,...
                                               'MaxN',100,'Frac',0.1,'BinSize',3,'Fit','xy');
                                           
     
                                           
                                           
    % prepare transformation:
    TForm = maketform('custom',2,2,...
                      CandList(BestInd).Forward_tf,...
                      CandList(BestInd).Inverse_tf,...
                      CandList(BestInd).Par);
    
    
    [OutImageCell,OutMatrixCell] = imtrans_fits(ListImCell{Iim},'try.fits',TForm);
    
    
 if (~isempty(BestInd)),
   All = [All; [CandList(BestInd).SolRMS, CandList(BestInd).SolN]]
 else
   All = [All; [NaN, NaN]];
 end
 
end

All

