/*
 * Copyright (c) 2016 droidwolf(droidwolf2006@gmail.com)
 * 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.reactnative.FixedTableView;

import android.content.Context;
import android.support.v7.widget.RecyclerView;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.widget.LinearLayout;
import com.facebook.react.uimanager.PixelUtil;


public class FixedTableView extends LinearLayout {

    private View mHeaderLeftView;
    private View mHeaderRightView;

    private RecyclerView mLeftView;
    private RecyclerView mRightView;
    private ObservableHorizontalScrollView mScrollView;

    private LinearLayout mLeftLayout;
    private LinearLayout mRightLayout;

    private int mFreezeWidth = 0;
    private int mFreezeHeight = 0;
    private int mScrollWidth = 0;

    private final RecyclerView.OnScrollListener mLeftOSL = new MyOnScrollListener() {
        @Override
        public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
            super.onScrolled(recyclerView, dx, dy);
            mRightView.scrollBy(dx, dy);
        }
    };
    private final RecyclerView.OnScrollListener mRightOSL = new MyOnScrollListener() {
        @Override
        public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
            super.onScrolled(recyclerView, dx, dy);
            mLeftView.scrollBy(dx, dy);
        }
    };

    public FixedTableView(Context context) {
        super(context);
        mLeftLayout = new LinearLayout(getContext());
        mLeftLayout.setOrientation(VERTICAL);

        mScrollView = new ObservableHorizontalScrollView(getContext());
        mScrollView.setLayoutParams(new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT));

        mRightLayout = new LinearLayout(getContext());
        mRightLayout.setOrientation(VERTICAL);
        mRightLayout.setLayoutParams(new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT));

        mScrollView.addView(mRightLayout);

        addView(mLeftLayout);
        addView(mScrollView);

        initListener();
    }

    void setFreezeWidth(int freezeWidth) {
        mFreezeWidth = freezeWidth;
        mLeftLayout.setLayoutParams(new LayoutParams((int) PixelUtil.toPixelFromDIP(mFreezeWidth), LayoutParams.MATCH_PARENT));
    }

    void setFreezeHeight(int freezeHeight) {
        mFreezeHeight = freezeHeight;
    }

    void setScrollWidth(int scrollWidth) {
        this.mScrollWidth = scrollWidth;
    }

    void addNewView(View view, int index) {
        switch (index) {
            case 0:
                mHeaderLeftView = view;
                mHeaderLeftView.setLayoutParams(new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, (int) PixelUtil.toPixelFromDIP(mFreezeHeight)));
                mLeftLayout.addView(mHeaderLeftView);
                return;
            case 1:
                mHeaderRightView = view;
                mHeaderRightView.setLayoutParams(new ViewGroup.LayoutParams((int) PixelUtil.toPixelFromDIP(mScrollWidth), (int) PixelUtil.toPixelFromDIP(mFreezeHeight)));
                mRightLayout.addView(mHeaderRightView);
                return;
            case 2:
                mLeftView = (RecyclerView) view;
                mLeftLayout.addView(mLeftView);
                break;
            case 3:
                mRightView = (RecyclerView) view;
                mRightView.setLayoutParams(new ViewGroup.LayoutParams((int) PixelUtil.toPixelFromDIP(mScrollWidth), ViewGroup.LayoutParams.MATCH_PARENT));
                mRightLayout.addView(mRightView);
                break;
            default:
                super.addView(view);
                return;
        }
        setSyncScrollListener();
    }

    private void initListener() {
        mScrollView.setScrollViewListener(new ObservableHorizontalScrollView.ScrollViewListener() {
            @Override
            public void onScrollChanged(ObservableHorizontalScrollView scrollView, int x, int y, int oldx, int oldy) {
                mLeftView.removeOnScrollListener(mLeftOSL);
                mRightView.removeOnScrollListener(mRightOSL);
            }
        });
    }

    /**
     * 设置两个列表的同步滚动
     */
    private void setSyncScrollListener() {

        if (mLeftView != null && mRightView != null) {
            mLeftView.addOnItemTouchListener(new RecyclerView.OnItemTouchListener() {

                private int mLastY;

                @Override
                public boolean onInterceptTouchEvent(RecyclerView rv, MotionEvent e) {
                    // 当列表是空闲状态时
                    if (rv.getScrollState() == RecyclerView.SCROLL_STATE_IDLE) {
                        onTouchEvent(rv, e);
                    }
                    return false;
                }

                @Override
                public void onTouchEvent(RecyclerView rv, MotionEvent e) {
                    // 若是手指按下的动作，且另一个列表处于空闲状态
                    if (e.getAction() == MotionEvent.ACTION_DOWN && mRightView.getScrollState() == RecyclerView.SCROLL_STATE_IDLE) {
                        // 记录当前另一个列表的y坐标并对当前列表设置滚动监听
                        mLastY = rv.getScrollY();
                        rv.addOnScrollListener(mLeftOSL);
                    } else {
                        // 若当前列表原地抬起手指时，移除当前列表的滚动监听
                        if (e.getAction() == MotionEvent.ACTION_UP && rv.getScrollY() == mLastY) {
                            rv.removeOnScrollListener(mLeftOSL);
                        }
                    }
                }

                @Override
                public void onRequestDisallowInterceptTouchEvent(boolean disallowIntercept) {

                }
            });
            mRightView.addOnItemTouchListener(new RecyclerView.OnItemTouchListener() {

                private int mLastY;

                @Override
                public boolean onInterceptTouchEvent(RecyclerView rv, MotionEvent e) {
                    if (rv.getScrollState() == RecyclerView.SCROLL_STATE_IDLE) {
                        onTouchEvent(rv, e);
                    }
                    return false;
                }

                @Override
                public void onTouchEvent(RecyclerView rv, MotionEvent e) {
                    if (e.getAction() == MotionEvent.ACTION_DOWN && mRightView.getScrollState() == RecyclerView.SCROLL_STATE_IDLE) {
                        mLastY = rv.getScrollY();
                        rv.addOnScrollListener(mRightOSL);
                    } else {
                        if (e.getAction() == MotionEvent.ACTION_UP && rv.getScrollY() == mLastY) {
                            rv.removeOnScrollListener(mRightOSL);
                        }
                    }
                }

                @Override
                public void onRequestDisallowInterceptTouchEvent(boolean disallowIntercept) {

                }
            });
        }
    }


    void removeAllView() {
        removeAllViews();
        mHeaderLeftView = null;
        mHeaderRightView = null;
        mLeftView = null;
        mRightView = null;
        mScrollView = null;
    }
}
