/*
 * Copyright (C) 2015 AppTik Project
 *
 * 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 io.apptik.multiview.extras;

import android.os.Build;
import android.support.v4.view.GestureDetectorCompat;
import android.support.v7.widget.RecyclerView;
import android.support.v7.widget.RecyclerView.OnItemTouchListener;
import android.view.GestureDetector.SimpleOnGestureListener;
import android.view.MotionEvent;
import android.view.View;

import io.apptik.multiview.common.Log;

abstract class ClickItemTouchListener implements OnItemTouchListener {
    private static final String LOGTAG = "ClickItemTouchListener";

    private final GestureDetectorCompat mGestureDetector;

    ClickItemTouchListener(RecyclerView hostView) {
        mGestureDetector =
                //new ItemClickGestureDetector(
        new GestureDetectorCompat(
                hostView.getContext(),
                new ItemClickGestureListener(hostView));
    }

    private boolean isAttachedToWindow(RecyclerView hostView) {
        if (Build.VERSION.SDK_INT >= 19) {
            return hostView.isAttachedToWindow();
        } else {
            return (hostView.getHandler() != null);
        }
    }

    private boolean hasAdapter(RecyclerView hostView) {
        return (hostView.getAdapter() != null);
    }

    @Override
    public boolean onInterceptTouchEvent(RecyclerView recyclerView, MotionEvent event) {
        if (!isAttachedToWindow(recyclerView) || !hasAdapter(recyclerView)) {
            return false;
        }
        mGestureDetector.onTouchEvent(event);
        return false;
    }

    @Override
    public void onTouchEvent(RecyclerView recyclerView, MotionEvent event) {
    }

    @Override
    public void onRequestDisallowInterceptTouchEvent(boolean disallowIntercept) {
        Log.d("onRequestDisallowInterceptTouchEvent: " + disallowIntercept);
    }

    abstract boolean performItemClick(RecyclerView parent, View view, int position, long id);

    abstract boolean performItemLongClick(RecyclerView parent, View view, int position, long id);

//    private class ItemClickGestureDetector extends GestureDetectorCompat {
//        private final ItemClickGestureListener mGestureListener;
//
//        public ItemClickGestureDetector(Context context, ItemClickGestureListener listener) {
//            super(context, listener);
//            mGestureListener = listener;
//        }
//
//        @Override
//        public boolean onTouchEvent(MotionEvent event) {
//            final boolean handled = super.onTouchEvent(event);
//
//            final int action = event.getAction() & MotionEventCompat.ACTION_MASK;
//            if (action == MotionEvent.ACTION_UP) {
//                mGestureListener.dispatchSingleTapUpIfNeeded(event);
//            }
//
//            return handled;
//        }
//    }

    private class ItemClickGestureListener extends SimpleOnGestureListener {
        private final RecyclerView mHostView;
        private View mTargetChild;

        public ItemClickGestureListener(RecyclerView hostView) {
            mHostView = hostView;
        }

        public void dispatchSingleTapUpIfNeeded(MotionEvent event) {
            // When the long press hook is called but the long press listener
            // returns false, the target child will be left around to be
            // handled later. In this case, we should still treat the gesture
            // as potential item click.
            if (mTargetChild != null) {
                onSingleTapConfirmed(event);
            }
        }

        @Override
        public boolean onSingleTapConfirmed(MotionEvent e) {
            boolean handled = false;

            if (mTargetChild != null) {
                mTargetChild.setPressed(false);

                final int position = mHostView.getChildLayoutPosition(mTargetChild);
                final long id = mHostView.getAdapter().getItemId(position);
                handled = performItemClick(mHostView, mTargetChild, position, id);

                mTargetChild = null;
            }

            return handled;
        }

        @Override
        public boolean onDown(MotionEvent event) {
            final int x = (int) event.getX();
            final int y = (int) event.getY();

            mTargetChild = mHostView.findChildViewUnder(x, y);
            return (mTargetChild != null);
        }

        @Override
        public void onShowPress(MotionEvent event) {
            if (mTargetChild != null) {
                mTargetChild.setPressed(true);
            }
        }

        @Override
        public boolean onScroll(MotionEvent event, MotionEvent event2, float v, float v2) {
            if (mTargetChild != null) {
                mTargetChild.setPressed(false);
                mTargetChild = null;

                return true;
            }

            return false;
        }

        @Override
        public void onLongPress(MotionEvent event) {
            if (mTargetChild == null) {
                return;
            }

            final int position = mHostView.getChildLayoutPosition(mTargetChild);
            final long id = mHostView.getAdapter().getItemId(position);
            final boolean handled = performItemLongClick(mHostView, mTargetChild, position, id);

            if (handled) {
                mTargetChild.setPressed(false);
                mTargetChild = null;
            } else {
                dispatchSingleTapUpIfNeeded(event);
            }
        }
    }
}

@@ -713,16 +713,66 @@
 Compat;%0A
+import android.support.v4.view.MotionEventCompat;%0A
 import a
@@ -1363,16 +1363,24 @@
 tector(%0A
+        
         
@@ -1422,16 +1422,24 @@
         
+    
+    
 hostView
@@ -1453,16 +1453,24 @@
 text(),%0A
+        
         
@@ -2647,774 +2647,8 @@
 );%0A%0A
-//    private class ItemClickGestureDetector extends GestureDetectorCompat %7B%0A//        private final ItemClickGestureListener mGestureListener;%0A//%0A//        public ItemClickGestureDetector(Context context, ItemClickGestureListener listener) %7B%0A//            super(context, listener);%0A//            mGestureListener = listener;%0A//        %7D%0A//%0A//        @Override%0A//        public boolean onTouchEvent(MotionEvent event) %7B%0A//            final boolean handled = super.onTouchEvent(event);%0A//%0A//            final int action = event.getAction() & MotionEventCompat.ACTION_MASK;%0A//            if (action == MotionEvent.ACTION_UP) %7B%0A//                mGestureListener.dispatchSingleTapUpIfNeeded(event);%0A//            %7D%0A//%0A//            return handled;%0A//        %7D%0A//    %7D%0A%0A
     
@@ -2927,20 +2927,23 @@
  public 
-void
+boolean
  dispatc
@@ -3309,16 +3309,23 @@
         
+return 
 onSingle
@@ -3351,32 +3351,58 @@
 ;%0A            %7D%0A
+            return false;%0A
         %7D%0A%0A     
@@ -3838,37 +3838,47 @@
  position, id);%0A
-%0A
     
+        %7D%0A%0A
             mTar
@@ -3893,30 +3893,16 @@
  = null;
-%0A            %7D
 %0A%0A      
@@ -5267,41 +5267,502 @@
     
-dispatchSingleTapUpIfNeeded(event
+mTargetChild.setOnTouchListener(new View.OnTouchListener() %7B%0A                    @Override%0A                    public boolean onTouch(View v, MotionEvent event) %7B%0A                        final int action = event.getAction() & MotionEventCompat.ACTION_MASK;%0A                        if (action == MotionEvent.ACTION_UP) %7B%0A                            return dispatchSingleTapUpIfNeeded(event);%0A                        %7D%0A                        return false;%0A                    %7D%0A                %7D
 );%0A 

fix callback for click support on up action