package com.tjzhxx.union.public_store.fragment;/**
 * Created by Administrator on 2016/4/1.
 */

import android.os.Bundle;
import android.view.View;

import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentManager;
import androidx.fragment.app.FragmentTransaction;


/**
 * Created by Administrator on 2016/4/1.
 * 描述: Fragment查看器
 * 修改者:
 *
 * @author tianhongtao on 2016/4/1 09:56
 * @version 1.0 2016/4/1 09:56
 * @since 1.0
 */
public class FragmentVisitor {
    //当前项
    private int fragmentCurrentItem = -1;
    private FragmentManager fragmentManager;
    private FragmentVisitorListener fragmentVisitorListener;

    private int resContinerId = -1;

    private FragmentTab[] fragmentTabs;
    private Class<? extends Fragment>[] fragments;
    private Fragment preFragmen;

    /**
     * 初始化
     */
    public FragmentVisitor init(FragmentManager fragmentManager1, FragmentVisitorListener fragmentVisitorListener1) {
        if (fragmentManager1 == null) {
            throw new RuntimeException("FragmentManager can not been null");
        }
        this.fragmentManager = fragmentManager1;
        this.fragmentVisitorListener = fragmentVisitorListener1;
        return this;
    }

    /**
     * 设置容器
     */
    public FragmentVisitor setFragmentContiner(int resId) {
        this.resContinerId = resId;
        return this;
    }

    /**
     * 设置tab和数据
     */
    public FragmentVisitor setTabAndFragmentData(FragmentTab[] fragmentTabs1, Class<? extends Fragment>[] fragments1) {
        if (fragmentTabs1 == null || fragments1 == null) {
            throw new RuntimeException("FragmentVisitor data init error:either can not been null");
        }
        if (fragmentTabs1.length != fragments1.length) {
            throw new RuntimeException("FragmentVisitor data init error:is not equal size");
        }
        if (fragmentManager == null || resContinerId < 0) {
            throw new RuntimeException("Method must be set FragmentManager and ContinerId first");
        }
        this.fragmentTabs = fragmentTabs1;
        this.fragments = fragments1;
        for (int i = 0; i < fragmentTabs.length; i++) {
            final int finalI = i;
            fragmentTabs[finalI].setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    setCurrentItem(finalI);
                }
            });
        }
        return this;
    }

    public void setCurrentItem(int item) {
        if (item < 0) {
            return;
        }
        boolean itemEnable = true;
        if (fragmentVisitorListener != null) {
            itemEnable = fragmentVisitorListener.boforeItemChangedItemEnable(fragmentCurrentItem,item);
        }
        if (fragmentVisitorListener != null) {
            fragmentVisitorListener.controlItemEnable(itemEnable);
        }
        if (!itemEnable) {
            return;
        }
        //item改变
        if (fragmentCurrentItem != item && fragmentTabs != null && (fragmentTabs.length - 1 >= item)) {
            if (fragmentVisitorListener != null) {
                fragmentVisitorListener.onItemChanged(fragmentCurrentItem, item, fragmentTabs[item].getTabCaption());
            }
            if (fragmentCurrentItem < 0) {
                try {
                    preFragmen = fragments[item].newInstance();
                    this.fragmentCurrentItem = item;
                    setTabs();
                    FragmentUtils.replaceFragment(fragmentManager, resContinerId,fragments[fragmentCurrentItem], null, false);
                } catch (InstantiationException e) {
                    e.printStackTrace();
                } catch (IllegalAccessException e) {
                    e.printStackTrace();
                }
            }
            else {
                this.fragmentCurrentItem = item;
                //改变tab
                setTabs();
                //设置Fragment
                replaceFragment(fragments[fragmentCurrentItem]);
            }
        }
    }

    private void setTabs() {
        if ((fragmentTabs != null) && (fragmentTabs.length - 1 >= fragmentCurrentItem)) {
            for (int i = 0; i < fragmentTabs.length; i++) {
                fragmentTabs[i].setTabFoucus(i == fragmentCurrentItem);
            }
        }
    }

    private void replaceFragment(Class<? extends Fragment> newFragment) {

        preFragmen = FragmentUtils.switchFragment(fragmentManager,
                resContinerId, preFragmen,
                newFragment, null, false);
    }

    public interface FragmentVisitorListener {
        void onItemChanged(int oldItem, int newItem, String tabDiscription);

        boolean boforeItemChangedItemEnable(int currentItem, int newItem);

        void controlItemEnable(boolean enable);
    }


    private final static class FragmentUtils {


        public static Fragment replaceFragment(FragmentManager fragmentManager, int container,
                                               Class<? extends Fragment> newFragment, Bundle args) {
            return replaceFragment(fragmentManager, container, newFragment, args, false);
        }

        public static Fragment replaceFragment(FragmentManager fragmentManager, int container,
                                               Fragment newFragment) {
            return replaceFragment(fragmentManager, container, newFragment, false);
        }

        public static Fragment replaceFragment(FragmentManager fragmentManager, int container,
                                               Class<? extends Fragment> newFragment, Bundle args, boolean addToBackStack) {

            Fragment fragment = null;

            // 构造新的Fragment
            try {
                fragment = newFragment.newInstance();
            } catch (InstantiationException e) {
                e.printStackTrace();
            } catch (IllegalAccessException e) {
                e.printStackTrace();
            }

            if (fragment != null) {
                // 设置参数
                if (args != null && !args.isEmpty()) {
                    final Bundle bundle = fragment.getArguments();
                    if (bundle != null) {
                        bundle.putAll(args);
                    } else {
                        fragment.setArguments(args);
                    }
                }
                // 替换
                return replaceFragment(fragmentManager, container, fragment, addToBackStack);
            } else {
                return null;
            }
        }

        public static Fragment replaceFragment(FragmentManager fragmentManager, int container,
                                               Fragment newFragment, boolean addToBackStack) {
            final FragmentTransaction transaction = fragmentManager.beginTransaction();
            final String tag = newFragment.getClass().getSimpleName();

            if (newFragment != null) {
                transaction.replace(container, newFragment, tag);
            }

            if (addToBackStack) {
                transaction.addToBackStack(null);
            }
            transaction.commitAllowingStateLoss();
            return newFragment;
        }

        public static Fragment switchFragment(FragmentManager fragmentManager, int container,
                                              Fragment currentFragment, Class<? extends Fragment> newFragment, Bundle args) {
            return switchFragment(fragmentManager, container, currentFragment, newFragment, args, false);
        }

        /**
         * @param fragmentManager
         * @param container
         * @param currentFragment
         * @param newFragment
         * @param args            新Fragment的参数
         * @param addToBackStack  这个操作是否加入栈中，如果要实现类似返回效果，则需要。
         * @return 新显示的Fragment
         */
        public static Fragment switchFragment(FragmentManager fragmentManager, int container,
                                              Fragment currentFragment, Class<? extends Fragment> newFragment, Bundle args,
                                              boolean addToBackStack) {

            final FragmentTransaction transaction = fragmentManager.beginTransaction();
            final String tag = newFragment.getSimpleName();
            Fragment fragment = fragmentManager.findFragmentByTag(tag);

            // 如果在栈中找到相应的Fragment，则显示，否则重新生成一个
            if (fragment != null) {
                if (fragment != currentFragment) {
                    if (currentFragment != null) {
                        transaction.hide(currentFragment);
                    }
                    transaction.show(fragment);
                    if (addToBackStack) {
                        transaction.addToBackStack(null);
                    }
                    transaction.commitAllowingStateLoss();
                } else {
                    fragment.getArguments().putAll(args);
                }

                return fragment;
            } else {
                try {
                    fragment = newFragment.newInstance();
                } catch (InstantiationException e) {
                    e.printStackTrace();
                } catch (IllegalAccessException e) {
                    e.printStackTrace();
                }
            }

            // 为新的Fragment添加参数
            if (fragment != null) {
                if (args != null && !args.isEmpty()) {
                    final Bundle bundle = fragment.getArguments();
                    if (bundle != null) {
                        bundle.putAll(args);
                    } else {
                        fragment.setArguments(args);
                    }
                }
            }

            // 显示新的Fragment
            if (currentFragment != null) {
                transaction.hide(currentFragment);
            }
            transaction.add(container, fragment, tag);
            if (addToBackStack) {
                transaction.addToBackStack(null);
            }
            transaction.commitAllowingStateLoss();

            return fragment;
        }

    }
}
