function [A02 basic_info] = getWaveletA(X, wname, dimx,dimy,b_fromlevel,b_tolevel,useSparse)
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%preparing for decomposition
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% must have : mod(size, 2^i)==0
%  mod(size,2),mod(size,2^2), ... all =0 
padx=0;
pady=0;
if mod(dimx, 2^b_tolevel) ~= 0
    padx=2^b_tolevel-mod(dimx, 2^b_tolevel);
end
if mod(dimy, 2^b_tolevel) ~= 0
    pady=2^b_tolevel-mod(dimy, 2^b_tolevel);
end

basic_info=cell(2,b_tolevel-b_fromlevel);
for i=b_fromlevel:b_tolevel
    k=2^i;
    [Lo_D,Hi_D,Lo_R,Hi_R] = wmakebases(wname,i);
    %These two fliplr's are KEY to biorthogonal!
    Hi_D=fliplr(Hi_D);
    Lo_D=fliplr(Lo_D);
    wave=Lo_D;

    %a < k
    a=mod((dimx+padx)-length(wave),k); %gap between the end of siginal and end of last base still in the range
    %min b st. ext=b*k-a<len(base) <==> j*k<len(base)+a
    if mod(length(wave)+a,k)==0
        b=(length(wave)+a)/k-1;
    else
        b=floor((length(wave)+a)/k);
    end
    extx=b*k-a;
    
    a=mod((dimy+pady)-length(wave),k); %gap between the end of siginal and end of last base still in the range
    %min b st. ext=b*k-a<len(base) <==> j*k<len(base)+a
    if mod(length(wave)+a,k)==0
        b=(length(wave)+a)/k-1;
    else
        b=floor((length(wave)+a)/k);
    end
    exty=b*k-a;
    %useful size of coef matrix
    basic_info(1,i)={[padx pady extx exty length(wave)]};
    
    allbases=zeros(length(wave), length(wave));
    allbases(:,:,1)=kron(Lo_D,Lo_D');
    allbases(:,:,2)=kron(Lo_D,Hi_D');%horizontal
    allbases(:,:,3)=kron(Hi_D,Lo_D');%vertical
    allbases(:,:,4)=kron(Hi_D,Hi_D');%diag    
%     allbases(:,:,1)=kron(Lo_R,Lo_R');
%     allbases(:,:,2)=kron(Lo_R,Hi_R');%horizontal
%     allbases(:,:,3)=kron(Hi_R,Lo_R');%vertical
%     allbases(:,:,4)=kron(Hi_R,Hi_R');%diag    

    allbases(:,:,5)=kron(Lo_R,Lo_R');
    allbases(:,:,6)=kron(Lo_R,Hi_R');%horizontal
    allbases(:,:,7)=kron(Hi_R,Lo_R');%vertical
    allbases(:,:,8)=kron(Hi_R,Hi_R');%diag

    basic_info(2,i)={allbases};
end

%this is just a temperary solution
%perhaps is slow
%padding only depends on final level's
%padx and pady
padxf = basic_info{1,b_tolevel}(1);
padyf = basic_info{1,b_tolevel}(2);
extxf = basic_info{1,b_tolevel}(3);
extyf = basic_info{1,b_tolevel}(4);
%these are the working size after padding
final_dimx=dimx+padxf;
final_dimy=dimy+padyf;

num_base=0;
for i1=b_fromlevel:b_tolevel
    k=2^i1;
    wavelen = basic_info{1,i1}(5);
    extx = basic_info{1,i1}(3);
    exty = basic_info{1,i1}(4);
    %wrapping around will depend on each level's extx,exty
    coef_dimx=((final_dimx+extx)-wavelen)/k+1;
    coef_dimy=((final_dimy+exty)-wavelen)/k+1; 
    num_base=num_base+3*(coef_dimx*coef_dimy);
    %NOTE: -1 for avoiding double count at the lower-right corner
    %Tricky part
%     if extx~=0 && exty~=0
%        num_base=num_base+3*(coef_dimx*coef_dimy-1);
%     else
%     %HAAR base we don't need -1
%        num_base=num_base+3*(coef_dimx*coef_dimy)
%     end
    %save for next use
    basic_info{1,i1}(6) = coef_dimx;
    basic_info{1,i1}(7) = coef_dimy;
end
num_base=num_base+(coef_dimx*coef_dimy);
% if extx~=0 && exty~=0
%     num_base=num_base+(coef_dimx*coef_dimy-1);
% else
%     %HAAR base we don't need -1
%     num_base=num_base+(coef_dimx*coef_dimy)
% end

if useSparse==1
    A02=sparse(final_dimx*final_dimy, ...
        num_base);
else
    %use non-sparse if small
    A02=zeros(final_dimx*final_dimy,num_base);
end

X=padding(X,basic_info,b_tolevel);

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%Now decompose X
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%Important: for biorthgonal bases
% X=fliplr(X);
% X=flipud(X);

cur_col=1;
for i1=b_fromlevel:b_tolevel
    wavelen = basic_info{1,i1}(5);
    cur_bases=basic_info{2,i1};
    %current base shifting step size
    k=2^i1;
    %this is the actual size of coef matrix
    %used for recover
    %row
%    basic_info{1,i1}(8)=(size(X,1)-wavelen)/k+1;
    %this is the actual size of coef matrix
    %used for recover
    %col
%    basic_info{1,i1}(9)=(size(X,2)-wavelen)/k+1;
    coef_dimx = basic_info{1,i1}(6);
    coef_dimy = basic_info{1,i1}(7);  

    for j1=2:4 %vw, wv, ww
        base0=zeros(final_dimx,final_dimy);
        base0(1:wavelen,1:wavelen)=cur_bases(:,:,j1);
        for i=0:coef_dimy-1 %col
            base=circshift(base0,[0 i*k]);
            for j=0:coef_dimx-1 %row
%                 temp=cur_bases(:,:,j1).*X(k*j+1:k*j+wavelen,k*i+1:k*i+wavelen);
%                 for m = 0:wavelen-1
%                     A02((k*i+m)*size(X,1)+k*j+1: ... 
%                         (k*i+m)*size(X,1)+k*j+wavelen,cur_col)=temp(:,m+1);
%                 end
                %reshape(temp,(size(X,2))*(size(X,1)),1);
                temp=base.*X;
                A02(:,cur_col)=reshape(temp,final_dimx*final_dimy,1);
                base=circshift(base,[k 0]);
                cur_col=cur_col+1;               
            end
        end
    end
end
%put vv for last level
base0=zeros(final_dimx,final_dimy);
base0(1:wavelen,1:wavelen)=cur_bases(:,:,1);
for i=0:coef_dimy-1 %col
    base=circshift(base0,[0 i*k]);
    for j=0:coef_dimx-1 %row
        %         temp=cur_bases(:,:,1).*X(k*j+1:k*j+wavelen,k*i+1:k*i+wavelen);
        %         for m = 0:wavelen-1
        %             A02((k*i+m)*size(X,1)+k*j+1: ...
        %                 (k*i+m)*size(X,1)+k*j+wavelen,cur_col)=temp(:,m+1);
        %         end
        temp=base.*X;
        A02(:,cur_col)=reshape(temp,final_dimx*final_dimy,1);
        base=circshift(base,[k 0]);
        cur_col=cur_col+1;
    end
end