package com.sanyuzhang.circular.viewpager.cvp.adapter;

import android.annotation.TargetApi;
import android.app.ActionBar;
import android.content.Context;
import android.content.res.ColorStateList;
import android.graphics.drawable.Drawable;
import android.os.Build;
import android.support.annotation.NonNull;
import android.support.v4.view.ViewCompat;
import android.support.v7.widget.AppCompatTextView;
import android.support.v7.widget.RecyclerView;
import android.text.TextUtils;
import android.util.TypedValue;
import android.view.Gravity;
import android.view.View;
import android.view.ViewGroup;
import android.view.ViewParent;
import android.view.accessibility.AccessibilityEvent;
import android.view.accessibility.AccessibilityNodeInfo;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView;
import android.widget.Toast;

import com.sanyuzhang.circular.viewpager.cvp.R;
import com.sanyuzhang.circular.viewpager.cvp.util.CircularUtils;
import com.sanyuzhang.circular.viewpager.cvp.view.CircularTabLayout;

import java.util.List;

import static android.support.v7.content.res.AppCompatResources.getDrawable;

/**
 * Created by j_cho on 2017/10/03.
 */

public class CircularTabLayoutAdapter extends RecyclerView.Adapter<CircularTabLayoutAdapter.TabViewHolder> {

    private Context mContext;

    private CircularTabLayout.ITabSelectedListener mTabSelectedListener;

    private int mCurrentPosition = CircularUtils.START_POSITION;

    /**
     * real tab
     */
    private List<CircularTabLayout.Tab> mObjectList;

    /**
     * ViewHolder.itemView listener
     */
    private View.OnClickListener mOnClickListener = new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            mTabSelectedListener.onTabItemClicked((Integer) v.getTag());
        }
    };

    /**
     * TabView Style
     */
    private int mTabViewMinimumHeight;

    private int mTabViewBackground;

    private int[] mTabViewPadding;

    private int[] mTabViewMarings;

    private int mTabMinWidth;

    private int mTabMaxWidth;

    private int mTabTextAppearance;

    private ColorStateList mTabTextColors;

    private int mTabTextSize;

    /**
     * Constructor.
     *
     * @param context
     * @param tabSelectedListener
     */
    public CircularTabLayoutAdapter(@NonNull Context context, @NonNull CircularTabLayout.ITabSelectedListener tabSelectedListener) {
        mContext = context;
        mTabSelectedListener = tabSelectedListener;
    }

    @Override
    public TabViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        TabView tabView = createTabView();
        tabView.setId(R.id.recycler_tab_layout_tab_view);
        return new TabViewHolder(tabView);
    }

    @Override
    public void onBindViewHolder(TabViewHolder holder, int position) {
        int realFragmentPosition = calculateRealPositionFromDummyPosition(position);
        holder.itemView.setTag(position);
        holder.itemView.setOnClickListener(mOnClickListener);
        holder.tabView.update(mObjectList.get(realFragmentPosition));
        holder.tabView.setSelected(isSelectedItem(position));
    }

    @Override
    public int getItemCount() {
        return CircularUtils.ITEM_COUNT;
    }

    public int getCurrentPosition() {
        return mCurrentPosition;
    }

    /**
     * @param position
     */
    public void setCurrentPosition(int position) {
        int previousPosition = mCurrentPosition;
        mCurrentPosition = position;
        notifyItemChanged(previousPosition);
        notifyItemChanged(mCurrentPosition);
    }

    /**
     * @param position
     * @return
     */
    public boolean isSelectedItem(int position) {
        return mCurrentPosition == position;
    }

    /**
     * calculate the real position from DummyPosition
     *
     * @param dummyPosition
     * @return
     */
    public int calculateRealPositionFromDummyPosition(int dummyPosition) {
        return CircularUtils.calculateRealPositionFromDummyPosition(mObjectList.size(), dummyPosition);
    }

    /**
     * calculate DummyPosition from real position.
     *
     * @param realPosition
     * @return
     */
    public int calculateDummyPositionFromRealPosition(int realPosition) {
        return CircularUtils.calculateDummyPositionFromRealPosition(mObjectList.size(), mCurrentPosition,
                realPosition);
    }

    /**
     * @param realPosition
     * @return
     */
    public int moveToPosition(int realPosition) {
        int dummyPosition = calculateDummyPositionFromRealPosition(realPosition);
        setCurrentPosition(dummyPosition);
        return dummyPosition;
    }

    public void setTabViewStyle(int tabViewMinimumHeight, int tabViewBackground, int[] tabViewMargins,
                                int[] tabViewPadding, int tabMinWidth, int tabMaxWidth,
                                int tabTextSize, int tabTextAppearance, ColorStateList tabTextColors) {
        mTabViewMinimumHeight = tabViewMinimumHeight;
        mTabViewBackground = tabViewBackground;
        mTabViewPadding = tabViewPadding;
        mTabViewMarings = tabViewMargins;
        mTabMinWidth = tabMinWidth;
        mTabMaxWidth = tabMaxWidth;
        mTabTextSize = tabTextSize;
        mTabTextAppearance = tabTextAppearance;
        mTabTextColors = tabTextColors;
    }

    /**
     * @return
     */
    protected TabView createTabView() {
        TabView tabView = new TabView(mContext, mTabViewBackground, mTabViewMarings, mTabViewPadding, mTabMinWidth,
                mTabMaxWidth, mTabTextSize, mTabTextAppearance, mTabTextColors);
        tabView.setFocusable(true);
        tabView.setMinimumHeight(mTabViewMinimumHeight);
        return tabView;
    }

    /**
     * RecyclerView.Tab list
     *
     * @param objectList
     */
    public void setTabData(List<CircularTabLayout.Tab> objectList) {
        mObjectList = objectList;
    }

    static class TabViewHolder extends RecyclerView.ViewHolder {

        TabView tabView;

        public TabViewHolder(View itemView) {
            super(itemView);
            tabView = (TabView) itemView.findViewById(R.id.recycler_tab_layout_tab_view);
        }
    }

    static class TabView extends LinearLayout implements View.OnLongClickListener {

        private static final int MAX_TAB_TEXT_LINES = 2;

        private CircularTabLayout.Tab mTab;

        private TextView mTextView;

        private ImageView mIconView;

        private View mCustomView;

        private int mTabTextSize;

        private int mTabMinWidth;

        private int mTabMaxWidth;

        private int mTabTextAppearance;

        private ColorStateList mTabTextColors;

        public TabView(Context context, int background, int[] margins,
                       int[] paddings, int tabMinWidth, int tabMaxWidth,
                       int tabTextSize, int tabTextAppearance, ColorStateList tabTextColors) {
            super(context);
            if (background != 0) {
                setBackgroundDrawable(getDrawable(context, background));
            }

            ViewCompat.setPaddingRelative(this, paddings[0], paddings[1], paddings[2], paddings[3]);

            mTabMinWidth = tabMinWidth;
            mTabMaxWidth = tabMaxWidth;
            mTabTextSize = tabTextSize;
            mTabTextAppearance = tabTextAppearance;
            mTabTextColors = tabTextColors;

            MarginLayoutParams marginLayoutParams = new MarginLayoutParams(MarginLayoutParams.WRAP_CONTENT, MarginLayoutParams.WRAP_CONTENT);

            marginLayoutParams.leftMargin = margins[0];
            marginLayoutParams.topMargin = margins[1];
            marginLayoutParams.rightMargin = margins[2];
            marginLayoutParams.bottomMargin = margins[3];

            setLayoutParams(marginLayoutParams);

            setGravity(Gravity.CENTER);
        }

        public void setSelected(boolean selected) {
            boolean changed = isSelected() != selected;
            super.setSelected(selected);
            if (changed && selected) {
                sendAccessibilityEvent(AccessibilityEvent.TYPE_VIEW_SELECTED);
                if (mTextView != null) {
                    mTextView.setSelected(selected);
                }
                if (mIconView != null) {
                    mIconView.setSelected(selected);
                }
            }
        }

        @TargetApi(Build.VERSION_CODES.ICE_CREAM_SANDWICH)
        public void onInitializeAccessibilityEvent(AccessibilityEvent event) {
            super.onInitializeAccessibilityEvent(event);
            event.setClassName(ActionBar.Tab.class.getName());
        }

        @TargetApi(Build.VERSION_CODES.ICE_CREAM_SANDWICH)
        public void onInitializeAccessibilityNodeInfo(AccessibilityNodeInfo info) {
            super.onInitializeAccessibilityNodeInfo(info);
            info.setClassName(ActionBar.Tab.class.getName());
        }

        public void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
            super.onMeasure(widthMeasureSpec, heightMeasureSpec);
            if (mTabMaxWidth != 0 && getMeasuredWidth() > mTabMaxWidth) {
                super.onMeasure(MeasureSpec.makeMeasureSpec(mTabMaxWidth, MeasureSpec.EXACTLY), heightMeasureSpec);
            } else if (mTabMinWidth > 0 && getMeasuredHeight() < mTabMinWidth) {
                super.onMeasure(MeasureSpec.makeMeasureSpec(mTabMinWidth, MeasureSpec.EXACTLY), heightMeasureSpec);
            }
        }

        final void update(CircularTabLayout.Tab tab) {
            ColorStateList tabTextColors = tab.getTextColorStateList() == null ? mTabTextColors : tab.getTextColorStateList();

            mTab = tab;
            View custom = tab.getCustomView();
            if (custom != null) {
                ViewParent icon = custom.getParent();
                if (icon != this) {
                    if (icon != null) {
                        ((ViewGroup) icon).removeView(custom);
                    }
                    addView(custom);
                }

                mCustomView = custom;
                if (mTextView != null) {
                    mTextView.setVisibility(View.GONE);
                }

                if (mIconView != null) {
                    mIconView.setVisibility(View.GONE);
                    mIconView.setImageDrawable(null);
                }
            } else {
                if (mCustomView != null) {
                    removeView(mCustomView);
                    mCustomView = null;
                }

                Drawable icon1 = tab.getIcon();
                CharSequence text = tab.getText();
                if (icon1 != null) {
                    if (mIconView == null) {
                        ImageView hasText = new ImageView(getContext());
                        LayoutParams textView = new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
                        textView.gravity = Gravity.CENTER_VERTICAL;
                        hasText.setLayoutParams(textView);
                        addView(hasText, 0);
                        mIconView = hasText;
                    }

                    mIconView.setImageDrawable(icon1);
                    mIconView.setVisibility(View.VISIBLE);
                } else if (mIconView != null) {
                    mIconView.setVisibility(View.GONE);
                    mIconView.setImageDrawable(null);
                }

                boolean hasText1 = !TextUtils.isEmpty(text);
                if (hasText1) {
                    if (mTextView == null) {
                        AppCompatTextView textView1 = new AppCompatTextView(getContext());
                        textView1.setTextAppearance(getContext(), mTabTextAppearance);
                        if (mTabTextSize != -1) {
                            textView1.setTextSize(TypedValue.COMPLEX_UNIT_PX, mTabTextSize);
                        }
                        textView1.setMaxLines(MAX_TAB_TEXT_LINES);
                        textView1.setEllipsize(TextUtils.TruncateAt.END);
                        textView1.setGravity(Gravity.CENTER);
                        if (tabTextColors != null) {
                            textView1.setTextColor(tabTextColors);
                        }
                        addView(textView1, LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
                        mTextView = textView1;
                    }
                    mTextView.setText(text);
                    mTextView.setContentDescription(tab.getContentDescription());
                    mTextView.setVisibility(View.VISIBLE);
                } else if (mTextView != null) {
                    mTextView.setVisibility(View.GONE);
                    mTextView.setText(null);
                }

                if (mIconView != null) {
                    mIconView.setContentDescription(tab.getContentDescription());
                }

                if (!hasText1 && !TextUtils.isEmpty(tab.getContentDescription())) {
                    setOnLongClickListener(this);
                    setLongClickable(true);
                } else {
                    setOnLongClickListener(null);
                    setLongClickable(false);
                }
            }
        }

        @Override
        public boolean onLongClick(View v) {
            final int[] screenPos = new int[2];
            getLocationOnScreen(screenPos);
            final Context context = getContext();
            final int width = getWidth();
            final int height = getHeight();
            final int screenWidth = context.getResources().getDisplayMetrics().widthPixels;
            Toast cheatSheet = Toast.makeText(context, mTab.getContentDescription(), Toast.LENGTH_SHORT);
            // display below the tab
            cheatSheet.setGravity(Gravity.TOP | Gravity.CENTER_HORIZONTAL, (screenPos[0] + width / 2) - screenWidth / 2, height);
            cheatSheet.show();
            return true;
        }
    }
}