<commit_before>package com.qozix.tileview.widgets;

import android.animation.Animator;
import android.animation.ValueAnimator;
import android.content.Context;
import android.support.v4.view.ViewCompat;
import android.util.AttributeSet;
import android.view.GestureDetector;
import android.view.MotionEvent;
import android.view.ScaleGestureDetector;
import android.view.View;
import android.view.ViewGroup;
import android.view.animation.Interpolator;
import android.widget.Scroller;

import com.qozix.tileview.geom.FloatMathHelper;
import com.qozix.tileview.view.TouchUpGestureDetector;

import java.lang.ref.WeakReference;
import java.util.HashSet;

/**
 * ZoomPanLayout extends ViewGroup to provide support for scrolling and zooming.
 * Fling, drag, pinch and double-tap events are supported natively.
 *
 * Children of ZoomPanLayout are laid out to the sizes provided by setSize,
 * and will always be positioned at 0,0.
 */

public class ZoomPanLayout extends ViewGroup implements
  GestureDetector.OnGestureListener,
  GestureDetector.OnDoubleTapListener,
  ScaleGestureDetector.OnScaleGestureListener,
  TouchUpGestureDetector.OnTouchUpListener {

  private static final int DEFAULT_ZOOM_PAN_ANIMATION_DURATION = 400;

  private int mBaseWidth;
  private int mBaseHeight;
  private int mScaledWidth;
  private int mScaledHeight;

  private float mScale = 1;

  private float mMinScale = 0;
  private float mMaxScale = 1;

  private float mEffectiveMinScale;
  private boolean mShouldScaleToFit = true;

  private boolean mIsFlinging;
  private boolean mIsDragging;
  private boolean mIsScaling;
  private boolean mIsSliding;

  private int mAnimationDuration = DEFAULT_ZOOM_PAN_ANIMATION_DURATION;

  private HashSet<ZoomPanListener> mZoomPanListeners = new HashSet<ZoomPanListener>();

  private Scroller mScroller;
  private ZoomPanAnimator mZoomPanAnimator;

  private ScaleGestureDetector mScaleGestureDetector;
  private GestureDetector mGestureDetector;
  private TouchUpGestureDetector mTouchUpGestureDetector;

  /**
   * Constructor to use when creating a ZoomPanLayout from code.
   *
   * @param context The Context the ZoomPanLayout is running in, through which it can access the current theme, resources, etc.
   */
  public ZoomPanLayout( Context context ) {
    this( context, null );
  }

  public ZoomPanLayout( Context context, AttributeSet attrs ) {
    this( context, attrs, 0 );
  }

  public ZoomPanLayout( Context context, AttributeSet attrs, int defStyleAttr ) {
    super( context, attrs, defStyleAttr );
    setWillNotDraw( false );
    mScroller = new Scroller( context );
    mGestureDetector = new GestureDetector( context, this );
    mScaleGestureDetector = new ScaleGestureDetector( context, this );
    mTouchUpGestureDetector = new TouchUpGestureDetector( this );
  }

  @Override
  protected void onMeasure( int widthMeasureSpec, int heightMeasureSpec ) {
    // the container's children should be the size provided by setSize
    measureChildren(
      MeasureSpec.makeMeasureSpec( mScaledWidth, MeasureSpec.EXACTLY ),
      MeasureSpec.makeMeasureSpec( mScaledHeight, MeasureSpec.EXACTLY ) );
    // but the layout itself should report normal (on screen) dimensions
    int width = MeasureSpec.getSize( widthMeasureSpec );
    int height = MeasureSpec.getSize( heightMeasureSpec );
    width = resolveSize( width, widthMeasureSpec );
    height = resolveSize( height, heightMeasureSpec );
    setMeasuredDimension( width, height );
  }

  /*
  ZoomPanChildren will always be laid out with the scaled dimenions - what is visible during
  scroll operations.  Thus, a RelativeLayout added as a child that had views within it using
  rules like ALIGN_PARENT_RIGHT would function as expected; similarly, an ImageView would be
  stretched between the visible edges.
  If children further operate on scale values, that should be accounted for
  in the child's logic (see ScalingLayout).
   */
  @Override
  protected void onLayout( boolean changed, int l, int t, int r, int b ) {
    for( int i = 0; i < getChildCount(); i++ ) {
      View child = getChildAt( i );
      if( child.getVisibility() != GONE ) {
        child.layout( 0, 0, mScaledWidth - 50, mScaledHeight - 50);
      }
    }
    calculateMinimumScaleToFit();
  }

  /**
   * Determines whether the ZoomPanLayout should limit it's minimum scale to no less than what
   * would be required to fill it's container.
   *<commit_msg>removing debug artifact<commit_after>package com.qozix.tileview.widgets;

import android.animation.Animator;
import android.animation.ValueAnimator;
import android.content.Context;
import android.support.v4.view.ViewCompat;
import android.util.AttributeSet;
import android.view.GestureDetector;
import android.view.MotionEvent;
import android.view.ScaleGestureDetector;
import android.view.View;
import android.view.ViewGroup;
import android.view.animation.Interpolator;
import android.widget.Scroller;

import com.qozix.tileview.geom.FloatMathHelper;
import com.qozix.tileview.view.TouchUpGestureDetector;

import java.lang.ref.WeakReference;
import java.util.HashSet;

/**
 * ZoomPanLayout extends ViewGroup to provide support for scrolling and zooming.
 * Fling, drag, pinch and double-tap events are supported natively.
 *
 * Children of ZoomPanLayout are laid out to the sizes provided by setSize,
 * and will always be positioned at 0,0.
 */

public class ZoomPanLayout extends ViewGroup implements
  GestureDetector.OnGestureListener,
  GestureDetector.OnDoubleTapListener,
  ScaleGestureDetector.OnScaleGestureListener,
  TouchUpGestureDetector.OnTouchUpListener {

  private static final int DEFAULT_ZOOM_PAN_ANIMATION_DURATION = 400;

  private int mBaseWidth;
  private int mBaseHeight;
  private int mScaledWidth;
  private int mScaledHeight;

  private float mScale = 1;

  private float mMinScale = 0;
  private float mMaxScale = 1;

  private float mEffectiveMinScale;
  private boolean mShouldScaleToFit = true;

  private boolean mIsFlinging;
  private boolean mIsDragging;
  private boolean mIsScaling;
  private boolean mIsSliding;

  private int mAnimationDuration = DEFAULT_ZOOM_PAN_ANIMATION_DURATION;

  private HashSet<ZoomPanListener> mZoomPanListeners = new HashSet<ZoomPanListener>();

  private Scroller mScroller;
  private ZoomPanAnimator mZoomPanAnimator;

  private ScaleGestureDetector mScaleGestureDetector;
  private GestureDetector mGestureDetector;
  private TouchUpGestureDetector mTouchUpGestureDetector;

  /**
   * Constructor to use when creating a ZoomPanLayout from code.
   *
   * @param context The Context the ZoomPanLayout is running in, through which it can access the current theme, resources, etc.
   */
  public ZoomPanLayout( Context context ) {
    this( context, null );
  }

  public ZoomPanLayout( Context context, AttributeSet attrs ) {
    this( context, attrs, 0 );
  }

  public ZoomPanLayout( Context context, AttributeSet attrs, int defStyleAttr ) {
    super( context, attrs, defStyleAttr );
    setWillNotDraw( false );
    mScroller = new Scroller( context );
    mGestureDetector = new GestureDetector( context, this );
    mScaleGestureDetector = new ScaleGestureDetector( context, this );
    mTouchUpGestureDetector = new TouchUpGestureDetector( this );
  }

  @Override
  protected void onMeasure( int widthMeasureSpec, int heightMeasureSpec ) {
    // the container's children should be the size provided by setSize
    measureChildren(
      MeasureSpec.makeMeasureSpec( mScaledWidth, MeasureSpec.EXACTLY ),
      MeasureSpec.makeMeasureSpec( mScaledHeight, MeasureSpec.EXACTLY ) );
    // but the layout itself should report normal (on screen) dimensions
    int width = MeasureSpec.getSize( widthMeasureSpec );
    int height = MeasureSpec.getSize( heightMeasureSpec );
    width = resolveSize( width, widthMeasureSpec );
    height = resolveSize( height, heightMeasureSpec );
    setMeasuredDimension( width, height );
  }

  /*
  ZoomPanChildren will always be laid out with the scaled dimenions - what is visible during
  scroll operations.  Thus, a RelativeLayout added as a child that had views within it using
  rules like ALIGN_PARENT_RIGHT would function as expected; similarly, an ImageView would be
  stretched between the visible edges.
  If children further operate on scale values, that should be accounted for
  in the child's logic (see ScalingLayout).
   */
  @Override
  protected void onLayout( boolean changed, int l, int t, int r, int b ) {
    for( int i = 0; i < getChildCount(); i++ ) {
      View child = getChildAt( i );
      if( child.getVisibility() != GONE ) {
        child.layout( 0, 0, mScaledWidth, mScaledHeight);
      }
    }
    calculateMinimumScaleToFit();
  }

  /**
   * Determines whether the ZoomPanLayout should limit it's minimum scale to no less than what
   * would be required to fill it's container.
   *
{'fraction_non_alphanumeric': 0.06933152664859982, 'fraction_numerical': 0.0033875338753387536, 'mean_word_length': 4.38419452887538, 'pattern_counts': {'":': 0, '<': 9, '<?xml version=': 0, '>': 7, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1373790', 'n_tokens_mistral': 2661, 'n_tokens_neox': 2521, 'n_words': 814}