package com.luticate.utils.ui.fragments;

import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
import android.app.Fragment;
import android.os.Build;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;

import com.luticate.utils.business.LuPromise;
import com.luticate.utils.dbo.LuDbo;
import com.luticate.utils.dbo.LuMultipleDbo;
import com.luticate.utils.ui.views.AbstractPaginationView;

import java.util.Vector;

/**
 * Created by robin on 12/6/15.
 */
public abstract class AbstractPaginationFragment<Dbo extends LuDbo> extends Fragment {

    protected int _page = 0;

    protected int _perPage = 15;

    protected int _maxPage = 1;

    protected String _query = "";

    protected LuMultipleDbo<Dbo> _items = null;

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
    {
        return inflater.inflate(getLayoutId(), container, false);
    }

    @Override
    public void onStart() {
        super.onStart();
        View v = getView();
        AbstractPaginationView paginationView = (AbstractPaginationView) v.findViewById(getPaginationViewId());
        paginationView.setOnPageChanged(new LuPromise.LuConsumer<Integer>() {
            @Override
            public void execute(Integer page) {
                loadPage(page);
            }
        });
        if (_items == null) {
            loadPage(_page);
        }
    }

    protected void showProgress(final boolean show)
    {
        View v = getView();
        if (!isAdded() || v == null)
            return;

        final View imagesScrollView = v.findViewById(getScrollViewId());
        final View loadingView = v.findViewById(getLoaderViewId());

        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB_MR2)
        {
            int shortAnimTime =
                    getResources().getInteger(android.R.integer.config_shortAnimTime);

            loadingView.setVisibility(View.VISIBLE);
            loadingView.animate().setDuration(shortAnimTime).alpha(show ? 1 : 0)
                    .setListener(new AnimatorListenerAdapter()
                    {
                        @Override
                        public void onAnimationEnd(Animator animation)
                        {
                            loadingView.setVisibility(show ? View.VISIBLE : View.GONE);
                        }
                    });

            imagesScrollView.setVisibility(View.VISIBLE);
            imagesScrollView.animate().setDuration(shortAnimTime).alpha(show ? 0 : 1)
                    .setListener(new AnimatorListenerAdapter()
                    {
                        @Override
                        public void onAnimationEnd(Animator animation)
                        {
                            imagesScrollView.setVisibility(show ? View.GONE : View.VISIBLE);
                        }
                    });
        }
        else
        {
            loadingView.setVisibility(show ? View.VISIBLE : View.GONE);
            imagesScrollView.setVisibility(show ? View.GONE : View.VISIBLE);
        }
    }

    public void loadPage(final int page)
    {
        final View v = getView();
        if (!isAdded() || v == null) {
            return;
        }
        showProgress(true);
        if (_items != null) {
            _items.setData(new Vector<Dbo>());
        }
        getLoadPagePromise(page, _perPage, _query).then(new LuPromise.LuConsumer<LuMultipleDbo<Dbo>>() {
            @Override
            public void execute(LuMultipleDbo<Dbo> items) {
                _items = items;
                _page = page;
                _maxPage = Math.max(items.getCount() / _perPage, 1);
                AbstractPaginationView paginationView = (AbstractPaginationView) v.findViewById(getPaginationViewId());
                paginationView.setMaxPage(_maxPage);
                paginationView.setPage(_page);
                onPageChanged();
                showProgress(false);
            }
        }, new LuPromise.LuConsumer<LuPromise.LuPromiseError>() {
            @Override
            public void execute(LuPromise.LuPromiseError error) {

                showProgress(false);
            }
        });
    }

    protected abstract void onPageChanged();

    protected abstract LuPromise<LuMultipleDbo<Dbo>> getLoadPagePromise(int page, int perPage, String query);

    protected abstract int getScrollViewId();

    protected abstract int getLoaderViewId();

    protected abstract int getLayoutId();

    protected abstract int getPaginationViewId();
}
