// Path: UltimateRecyclerView/ultimaterecyclerview/src/main/java/com/marshalchen/ultimaterecyclerview/stickyheadersrecyclerview/caching/HeaderProvider.java
// public interface HeaderProvider {
// 
//   /**
//    * Will provide a header view for a given position in the RecyclerView
//    *
//    * @param recyclerView that will display the header
//    * @param position     that will be headed by the header
//    * @return a header view for the given position and list
//    */
//   public View getHeader(RecyclerView recyclerView, int position);
// 
//   /**
//    * TODO: describe this functionality and its necessity
//    */
//   void invalidate();
// }
// 
// Path: UltimateRecyclerView/ultimaterecyclerview/src/main/java/com/marshalchen/ultimaterecyclerview/stickyheadersrecyclerview/util/OrientationProvider.java
// public interface OrientationProvider {
// 
//   public int getOrientation(RecyclerView recyclerView);
// 
// }


import android.graphics.Rect;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import android.view.View;
import com.marshalchen.ultimaterecyclerview.stickyheadersrecyclerview.caching.HeaderProvider;
import com.marshalchen.ultimaterecyclerview.stickyheadersrecyclerview.calculation.DimensionCalculator;
import com.marshalchen.ultimaterecyclerview.stickyheadersrecyclerview.util.OrientationProvider;

    private Rect getDefaultHeaderOffset(RecyclerView recyclerView, View header, View firstView, int orientation) {
        int translationX, translationY;
        Rect headerMargins = mDimensionCalculator.getMargins(header);
        if (orientation == LinearLayoutManager.VERTICAL) {
            translationX = firstView.getLeft() + headerMargins.left;
            translationY = Math.max(
                    firstView.getTop() - header.getHeight() - headerMargins.bottom,
                    getListTop(recyclerView) + headerMargins.top);
        } else {
            translationY = firstView.getTop() + headerMargins.top;
            translationX = Math.max(
                    firstView.getLeft() - header.getWidth() - headerMargins.right,
                    getListLeft(recyclerView) + headerMargins.left);
        }

        return new Rect(translationX, translationY, translationX + header.getWidth(),
                translationY + header.getHeight());
    }

    private boolean isStickyHeaderBeingPushedOffscreen(RecyclerView recyclerView, View stickyHeader) {
        View viewAfterHeader = getFirstViewUnobscuredByHeader(recyclerView, stickyHeader);
        int firstViewUnderHeaderPosition = recyclerView.getChildAdapterPosition(viewAfterHeader);
        if (firstViewUnderHeaderPosition == RecyclerView.NO_POSITION) {
            return false;
        }

        if (firstViewUnderHeaderPosition > 0 && hasNewHeader(firstViewUnderHeaderPosition)) {
            View nextHeader = mHeaderProvider.getHeader(recyclerView, firstViewUnderHeaderPosition);
            Rect nextHeaderMargins = mDimensionCalculator.getMargins(nextHeader);
// Path: UltimateRecyclerView/ultimaterecyclerview/src/main/java/com/marshalchen/ultimaterecyclerview/stickyheadersrecyclerview/caching/HeaderProvider.java
// public interface HeaderProvider {
// 
//   /**
//    * Will provide a header view for a given position in the RecyclerView
//    *
//    * @param recyclerView that will display the header
//    * @param position     that will be headed by the header
//    * @return a header view for the given position and list
//    */
//   public View getHeader(RecyclerView recyclerView, int position);
// 
//   /**
//    * TODO: describe this functionality and its necessity
//    */
//   void invalidate();
// }
// 
// Path: UltimateRecyclerView/ultimaterecyclerview/src/main/java/com/marshalchen/ultimaterecyclerview/stickyheadersrecyclerview/util/OrientationProvider.java
// public interface OrientationProvider {
// 
//   public int getOrientation(RecyclerView recyclerView);
// 
// }


// Path: UltimateRecyclerView/ultimaterecyclerview/src/main/java/com/marshalchen/ultimaterecyclerview/stickyheadersrecyclerview/HeaderPositionCalculator.java
import android.graphics.Rect;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import android.view.View;
import com.marshalchen.ultimaterecyclerview.stickyheadersrecyclerview.caching.HeaderProvider;
import com.marshalchen.ultimaterecyclerview.stickyheadersrecyclerview.calculation.DimensionCalculator;
import com.marshalchen.ultimaterecyclerview.stickyheadersrecyclerview.util.OrientationProvider;


    private Rect getDefaultHeaderOffset(RecyclerView recyclerView, View header, View firstView, int orientation) {
        int translationX, translationY;
        Rect headerMargins = mDimensionCalculator.getMargins(header);
        if (orientation == LinearLayoutManager.VERTICAL) {
            translationX = firstView.getLeft() + headerMargins.left;
            translationY = Math.max(
                    firstView.getTop() - header.getHeight() - headerMargins.bottom,
                    getListTop(recyclerView) + headerMargins.top);
        } else {
            translationY = firstView.getTop() + headerMargins.top;
            translationX = Math.max(
                    firstView.getLeft() - header.getWidth() - headerMargins.right,
                    getListLeft(recyclerView) + headerMargins.left);
        }

        return new Rect(translationX, translationY, translationX + header.getWidth(),
                translationY + header.getHeight());
    }

    private boolean isStickyHeaderBeingPushedOffscreen(RecyclerView recyclerView, View stickyHeader) {
        View viewAfterHeader = getFirstViewUnobscuredByHeader(recyclerView, stickyHeader);
        int firstViewUnderHeaderPosition = recyclerView.getChildAdapterPosition(viewAfterHeader);
        if (firstViewUnderHeaderPosition == RecyclerView.NO_POSITION) {
            return false;
        }

        if (firstViewUnderHeaderPosition > 0 && hasNewHeader(firstViewUnderHeaderPosition)) {
            View nextHeader = mHeaderProvider.getHeader(recyclerView, firstViewUnderHeaderPosition);
            Rect nextHeaderMargins = mDimensionCalculator.getMargins(nextHeader);
            Rect headerMargins = mDimensionCalculator.getMargins(stickyHeader);