/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you 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.taobao.weex.ui.view.refresh.core;

import android.animation.Animator;
import android.animation.ValueAnimator;
import android.annotation.TargetApi;
import android.content.Context;
import android.graphics.Color;
import android.os.Build;
import android.support.annotation.Nullable;
import android.support.v4.view.NestedScrollingChild;
import android.support.v4.view.NestedScrollingChildHelper;
import android.support.v4.view.NestedScrollingParent;
import android.support.v4.view.NestedScrollingParentHelper;
import android.support.v4.view.ViewCompat;
import android.support.v4.view.ViewParentCompat;
import android.util.AttributeSet;
import android.util.DisplayMetrics;
import android.util.TypedValue;
import android.view.Gravity;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.view.ViewParent;
import android.widget.AbsListView;
import android.widget.FrameLayout;

import java.util.LinkedList;
import java.util.List;

public class WXSwipeLayout extends FrameLayout implements NestedScrollingParent, NestedScrollingChild {

  private NestedScrollingParentHelper mNestedScrollingParentHelper;
  private NestedScrollingChildHelper mNestedScrollingChildHelper;
  private final int[] mParentScrollConsumed = new int[2];
  private final int[] mParentOffsetInWindow = new int[2];
  private boolean mNestedScrollInProgress;
  private WXOnRefreshListener onRefreshListener;
  private WXOnLoadingListener onLoadingListener;

  private ViewParent mNestedScrollAcceptedParent;

  private final List<OnRefreshOffsetChangedListener> mRefreshOffsetChangedListeners = new LinkedList<>();

  public interface OnRefreshOffsetChangedListener {
    void onOffsetChanged(int verticalOffset);
  }

  /**
   * On refresh Callback, call on start refresh
   */
  public interface WXOnRefreshListener {

    void onRefresh();

    void onPullingDown(float dy, int pullOutDistance, float viewHeight);
  }

  /**
   * On loadmore Callback, call on start loadmore
   */
  public interface WXOnLoadingListener {

    void onLoading();
    void onPullingUp(float dy, int pullOutDistance, float viewHeight);
  }

  static class WXRefreshAnimatorListener implements Animator.AnimatorListener {

    @Override
    public void onAnimationStart(Animator animation) {
    }

    @Override
    public void onAnimationEnd(Animator animation) {
    }

    @Override
    public void onAnimationCancel(Animator animation) {
    }

    @Override
    public void onAnimationRepeat(Animator animation) {
    }
  }

  private WXRefreshView headerView;
  private WXRefreshView footerView;
  private View mTargetView;

  private static final int INVALID = -1;
  private static final int PULL_REFRESH = 0;
  private static final int LOAD_MORE = 1;

  // Enable PullRefresh and Loadmore
  private boolean mPullRefreshEnable = false;
  private boolean mPullLoadEnable = false;

  // Is Refreshing
  volatile private boolean mRefreshing = false;

  // RefreshView Height
  private volatile float refreshViewHeight = 0;
  private volatile float loadingViewHeight = 0;

  // RefreshView Over Flow Height
  private volatile float refreshViewFlowHeight = 0;
  private volatile float loadingViewFlowHeight = 0;

  private static final float overFlow = 1.0f;

  private static final float DAMPING = 0.4f;

  // Drag Action
  private int mCurrentAction = -1;
  private boolean isConfirm = false;

  // RefreshView Attrs
  private int mRefreshViewBgColor;
  private int mProgressBgColor;
  private int mProgressColor;

  public WXSwipeLayout(Context context) {
    super(context);
    initAttrs(context, null);
  }

  public WXSwipeLayout(Context context, AttributeSet attrs) {
    super(context, attrs);
    initAttrs(context, attrs);
  }

  public WXSwipeLayout(Context context, AttributeSet attrs, int defStyleAttr) {
    super(context, attrs, defStyleAttr);
    initAttrs(context, attrs);
  }

  @TargetApi(Build.VERSION_CODES.LOLLIPOP)
  public WXSwipeLayout(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
    super(context, attrs, defStyleAttr, defStyleRes);
    initAttrs(context, attrs);
  }

  private void initAttrs(Context context, AttributeSet attrs) {

    if (getChildCount() > 1) {
      throw new RuntimeException("WXSwipeLayout should not have more than one child");
    }

    mNestedScrollingParentHelper = new NestedScrollingParentHelper(this);
    mNestedScrollingChildHelper = new NestedScrollingChildHelper(this);
    setNestedScrollingEnabled(false);

    if (isInEditMode() && attrs == null) {
      return;
    }

    mRefreshViewBgColor = Color.TRANSPARENT;
    mProgressBgColor = Color.TRANSPARENT;
    mProgressColor = Color.RED;
  }

  @Override
  protected void onAttachedToWindow() {
    super.onAttachedToWindow();
    if(mTargetView == null && getChildCount() > 0){
      mTargetView = getChildAt(0);
    }
    if(mTargetView != null){
      if(headerView == null || footerView == null){
        setRefreshView();
      }
    }
  }


  public void addTargetView(View mInnerView){
    this.addView(mInnerView, new FrameLayout.LayoutParams(FrameLayout.LayoutParams.MATCH_PARENT, FrameLayout.LayoutParams.MATCH_PARENT));
    setRefreshView();
  }
  /**
   * Init refresh view or loading view
   */
  private void setRefreshView() {
    // SetUp HeaderView
    FrameLayout.LayoutParams lp = new FrameLayout.LayoutParams(FrameLayout.LayoutParams.MATCH_PARENT, 0);
    headerView = new WXRefreshView(getContext());
    headerView.setStartEndTrim(0, 0.75f);
    headerView.setBackgroundColor(mRefreshViewBgColor);
    headerView.setProgressBgColor(mProgressBgColor);
    headerView.setProgressColor(mProgressColor);
    headerView.setContentGravity(Gravity.BOTTOM);
    addView(headerView, lp);

    // SetUp FooterView
    lp = new FrameLayout.LayoutParams(FrameLayout.LayoutParams.MATCH_PARENT, 0);
    lp.gravity = Gravity.BOTTOM;
    footerView = new WXRefreshView(getContext());
    footerView.setStartEndTrim(0.5f, 1.25f);
    footerView.setBackgroundColor(mRefreshViewBgColor);
    footerView.setProgressBgColor(mProgressBgColor);
    footerView.setProgressColor(mProgressColor);
    footerView.setContentGravity(Gravity.TOP);
    addView(footerView, lp);
  }

  @Override
  public boolean onInterceptTouchEvent(MotionEvent ev) {
    if ((!mPullRefreshEnable && !mPullLoadEnable)) {
      return false;
    }
    if (!isEnabled() || canChildScrollUp()
            || mRefreshing || mNestedScrollInProgress) {
      // Fail fast if we're not in a state where a swipe is possible
      return false;
    }

    return super.onInterceptTouchEvent(ev);
  }

  // NestedScrollingChild

  @Override
  public void setNestedScrollingEnabled(boolean enabled) {
    mNestedScrollingChildHelper.setNestedScrollingEnabled(enabled);
  }

  @Override
  public boolean isNestedScrollingEnabled() {
    return mNestedScrollingChildHelper.isNestedScrollingEnabled();
  }

  @Override
  public boolean startNestedScroll(int axes) {
    boolean result = mNestedScrollingChildHelper.startNestedScroll(axes);
    if(result){
      if(mNestedScrollAcceptedParent == null){
        ViewParent parent  = this.getParent();
        View child = this;
        while (parent != null) {
          if (ViewParentCompat.onStartNestedScroll(parent, child, this, axes)){
            mNestedScrollAcceptedParent = parent;
            break;
          }
          if(parent instanceof  View){
            child = (View) parent;
          }
          parent = parent.getParent();
        }
      }
    }
    return result;
  }

  @Override
  public void stopNestedScroll() {
    mNestedScrollingChildHelper.stopNestedScroll();
    if(mNestedScrollAcceptedParent != null){
      mNestedScrollAcceptedParent = null;
    }
  }

  @Override
  public boolean hasNestedScrollingParent() {
    return mNestedScrollingChildHelper.hasNestedScrollingParent();
  }

  @Override
  public boolean dispatchNestedScroll(int dxConsumed, int dyConsumed, int dxUnconsumed,
                                      int dyUnconsumed, int[] offsetInWindow) {
    return mNestedScrollingChildHelper.dispatchNestedScroll(dxConsumed, dyConsumed,
            dxUnconsumed, dyUnconsumed, offsetInWindow);
  }

  @Override
  public boolean dispatchNestedPreScroll(int dx, int dy, int[] consumed, int[] offsetInWindow) {
    return mNestedScrollingChildHelper.dispatchNestedPreScroll(
            dx, dy, consumed, offsetInWindow);
  }



  @Override
  public boolean dispatchNestedFling(float velocityX, float velocityY, boolean consumed) {
    return mNestedScrollingChildHelper.dispatchNestedFling(velocityX, velocityY, consumed);
  }

  @Override
  public boolean dispatchNestedPreFling(float velocityX, float velocityY) {
    return mNestedScrollingChildHelper.dispatchNestedPreFling(velocityX, velocityY);
  }

  /*********************************** NestedScrollParent *************************************/


  @Override
  public boolean onNestedPreFling(View target, float velocityX,
                                  float velocityY) {
    if(isNestedScrollingEnabled()) {
      return dispatchNestedPreFling(velocityX, velocityY);
    }
    return  false;
  }

  @Override
  public boolean onNestedFling(View target, float velocityX, float velocityY,
                               boolean consumed) {
    if(isNestedScrollingEnabled()) {
      return dispatchNestedFling(velocityX, velocityY, consumed);
    }
    return  false;
  }

  @Override
  public boolean onStartNestedScroll(View child, View target, int nestedScrollAxes) {
    boolean result =  isEnabled()  && !mRefreshing
            && (nestedScrollAxes & ViewCompat.SCROLL_AXIS_VERTICAL) != 0;

    return  result;
  }

  @Override
  public void onNestedScrollAccepted(View child, View target, int axes) {
    mNestedScrollingParentHelper.onNestedScrollAccepted(child, target, axes);
    if(isNestedScrollingEnabled()){
      startNestedScroll(axes & ViewCompat.SCROLL_AXIS_VERTICAL);
      mNestedScrollInProgress = true;
    }
  }


  /**
   * With child view to processing move events
   * @param target the child view
   * @param dx move x
   * @param dy move y
   * @param consumed parent consumed move distance
   */
  @Override
  public void onNestedPreScroll(View target, int dx, int dy, int[] consumed) {
    // Now let our nested parent consume the leftovers
    final int[] parentConsumed = mParentScrollConsumed;
    if(isNestedScrollingEnabled()){
      if (dispatchNestedPreScroll(dx - consumed[0], dy - consumed[1], parentConsumed, null)) {
        consumed[0] += parentConsumed[0];
        consumed[1] += parentConsumed[1];
        return;
      }
    }
    if ((!mPullRefreshEnable && !mPullLoadEnable)) {
      return;
    }

    /**
     * when in nest-scroll, list canChildScrollUp() false,
     * maybe parent scroll can scroll up
     * */
    if(!canChildScrollUp() && isNestedScrollingEnabled()){
      if(mNestedScrollAcceptedParent != null && mNestedScrollAcceptedParent != mTargetView){
        ViewGroup group = (ViewGroup) mNestedScrollAcceptedParent;
        if(group.getChildCount() > 0){
          int count = group.getChildCount();
          for(int i=0; i<count; i++){
            View view  = group.getChildAt(i);
            if(view.getVisibility() != View.GONE && view.getMeasuredHeight() > 0){
              if(view.getTop() < 0){
                return;
              }else{
                break;
              }
            }
          }
        }
      }
    }



    int spinnerDy = (int) calculateDistanceY(target, dy);

    mRefreshing = false;

    if (!isConfirm) {
      if (spinnerDy < 0 && !canChildScrollUp()) {
        mCurrentAction = PULL_REFRESH;
        isConfirm = true;
      } else if (spinnerDy > 0 && !canChildScrollDown() && (!mRefreshing)) {
        mCurrentAction = LOAD_MORE;
        isConfirm = true;
      }
    }

    if (moveSpinner(-spinnerDy)) {
      if (!canChildScrollUp() && mPullRefreshEnable
              && mTargetView.getTranslationY() > 0
              && dy > 0) {
        consumed[1] += dy;
      }else if (!canChildScrollDown() && mPullLoadEnable
              && mTargetView.getTranslationY() < 0
              && dy < 0){
        consumed[1] += dy;
      }else{
        consumed[1] += spinnerDy;
      }
    }
  }

  @Override
  public int getNestedScrollAxes() {
    return mNestedScrollingParentHelper.getNestedScrollAxes();
  }


  /**
   * Callback on TouchEvent.ACTION_CANCLE or TouchEvent.ACTION_UP
   * handler : refresh or loading
   * @param child : child view of SwipeLayout,RecyclerView or Scroller
   */
  @Override
  public void onStopNestedScroll(View child) {
    mNestedScrollingParentHelper.onStopNestedScroll(child);
    handlerAction();
    if(isNestedScrollingEnabled()) {
      mNestedScrollInProgress = true;
      stopNestedScroll();
    }
  }


  @Override
  public void onNestedScroll(View target, int dxConsumed, int dyConsumed, int dxUnconsumed, int dyUnconsumed) {
    if(isNestedScrollingEnabled()) {
      dispatchNestedScroll(dxConsumed, dyConsumed, dxUnconsumed, dyUnconsumed, mParentOffsetInWindow);
    }
  }





  private double calculateDistanceY(View target, int dy) {
    int viewHeight = target.getMeasuredHeight();
    double ratio = (viewHeight - Math.abs(target.getY())) / 1.0d / viewHeight * DAMPING;
    if (ratio <= 0.01d) {
      //Filter tiny scrolling action
      ratio = 0.01d;
    }
    return ratio * dy;
  }

  /**
   * Adjust the refresh or loading view according to the size of the gesture
   *
   * @param distanceY move distance of Y
   */
  private boolean moveSpinner(float distanceY) {
    if (mRefreshing) {
      return false;
    }

    if (!canChildScrollUp() && mPullRefreshEnable && mCurrentAction == PULL_REFRESH) {
      // Pull Refresh
      LayoutParams lp = (LayoutParams) headerView.getLayoutParams();
      lp.height += distanceY;
      if (lp.height < 0) {
        lp.height = 0;
      }

      if (lp.height == 0) {
        isConfirm = false;
        mCurrentAction = INVALID;
      }
      headerView.setLayoutParams(lp);
      onRefreshListener.onPullingDown(distanceY, lp.height, refreshViewFlowHeight);
      notifyOnRefreshOffsetChangedListener(lp.height);
      headerView.setProgressRotation(lp.height / refreshViewFlowHeight);
      moveTargetView(lp.height);
      return true;
    } else if (!canChildScrollDown() && mPullLoadEnable && mCurrentAction == LOAD_MORE) {
      // Load more
      LayoutParams lp = (LayoutParams) footerView.getLayoutParams();
      lp.height -= distanceY;
      if (lp.height < 0) {
        lp.height = 0;
      }

      if (lp.height == 0) {
        isConfirm = false;
        mCurrentAction = INVALID;
      }
      footerView.setLayoutParams(lp);
      onLoadingListener.onPullingUp(distanceY, lp.height, loadingViewFlowHeight);
      footerView.setProgressRotation(lp.height / loadingViewFlowHeight);
      moveTargetView(-lp.height);
      return true;
    }
    return false;
  }

  /**
   * Adjust contentView(Scroller or List) at refresh or loading time
   * @param h Height of refresh view or loading view
   */
  private void moveTargetView(float h) {
    mTargetView.setTranslationY(h);
  }

  /**
   * Decide on the action refresh or loadmore
   */
  private void handlerAction() {

    if (isRefreshing()) {
      return;
    }
    isConfirm = false;

    LayoutParams lp;
    if (mPullRefreshEnable && mCurrentAction == PULL_REFRESH) {
      lp = (LayoutParams) headerView.getLayoutParams();
      if (lp.height >= refreshViewHeight) {
        startRefresh(lp.height);
      } else if (lp.height > 0) {
        resetHeaderView(lp.height);
      } else {
        resetRefreshState();
      }
    }

    if (mPullLoadEnable && mCurrentAction == LOAD_MORE) {
      lp = (LayoutParams) footerView.getLayoutParams();
      if (lp.height >= loadingViewHeight) {
        startLoadmore(lp.height);
      } else if (lp.height > 0) {
        resetFootView(lp.height);
      } else {
        resetLoadmoreState();
      }
    }
  }

  /**
   * Start Refresh
   * @param headerViewHeight
   */
  private void startRefresh(int headerViewHeight) {
    mRefreshing = true;
    ValueAnimator animator = ValueAnimator.ofFloat(headerViewHeight, refreshViewHeight);
    animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
      @Override
      public void onAnimationUpdate(ValueAnimator animation) {
        LayoutParams lp = (LayoutParams) headerView.getLayoutParams();
        lp.height = (int) ((Float) animation.getAnimatedValue()).floatValue();
        notifyOnRefreshOffsetChangedListener(lp.height);
        headerView.setLayoutParams(lp);
        moveTargetView(lp.height);
      }
    });
    animator.addListener(new WXRefreshAnimatorListener() {
      @Override
      public void onAnimationEnd(Animator animation) {
        headerView.startAnimation();
        //TODO updateLoadText
        if (onRefreshListener != null) {
          onRefreshListener.onRefresh();
        }
      }
    });
    animator.setDuration(300);
    animator.start();
  }

  /**
   * Reset refresh state
   * @param headerViewHeight
   */
  private void resetHeaderView(int headerViewHeight) {
    headerView.stopAnimation();
    headerView.setStartEndTrim(0, 0.75f);
    ValueAnimator animator = ValueAnimator.ofFloat(headerViewHeight, 0);
    animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
      @Override
      public void onAnimationUpdate(ValueAnimator animation) {
        LayoutParams lp = (LayoutParams) headerView.getLayoutParams();
        lp.height = (int) ((Float) animation.getAnimatedValue()).floatValue();
        notifyOnRefreshOffsetChangedListener(lp.height);
        headerView.setLayoutParams(lp);
        moveTargetView(lp.height);
      }
    });
    animator.addListener(new WXRefreshAnimatorListener() {
      @Override
      public void onAnimationEnd(Animator animation) {
        resetRefreshState();

      }
    });
    animator.setDuration(300);
    animator.start();
  }

  private void resetRefreshState() {
    mRefreshing = false;
    isConfirm = false;
    mCurrentAction = -1;
    //TODO updateLoadText
  }

  /**
   * Start loadmore
   * @param headerViewHeight
   */
  private void startLoadmore(int headerViewHeight) {
    mRefreshing = true;
    ValueAnimator animator = ValueAnimator.ofFloat(headerViewHeight, loadingViewHeight);
    animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
      @Override
      public void onAnimationUpdate(ValueAnimator animation) {
        LayoutParams lp = (LayoutParams) footerView.getLayoutParams();
        lp.height = (int) ((Float) animation.getAnimatedValue()).floatValue();
        footerView.setLayoutParams(lp);
        moveTargetView(-lp.height);
      }
    });
    animator.addListener(new WXRefreshAnimatorListener() {
      @Override
      public void onAnimationEnd(Animator animation) {
        footerView.startAnimation();
        //TODO updateLoadText
        if (onLoadingListener != null) {
          onLoadingListener.onLoading();
        }
      }
    });
    animator.setDuration(300);
    animator.start();
  }

  /**
   * Reset loadmore state
   * @param headerViewHeight
   */
  private void resetFootView(int headerViewHeight) {
    footerView.stopAnimation();
    footerView.setStartEndTrim(0.5f, 1.25f);
    ValueAnimator animator = ValueAnimator.ofFloat(headerViewHeight, 0);
    animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
      @Override
      public void onAnimationUpdate(ValueAnimator animation) {
        LayoutParams lp = (LayoutParams) footerView.getLayoutParams();
        lp.height = (int) ((Float) animation.getAnimatedValue()).floatValue();
        footerView.setLayoutParams(lp);
        moveTargetView(-lp.height);
      }
    });
    animator.addListener(new WXRefreshAnimatorListener() {
      @Override
      public void onAnimationEnd(Animator animation) {
        resetLoadmoreState();

      }
    });
    animator.setDuration(300);
    animator.start();
  }

  private void resetLoadmoreState() {
    mRefreshing = false;
    isConfirm = false;
    mCurrentAction = -1;
    //TODO updateLoadText
  }

  /**
   * Whether child view can scroll up
   * @return
   */
  public boolean canChildScrollUp() {
    if (mTargetView == null) {
      return false;
    }
    if (Build.VERSION.SDK_INT < 14) {
      if (mTargetView instanceof AbsListView) {
        final AbsListView absListView = (AbsListView) mTargetView;
        return absListView.getChildCount() > 0
                && (absListView.getFirstVisiblePosition() > 0 || absListView.getChildAt(0)
                .getTop() < absListView.getPaddingTop());
      } else {
        return ViewCompat.canScrollVertically(mTargetView, -1) || mTargetView.getScrollY() > 0;
      }
    } else {
      return ViewCompat.canScrollVertically(mTargetView, -1);
    }
  }

  /**
   * Whether child view can scroll down
   * @return
   */
  public boolean canChildScrollDown() {
    if (mTargetView == null) {
      return false;
    }
    if (Build.VERSION.SDK_INT < 14) {
      if (mTargetView instanceof AbsListView) {
        final AbsListView absListView = (AbsListView) mTargetView;
        if (absListView.getChildCount() > 0) {
          int lastChildBottom = absListView.getChildAt(absListView.getChildCount() - 1)
                  .getBottom();
          return absListView.getLastVisiblePosition() == absListView.getAdapter().getCount() - 1
                  && lastChildBottom <= absListView.getMeasuredHeight();
        } else {
          return false;
        }

      } else {
        return ViewCompat.canScrollVertically(mTargetView, 1) || mTargetView.getScrollY() > 0;
      }
    } else {
      return ViewCompat.canScrollVertically(mTargetView, 1);
    }
  }

  public float dipToPx(Context context, float value) {
    DisplayMetrics metrics = context.getResources().getDisplayMetrics();
    return TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, value, metrics);
  }

  public void setOnLoadingListener(WXOnLoadingListener onLoadingListener) {
    this.onLoadingListener = onLoadingListener;
  }

  public void setOnRefreshListener(WXOnRefreshListener onRefreshListener) {
    this.onRefreshListener = onRefreshListener;
  }

  @SuppressWarnings("unused")
  public void addOnRefreshOffsetChangedListener(@Nullable OnRefreshOffsetChangedListener listener) {
    if(listener != null && !mRefreshOffsetChangedListeners.contains(listener)) {
      mRefreshOffsetChangedListeners.add(listener);
    }
  }

  @SuppressWarnings("unused")
  public boolean removeOnRefreshOffsetChangedListener(@Nullable OnRefreshOffsetChangedListener listener) {
    if(listener != null) {
      return mRefreshOffsetChangedListeners.remove(listener);
    }
    return false;
  }

  private void notifyOnRefreshOffsetChangedListener(int verticalOffset) {
    for(OnRefreshOffsetChangedListener listener : mRefreshOffsetChangedListeners) {
      listener.onOffsetChanged(verticalOffset);
    }
  }

  /**
   * Callback on refresh finish
   */
  public void finishPullRefresh() {
    if (mCurrentAction == PULL_REFRESH) {
      resetHeaderView(headerView == null ? 0 : headerView.getMeasuredHeight());
    }
  }

  /**
   * Callback on loadmore finish
   */
  public void finishPullLoad() {
    if (mCurrentAction == LOAD_MORE) {
      resetFootView(footerView == null ? 0 : footerView.getMeasuredHeight());
    }
  }

  public WXRefreshView getHeaderView() {
    return headerView;
  }

  public WXRefreshView getFooterView() {
    return footerView;
  }

  public boolean isPullLoadEnable() {
    return mPullLoadEnable;
  }

  public void setPullLoadEnable(boolean mPullLoadEnable) {
    this.mPullLoadEnable = mPullLoadEnable;
  }

  public boolean isPullRefreshEnable() {
    return mPullRefreshEnable;
  }

  public void setPullRefreshEnable(boolean mPullRefreshEnable) {
    this.mPullRefreshEnable = mPullRefreshEnable;
  }

  public boolean isRefreshing() {
    return mRefreshing;
  }

  public void setRefreshHeight(int height) {
    refreshViewHeight = height;
    refreshViewFlowHeight = refreshViewHeight * overFlow;
  }

  public void setLoadingHeight(int height) {
    loadingViewHeight = height;
    loadingViewFlowHeight = loadingViewHeight * overFlow;
  }

  public void setRefreshBgColor(int color) {
    headerView.setBackgroundColor(color);
  }

  public void setLoadingBgColor(int color) {
    footerView.setBackgroundColor(color);
  }
}
