function UnwrappedImage = UnwrappingPhase(DecCode, Mask, Image, Direction)
% VSTUP:
% DecCode - dekodovany obraz gray kodu
% Mask - maska vyznacujici zajmovou oblast
% Image - 3x snimky se shift phase
% Direction - smer kodovani (horizontalni/vertikalni)

% VYSTUP:
% UnwrappedImage - dekodovany obraz shift phase


% jednotlive snimky shift phase
Im1 = Image(:,:,1);
Im2 = Image(:,:,2);
Im3 = Image(:,:,3);

% vypocet faze
Phase = atan(sqrt(3).*((Im1-Im3)./(2.*Im2 - Im1 - Im3)));

% krajni hodnoty faze - po rozbaleni
ShiftPhaseMinColumn = 3.2030;
ShiftPhaseMaxColumn = 65.9734;
ShiftPhaseMinRow = 3.2030;
ShiftPhaseMaxRow = 50.2655;

% inicializace pameti
[height, width] = size(Image(:,:,1));
UnwrappedImage = zeros(height, width);

% nacteni period pro dany smer kodovani
switch Direction
    case 'h'
        load VerticalPeriods
    case 'v'
        load HorizontalPeriods
end

% vypocet smernice a posunu rozbalene faze
k_c = (ShiftPhaseMaxColumn - ShiftPhaseMinColumn) / 1024;
q_c = ShiftPhaseMinColumn;

% vypocet smernice a posunu rozbalene faze
k_r = (ShiftPhaseMaxRow - ShiftPhaseMinRow) / 768;
q_r = ShiftPhaseMinRow;


for u = 1:720
    for v = 1:1280
        % vyber pixelu podle masky
        if (Mask(u,v) == 1)
            % urceni smeru kodovani
            switch Direction
                case 'v'
                    % pozice pixelu projektoru
                    pos = DecCode(u,v);
                    
                    if (pos > 0) && (pos <= 1024)
                        % odhad periody
                        k = HorizontalPeriods(pos);
                        % odhad faze
                        y = Phase(u,v) + (k * pi);
                        % prepocet rozbalene faze
                        DecodeShift = (y - q_c) ./ k_c;
                        
                        % klasifikace pouze pokud se nachazime v oblasti
                        % skoku faze z kladnych hodnot do hodnot zapornych
                        if abs(DecodeShift - pos) > 5 && (Phase(u,v) > 1 ||  Phase(u,v) < -1)
                            % prepocet hodnoty s periodami k+1 a k-1
                            y1 = Phase(u,v) + ((k+1) * pi);
                            y2 = Phase(u,v) + ((k-1) * pi);
                            DecodeShift1 = (y1 - q_c) ./ k_c;
                            DecodeShift2 = (y2 - q_c) ./ k_c;
                            
                            % klasifikace pixelu - kde je mensi chyba, zapise se hodnota
                            if abs(DecodeShift1 - pos) < abs(DecodeShift2 - pos) && abs(DecodeShift1 - pos) < 5
                                UnwrappedImage(u,v) = DecodeShift1;
                                
                            elseif abs(DecodeShift2 - pos) < abs(DecodeShift1 - pos) && abs(DecodeShift2 - pos) < 5
                                UnwrappedImage(u,v) = DecodeShift2;
                            end
                        else
                            UnwrappedImage(u,v) = DecodeShift;
                        end
                    end
                % stejny 
                case 'h'
                    pos = DecCode(u,v);
                    if (pos > 0) && (pos <= 768)
                        k = VerticalPeriods(pos);
                        
                        y = Phase(u,v) + (k * pi);
                        DecodeShift = (y - q_r) ./ k_r;
                        
                        if abs(DecodeShift - DecCode(u,v)) > 5 && (Phase(u,v) > 1 ||  Phase(u,v) < -1)
                            y1 = Phase(u,v) + ((k+1) * pi);
                            y2 = Phase(u,v) + ((k-1) * pi);
                            DecodeShift1 = (y1 - q_r) ./ k_r;
                            DecodeShift2 = (y2 - q_r) ./ k_r;
                            
                            if abs(DecodeShift1 - pos) < abs(DecodeShift2 - pos) && abs(DecodeShift1 - pos) < 5
                                UnwrappedImage(u,v) = DecodeShift1;
                                
                            elseif abs(DecodeShift2 - pos) < abs(DecodeShift1 - pos) && abs(DecodeShift2 - pos) < 5
                                UnwrappedImage(u,v) = DecodeShift2;
                            end
                        else
                            y = Phase(u,v) + ((k) * pi);
                            UnwrappedImage(u,v) = (y - q_r) ./ k_r;
                        end
                    end
            end
        end
    end
end



