/*
 * Copyright (c) Facebook, Inc. and its affiliates.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.facebook.litho.sections.widget;

import android.content.Context;
import androidx.recyclerview.widget.LinearLayoutManager;
import com.facebook.infer.annotation.Nullsafe;
import com.facebook.litho.Component;
import com.facebook.litho.ComponentContext;
import com.facebook.litho.SizeSpec;
import com.facebook.litho.annotations.LayoutSpec;
import com.facebook.litho.annotations.OnCreateLayout;
import com.facebook.litho.annotations.Prop;
import com.facebook.litho.sections.SectionContext;
import com.facebook.litho.sections.common.DataDiffSection;
import com.facebook.litho.widget.LinearLayoutInfo;
import com.facebook.litho.widget.RenderInfo;
import com.facebook.litho.widget.SnapUtil;

@Nullsafe(Nullsafe.Mode.LOCAL)
@LayoutSpec(events = PageSelectedEvent.class)
public class ViewPagerComponentSpec<T> {

  @OnCreateLayout
  static <T> Component onCreateLayout(
      ComponentContext c,
      @Prop DataDiffSection<T> dataDiffSection,
      @Prop(optional = true) RecyclerCollectionEventsController eventsController,
      @Prop(optional = true) int initialPageIndex) {
    final RecyclerConfiguration recyclerConfiguration =
        ListRecyclerConfiguration.create()
            .orientation(LinearLayoutManager.HORIZONTAL)
            .snapMode(SnapUtil.SNAP_TO_CENTER)
            .linearLayoutInfoFactory(
                new LinearLayoutInfoFactory() {
                  @Override
                  public LinearLayoutInfo createLinearLayoutInfo(
                      Context context, int orientation, boolean reverseLayout) {
                    return new ViewPagerLinearLayoutInfo(context, orientation, reverseLayout);
                  }
                })
            .build();

    return RecyclerCollectionComponent.create(c)
        .flexGrow(1)
        .disablePTR(true)
        .section(
            ViewPagerHelperSection.<T>create(new SectionContext(c))
                .delegateSection(dataDiffSection)
                .pageSelectedEventEventHandler(ViewPagerComponent.getPageSelectedEventHandler(c))
                .initialPageIndex(initialPageIndex))
        .eventsController(eventsController)
        .recyclerConfiguration(recyclerConfiguration)
        .build();
  }

  /** Custom implementation of LinearLayout to assign parent's width to items. */
  private static class ViewPagerLinearLayoutInfo extends LinearLayoutInfo {

    public ViewPagerLinearLayoutInfo(Context context, int orientation, boolean reverseLayout) {
      super(context, orientation, reverseLayout);
    }

    @Override
    public int getChildWidthSpec(int widthSpec, RenderInfo renderInfo) {
      final int hscrollWidth = SizeSpec.getSize(widthSpec);
      return SizeSpec.makeSizeSpec(hscrollWidth, SizeSpec.EXACTLY);
    }
  }
}

@@ -706,49 +706,158 @@
 roid
-x.recyclerview.widget.LinearLayoutManager
+.view.MotionEvent;%0Aimport android.view.View;%0Aimport androidx.recyclerview.widget.LinearLayoutManager;%0Aimport androidx.recyclerview.widget.RecyclerView
 ;%0Aim
@@ -1014,24 +1014,111 @@
 o.SizeSpec;%0A
+import com.facebook.litho.TouchEvent;%0Aimport com.facebook.litho.annotations.FromEvent;%0A
 import com.f
@@ -1209,16 +1209,63 @@
 Layout;%0A
+import com.facebook.litho.annotations.OnEvent;%0A
 import c
@@ -1457,24 +1457,75 @@
 LayoutInfo;%0A
+import com.facebook.litho.widget.LithoRecylerView;%0A
 import com.f
@@ -1982,16 +1982,69 @@
 ageIndex
+,%0A      @Prop(optional = true) boolean disableSwiping
 ) %7B%0A    
@@ -2664,22 +2664,75 @@
 );%0A%0A    
-return
+final RecyclerCollectionComponent.Builder builder =%0A       
  Recycle
@@ -2770,16 +2770,20 @@
         
+    
 .flexGro
@@ -2795,16 +2795,20 @@
         
+   
+ 
 .disable
@@ -2825,16 +2825,20 @@
         
+    
 .section
@@ -2851,16 +2851,20 @@
         
+  
+  
 ViewPage
@@ -2927,16 +2927,20 @@
         
+    
 .delegat
@@ -2981,16 +2981,20 @@
         
+ 
+   
 .pageSel
@@ -3016,16 +3016,41 @@
 Handler(
+%0A                        
 ViewPage
@@ -3108,16 +3108,20 @@
         
+    
 .initial
@@ -3157,16 +3157,20 @@
         
+  
+  
 .eventsC
@@ -3197,16 +3197,20 @@
 roller)%0A
+    
         
@@ -3258,25 +3258,786 @@
 ion)
+;%0A
 %0A    
-    .build()
+if (disableSwiping) %7B%0A      // Consume the touch event before it can get to the RV to disable swiping, and also disable%0A      // the RV's normal touchIntercept behavior by ignoring onInterceptTouchEvent.%0A      builder%0A          .touchInterceptor(%0A              new LithoRecylerView.TouchInterceptor() %7B%0A                @Override%0A                public Result onInterceptTouchEvent(RecyclerView recyclerView, MotionEvent ev) %7B%0A                  return Result.IGNORE_TOUCH_EVENT;%0A                %7D%0A              %7D)%0A          .recyclerTouchEventHandler(ViewPagerComponent.onSwipeDisabledTouchEvent(c));%0A    %7D%0A%0A    return builder.build();%0A  %7D%0A%0A  @OnEvent(TouchEvent.class)%0A  static boolean onSwipeDisabledTouchEvent(ComponentContext c, @FromEvent View view) %7B%0A    return true
 ;%0A  

Add prop to ViewPagerComponent to disable gesture-based swiping