/*
 * 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 org.apache.weex.ui.view.listview;

import android.annotation.SuppressLint;
import android.annotation.TargetApi;
import android.content.Context;
import android.os.Build;
import android.support.annotation.Nullable;
import android.support.v7.widget.GridLayoutManager;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.OrientationHelper;
import android.support.v7.widget.RecyclerView;
import android.support.v7.widget.StaggeredGridLayoutManager;
import android.view.MotionEvent;

import org.apache.weex.common.Constants;
import org.apache.weex.common.WXThread;
import org.apache.weex.ui.view.gesture.WXGesture;
import org.apache.weex.ui.view.gesture.WXGestureObservable;

public class WXRecyclerView extends RecyclerView implements WXGestureObservable {

  public static final int TYPE_LINEAR_LAYOUT = 1;
  public static final int TYPE_GRID_LAYOUT = 2;
  public static final int TYPE_STAGGERED_GRID_LAYOUT = 3;
  private WXGesture mGesture;
  private boolean scrollable = true;
  private boolean hasTouch = false;


  public WXRecyclerView(Context context) {
    super(context);
  }

  public boolean isScrollable() {
    return scrollable;
  }

  public void setScrollable(boolean scrollable) {
    this.scrollable = scrollable;
  }

  public void initView(Context context, int type,int orientation) {
    initView(context,type, Constants.Value.COLUMN_COUNT_NORMAL,Constants.Value.COLUMN_GAP_NORMAL,orientation);
  }


  /**
   *
   * @param context
   * @param type
   * @param orientation should be {@link OrientationHelper#HORIZONTAL} or {@link OrientationHelper#VERTICAL}
   */
  @TargetApi(Build.VERSION_CODES.JELLY_BEAN)
  public void initView(Context context, int type, int columnCount, float columnGap, int orientation) {
    if (type == TYPE_GRID_LAYOUT) {
      setLayoutManager(new GridLayoutManager(context, columnCount,orientation,false));
    } else if (type == TYPE_STAGGERED_GRID_LAYOUT) {
      setLayoutManager(new ExtendedStaggeredGridLayoutManager(columnCount, orientation));
    } else if (type == TYPE_LINEAR_LAYOUT) {
      setLayoutManager(new ExtendedLinearLayoutManager(context,orientation,false));
    }
  }

  @Override
  public void registerGestureListener(@Nullable WXGesture wxGesture) {
    mGesture = wxGesture;
  }

  @Override
  public WXGesture getGestureListener() {
    return mGesture;
  }

  @SuppressLint("ClickableViewAccessibility")
  @Override
  public boolean onTouchEvent(MotionEvent event) {
    if(!scrollable) {
      return true;
    }
    return super.onTouchEvent(event);
  }

  @Override
  public boolean dispatchTouchEvent(MotionEvent event) {
    hasTouch = true;
    boolean result = super.dispatchTouchEvent(event);
    if (mGesture != null) {
      result |= mGesture.onTouch(this, event);
    }
    return result;
  }

  public void scrollTo(boolean smooth, int position, final  int offset, final int orientation){
    if (!smooth) {
      RecyclerView.LayoutManager layoutManager = getLayoutManager();
      if (layoutManager instanceof LinearLayoutManager) {
        //GridLayoutManager is also instance of LinearLayoutManager
        ((LinearLayoutManager) layoutManager).scrollToPositionWithOffset(position, -offset);
      } else if (layoutManager instanceof StaggeredGridLayoutManager) {
        ((StaggeredGridLayoutManager) layoutManager).scrollToPositionWithOffset(position, -offset);
      }
      //Any else?
    } else {
      smoothScrollToPosition(position);
      if (offset != 0) {
        setOnSmoothScrollEndListener(new ExtendedLinearLayoutManager.OnSmoothScrollEndListener() {
          @Override
          public void onStop() {
            post(WXThread.secure(new Runnable() {
              @Override
              public void run() {
                if (orientation == Constants.Orientation.VERTICAL) {
                  smoothScrollBy(0, offset);
                } else {
                  smoothScrollBy(offset, 0);
                }
              }
            }));
          }
        });
      }
    }
  }

  public void setOnSmoothScrollEndListener(final ExtendedLinearLayoutManager.OnSmoothScrollEndListener onSmoothScrollEndListener){
    addOnScrollListener(new RecyclerView.OnScrollListener() {
      @Override
      public void onScrollStateChanged(RecyclerView recyclerView, int newState) {
        if (newState == RecyclerView.SCROLL_STATE_IDLE) {
          recyclerView.removeOnScrollListener(this);
          if(onSmoothScrollEndListener != null){
            onSmoothScrollEndListener.onStop();
          }
        }
      }
    });
  }

}
