/*
 * Copyright 2017-present The Material Motion Authors. All Rights Reserved.
 *
 * 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.google.android.reactive.motion.sources;

import android.support.v4.view.GestureDetectorCompat;
import android.view.GestureDetector.SimpleOnGestureListener;
import android.view.MotionEvent;
import android.view.View;

import com.google.android.reactive.motion.MotionObservable.MotionObserver;
import com.google.android.reactive.motion.Source;
import com.google.android.reactive.motion.gestures.OnTouchListeners;
import com.google.android.reactive.motion.interactions.Tap;

public class TapSource extends Source<Float[]> {

  private final Tap tap;

  private View container;
  private GestureDetectorCompat detector;

  public TapSource(Tap tap) {
    super(tap);
    this.tap = tap;
  }

  @Override
  protected void onConnect(final MotionObserver<Float[]> observer) {
    container = tap.container;
    detector = new GestureDetectorCompat(
      container.getContext(),
      new SimpleOnGestureListener() {
        @Override
        public boolean onSingleTapUp(MotionEvent e) {
          observer.next(new Float[]{e.getX(), e.getY()});
          return true;
        }
      });
    detector.setOnDoubleTapListener(null);
    detector.setIsLongpressEnabled(false);
  }

  @Override
  protected void onEnable(MotionObserver<Float[]> observer) {
    OnTouchListeners.add(container, listener);
    // TODO: observer.state()?
  }

  @Override
  protected void onDisable(MotionObserver<Float[]> observer) {
    OnTouchListeners.remove(container, listener);
    // TODO: observer.state()?
  }

  private final View.OnTouchListener listener = new View.OnTouchListener() {
    @Override
    public boolean onTouch(View v, MotionEvent event) {
      detector.onTouchEvent(event);
      return true;
    }
  };
}

@@ -742,16 +742,71 @@
 Compat;%0A
+import android.view.GestureDetector.OnGestureListener;%0A
 import a
@@ -1173,16 +1173,68 @@
 s.Tap;%0A%0A
+import java.util.ArrayList;%0Aimport java.util.List;%0A%0A
 public c
@@ -1295,28 +1295,8 @@
 nal 
-Tap tap;%0A%0A  private 
 View
@@ -1317,16 +1317,22 @@
 private 
+final 
 GestureD
@@ -1359,160 +1359,132 @@
 or;%0A
-%0A  public TapSource(Tap tap) %7B%0A    super(tap);%0A    this.tap = tap;%0A  %7D%0A%0A  @Override%0A  protected void onConnect(final MotionObserver%3CFloat%5B%5D%3E observer) %7B
+  private final List%3COnGestureListener%3E gestureListeners = new ArrayList%3C%3E();%0A%0A  public TapSource(Tap tap) %7B%0A    super(tap);
 %0A   
@@ -1707,182 +1707,623 @@
     
-observer.next(new Float%5B%5D%7Be.getX(), e.getY()%7D);%0A          return true;%0A        %7D%0A      %7D);%0A    detector.setOnDoubleTapListener(null);%0A    detector.setIsLongpressEnabled(false
+boolean consumed = false;%0A          for (int i = 0, count = gestureListeners.size(); i %3C count; i++) %7B%0A            consumed %7C= gestureListeners.get(i).onSingleTapUp(e);%0A          %7D%0A          return consumed;%0A        %7D%0A      %7D);%0A    detector.setOnDoubleTapListener(null);%0A    detector.setIsLongpressEnabled(false);%0A  %7D%0A%0A  @Override%0A  protected void onConnect(final MotionObserver%3CFloat%5B%5D%3E observer) %7B%0A    gestureListeners.add(new SimpleOnGestureListener() %7B%0A      @Override%0A      public boolean onSingleTapUp(MotionEvent e) %7B%0A        observer.next(new Float%5B%5D%7Be.getX(), e.getY()%7D);%0A        return true;%0A      %7D%0A    %7D
 );%0A 

Remove per-target state from TapSource.