package kz.arta.synergy.workflow.mobile.android.documents.common.fragments;

import android.app.AlertDialog;
import android.app.Fragment;
import android.content.Context;
import android.content.DialogInterface;
import android.content.SharedPreferences;
import android.content.res.Configuration;
import android.os.AsyncTask;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.v4.widget.SwipeRefreshLayout;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AbsListView;
import android.widget.ArrayAdapter;
import android.widget.TextView;

import com.devspark.appmsg.AppMsg;
import com.google.gson.JsonSyntaxException;
import com.jeremyfeinstein.slidingmenu.lib.SlidingMenu;
import com.pnikosis.materialishprogress.ProgressWheel;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

import kz.arta.synergy.workflow.mobile.android.R;
import kz.arta.synergy.workflow.mobile.android.common.ActivityConst;
import kz.arta.synergy.workflow.mobile.android.common.SettingsConst;
import kz.arta.synergy.workflow.mobile.android.common.activities.MainActivity;
import kz.arta.synergy.workflow.mobile.android.common.models.ErrorCode;
import kz.arta.synergy.workflow.mobile.android.common.models.Person;
import kz.arta.synergy.workflow.mobile.android.common.offline.SyncMain;
import kz.arta.synergy.workflow.mobile.android.common.requests.RestClient;
import kz.arta.synergy.workflow.mobile.android.common.requests.SendGetRequest;
import kz.arta.synergy.workflow.mobile.android.common.utils.ActionUtils;
import kz.arta.synergy.workflow.mobile.android.common.utils.Const;
import kz.arta.synergy.workflow.mobile.android.common.utils.Fonts;
import kz.arta.synergy.workflow.mobile.android.common.utils.FragmentBackPressedListener;
import kz.arta.synergy.workflow.mobile.android.common.utils.FragmentConst;
import kz.arta.synergy.workflow.mobile.android.common.utils.MyApplication;
import kz.arta.synergy.workflow.mobile.android.common.utils.Utils;
import kz.arta.synergy.workflow.mobile.android.common.utils.Wrapper;
import kz.arta.synergy.workflow.mobile.android.common.utils.swipelist.BaseSwipeListViewListener;
import kz.arta.synergy.workflow.mobile.android.common.utils.swipelist.SwipeListView;
import kz.arta.synergy.workflow.mobile.android.documents.DocumentConst;
import kz.arta.synergy.workflow.mobile.android.documents.common.adapters.AdapterDocumentsAll;
import kz.arta.synergy.workflow.mobile.android.documents.common.adapters.AdapterDocumentsAllTablet;
import kz.arta.synergy.workflow.mobile.android.documents.common.adapters.AdapterDocumentsJournal;
import kz.arta.synergy.workflow.mobile.android.documents.common.adapters.AdapterDocumentsJournalTablet;
import kz.arta.synergy.workflow.mobile.android.documents.common.models.DocumentItem;
import kz.arta.synergy.workflow.mobile.android.documents.offline.DocumentTable;

/**
 * Created by neox on 01.11.14.
 * Список документов
 */
public class FragmentDocuments extends Fragment {

    /**
     * Данные, нужные для работы списка
     */
    private SwipeListView mainList;
    private List<DocumentItem> mainData;
    private ArrayAdapter<DocumentItem> mainAdapter;
    private ProgressWheel mainProgressBar;

    /**
     * Данные, нужные для работы списка (дочерние)
     */
    private SwipeListView childList;
    private List<DocumentItem> childData;
    private ArrayAdapter<DocumentItem> childAdapter;
    private ProgressWheel childProgressBar;

    /**
     * Настройки
     */
    private SharedPreferences settings;

    /**
     * Содержимое текущего фрагмента
     */
    private View view;

    /**
     * Данные пользователя
     */
    private Person person;

    /**
     * URL на текущий список документов
     */
    private String currentUrl;

    /**
     * URL на дочерние документы
     */
    private String childUrl;

    /**
     * Текущая страница списка документов
     */
    private int pageNumber = 0;

    /**
     * Загружаются ли документы в данный момент
     */
    private boolean isLoading = false;

    /**
     * Позиция экрана дочерних документов (0 - дочерние документы закрыты)
     */
    private int listPosition = 0;

    /**
     * Текущий фрагмент
     */
    private Fragment fragment;

    /**
     * Тип текущего фильтра
     *
     * @see DocumentConst#ALL
     * @see DocumentConst#JOURNAL
     */
    private String type;

    /**
     * filterType теущего фильтра (получается из API)
     */
    private String filterType;

    /**
     * URL на дочерние документы
     */
    private List<String> urlToChildData = new ArrayList<>();

    /**
     * Первая плашка у дочерних документов
     */
    private List<DocumentItem> headChildData = new ArrayList<>();

    /**
     * Боковая навигация (дочерние документы)
     */
    private SlidingMenu childDataSlidingMenu;

    /**
     * Используется ли планшет либо смартфон
     */
    private boolean tablet;

    /**
     * Обновление спика документов свайпом
     */
    private SwipeRefreshLayout mainRefreshLayout;

    /**
     * Обновление спика документов свайпом (дочерние)
     */
    private SwipeRefreshLayout childRefreshLayout;

    @Override
    public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        fragment = this;
        view = inflater.inflate(R.layout.fragment_list, null);
        tablet = isLarge();
        initComponents();
        // нажатие на кнопку "back"
        ((MainActivity) getActivity()).setFragmentBackPressedListener(new FragmentBackPressedListener() {
            @Override
            public void doBack() {
                if (((MainActivity) getActivity()).getFiltersSlidingMenu().isMenuShowing()) {
                    ((MainActivity) getActivity()).getFiltersSlidingMenu().toggle();
                } else {
                    backPressed();
                }
            }
        });
        return view;
    }

    /**
     * Список с основными документами
     */
    private void initMainList() {

        mainProgressBar = (ProgressWheel) view.findViewById(R.id.main_fragment_progress_bar);

        mainRefreshLayout = (SwipeRefreshLayout) view.findViewById(R.id.refresh);
        mainRefreshLayout.setColorSchemeResources(R.color.color1_update_list, R.color.color2_update_list,
                R.color.color3_update_list, R.color.color4_update_list);
        mainRefreshLayout.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() {
            @Override
            public void onRefresh() {
                mainRefreshLayout.postDelayed(new Runnable() {
                    @Override
                    public void run() {
                        isLoading = false;
                        pageNumber = 0;
                        getDocuments(ActionUtils.parseDocumentUrl(currentUrl, pageNumber), true, false, true);
                    }
                }, 0);
            }
        });

        mainList = (SwipeListView) view.findViewById(R.id.refresh_list);
        mainData = new ArrayList<>();
        mainAdapter = new AdapterDocumentsJournal(getActivity().getApplicationContext(), mainData, false, R.layout.main_activity, person);
        mainList.setAdapter(mainAdapter);

        // скроллинг
        mainList.setOnScrollListener(new AbsListView.OnScrollListener() {
            @Override
            public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) {
                if (totalItemCount >= FragmentConst.DEFAULT_COUNT_WORKS && firstVisibleItem + visibleItemCount == totalItemCount) {
                    if (!isLoading) {
                        isLoading = true;
                        pageNumber++;
                        getDocuments(ActionUtils.parseDocumentUrl(currentUrl, pageNumber), false, true, false);
                    }
                }
            }

            @Override
            public void onScrollStateChanged(AbsListView absListView, int i) {

            }
        });

        // свайп плашки
        mainList.setSwipeListViewListener(new BaseSwipeListViewListener() {
            @Override
            public void onOpened(int position, boolean toRight) {
                // если у документа есть дочерние и если есть соединение с интернетом и если текущая плашка не раскрыта
                if (mainData.get(position).getHasChildren().equals("true") &&
                        Utils.isOnline(getActivity(), person.getHost()) && !mainData.get(position).isOpened()) {
                    headChildData.add(mainData.get(position));
                    childUrl = "rest/api/docflow/doc/child_documents?documentID=" +
                            mainData.get(position).getDocumentID() + "&locale=" + MyApplication.getLang();
                    childDataSlidingMenu.showMenu();
                    listPosition++;
                    urlToChildData.add(childUrl);
                    getChildDocuments(childUrl, true);
                }
                mainList.closeOpenedItems();
            }

            @Override
            public void onDouble(int position) {
                if (mainData != null && !mainData.isEmpty()) {
                    mainData.get(position).setOpened(!mainData.get(position).isOpened());
                    mainAdapter.notifyDataSetChanged();
                }
            }

            @Override
            public void onLong(int position) {
                if (mainData != null && !mainData.isEmpty()) {
                    showDialog(position);
                }
            }

            @Override
            public void onSingle(int position) {
                if (mainData != null && !mainData.isEmpty()) {
                    // говорим что документ просмотрен
                    ActionUtils.markDocumentSeen(mainData.get(position).getDocumentID(), person);
                    // и открываем
                    ActionUtils.openDocument(mainData.get(position).getDocumentID(), getActivity(), fragment, person, type);
                }
            }

            @Override
            public void onClosed(int position, boolean fromRight) {
                mainRefreshLayout.setEnabled(true);
            }

            @Override
            public void onListChanged() {
            }

            @Override
            public void scaleBegin(int position) {
                mainList.setSwipeMode(SwipeListView.SWIPE_MODE_NONE);
                mainRefreshLayout.setEnabled(false);
            }

            @Override
            public void scaleEnd(int position) {
                if (mainData != null && !mainData.isEmpty()) {
                    mainData.get(position).setOpened(!mainData.get(position).isOpened());
                    mainAdapter.notifyDataSetChanged();
                    mainList.setSwipeMode(SwipeListView.SWIPE_MODE_LEFT);
                    mainRefreshLayout.setEnabled(true);
                }
            }

            @Override
            public void onMove(int position, float x) {
            }

            @Override
            public void onStartOpen(int position, int action, boolean right) {
                mainRefreshLayout.setEnabled(false);
            }

            @Override
            public void onStartClose(int position, boolean right) {
            }

            @Override
            public void onClickBackView(int position) {
            }

            @Override
            public void onDismiss(int[] reverseSortedPositions) {
            }
        });
    }

    /**
     * Метод используется для обновления списка из фильтров
     *
     * @param url        url до списка документов
     * @param filterType filterType текущего фильтра
     * @param type       тип плашки
     * @see DocumentConst#ALL
     * @see DocumentConst#JOURNAL
     */
    public void updateList(String url, String filterType, String type) {
        mainList.setSelection(0);
        currentUrl = url;
        pageNumber = 0;
        this.type = type;
        this.filterType = filterType;
        if (type.equals(DocumentConst.ALL)) {
            if (tablet) {
                mainAdapter = new AdapterDocumentsAllTablet(getActivity().getApplicationContext(), mainData,
                        false, R.layout.main_activity, filterType);
            } else {
                mainAdapter = new AdapterDocumentsAll(getActivity().getApplicationContext(), mainData,
                        false, R.layout.main_activity, filterType, person);
            }
        } else if (type.equals(DocumentConst.JOURNAL)) {
            if (tablet) {
                mainAdapter = new AdapterDocumentsJournalTablet(getActivity().getApplicationContext(), mainData,
                        false, R.layout.main_activity, person);
            } else {
                mainAdapter = new AdapterDocumentsJournal(getActivity().getApplicationContext(), mainData,
                        false, R.layout.main_activity, person);
            }
        }
        mainList.setAdapter(mainAdapter);
        getDocuments(currentUrl, true, true, false);
    }

    /**
     * Загружает документы в список
     *
     * @param url       - ссылка до списка с документами
     * @param clearList - очищать ли список с документами при загрузке документов
     */
    public void getDocuments(final String url, final boolean clearList, final boolean showProgress, final boolean syncServer) {
        new SendGetRequest(url, person) {
            @Override
            protected void onPreExecute() {
                if (showProgress) {
                    mainProgressBar.setVisibility(View.VISIBLE);
                }
                super.onPreExecute();
            }
            @Override
            protected void onPostExecute(String result) {
                mainProgressBar.setVisibility(View.GONE);
                if (syncServer && !SyncMain.canSync && Utils.checkSyncEnables(settings)) {
                    AppMsg.makeText(getActivity(), getString(R.string.can_not_sync), AppMsg.STYLE_ALERT).show();
                    mainRefreshLayout.setRefreshing(false);
                    return;
                }
                if (result != null) {
                    DocumentItem[] documentsList = RestClient.getGson().fromJson(result, DocumentItem[].class);
                    if (documentsList.length != 0) {
                        if (clearList) {
                            mainData.clear();
                        }
                        Collections.addAll(mainData, documentsList);
                        if (syncServer && Utils.checkSyncEnables(settings) && Utils.isOnline(getActivity(), person.getHost())) {
                            sync(url);
                        }
                        isLoading = false;
                    } else {
                        if (clearList) {
                            mainData.clear();
                        }
                        isLoading = true;
                    }
                } else if (Utils.checkSyncEnables(settings)) {
                    if (!clearList) {
                        return;
                    }
                    result = new DocumentTable(getActivity().getBaseContext()).get(person.getHost() + url);
                    DocumentItem[] documentsList = RestClient.getGson().fromJson(result, DocumentItem[].class);
                    if (documentsList.length != 0) {
                        mainData.clear();
                        Collections.addAll(mainData, documentsList);
                        isLoading = false;
                    }
                } else {
                    AppMsg.makeText(getActivity(), getString(R.string.no_connection), AppMsg.STYLE_ALERT).show();
                }
                refreshMainDocuments();
                super.onPostExecute(result);
            }
        }.execute();
    }

    /**
     * Данный метод синхронизирует работы, которые отображаются на данный момент в списке
     * Вызывается при обновлении списка свайпом
     */
    private void sync(final String url) {
        List<String> keys = new DocumentTable(getActivity().getBaseContext()).getAll();
        if (keys.isEmpty()) {
            AppMsg.makeText(getActivity(), getActivity().getString(R.string.no_sync_data), AppMsg.STYLE_ALERT).show();
            return;
        }
        if (!SyncMain.canSync) {
            AppMsg.makeText(getActivity(), getString(R.string.can_not_sync), AppMsg.STYLE_ALERT).show();
            return;
        }
        new SendGetRequest("about", person) {
            @Override
            protected void onPostExecute(String result) {
                if (result == null) {
                    return;
                }
                SyncMain offline = new SyncMain(getActivity(), person);
                offline.setAllSync(false);
                offline.setShowProgress(false);
                offline.setSend(false);
                offline.setDocumentsKey(url);
                offline.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
                super.onPostExecute(result);
            }
        }.execute();
    }

    /**
     * Список с дочерними документами
     */
    private void initChildWorksSlidingMenu() {
        childDataSlidingMenu = new SlidingMenu(getActivity().getApplicationContext());
        childDataSlidingMenu.setMode(SlidingMenu.RIGHT);
        childDataSlidingMenu.attachToActivity(getActivity(), SlidingMenu.SLIDING_CONTENT);
        childDataSlidingMenu.setMenu(initChildDocumentList());
        childDataSlidingMenu.setSlidingEnabled(false);
        childDataSlidingMenu.setBehindOffset(Utils.convertDpToPixel(Const.SLIDING_MENU_BEHIND_WIDTH, getActivity()));
        childDataSlidingMenu.setOnClosedListener(new SlidingMenu.OnClosedListener() {
            @Override
            public void onClosed() {
                listPosition = 0;
                headChildData.clear();
                childDataSlidingMenu.setSlidingEnabled(false);
                ((MainActivity) getActivity()).getFiltersSlidingMenu().setSlidingEnabled(true);
                ((MainActivity) getActivity()).createEventActionBar();
            }
        });
        childDataSlidingMenu.setOnOpenedListener(new SlidingMenu.OnOpenedListener() {
            @Override
            public void onOpened() {
                childDataSlidingMenu.setSlidingEnabled(true);
                ((MainActivity) getActivity()).getFiltersSlidingMenu().setSlidingEnabled(false);
            }
        });
    }

    /**
     * Метод инициализирует список дочерних документов и возвращает view
     *
     * @return view
     */
    public View initChildDocumentList() {

        LayoutInflater ltInflater = getActivity().getLayoutInflater();
        View view = ltInflater.inflate(R.layout.child_works_activity, null, false);

        ((TextView) view.findViewById(R.id.title_action_bar_child_works)).setTypeface(Fonts.getMedium(getActivity()));

        childProgressBar = (ProgressWheel) view.findViewById(R.id.child_work_progress_bar);

        // обновление дочерних документов свайпом
        childRefreshLayout = (SwipeRefreshLayout) view.findViewById(R.id.refresh_child);
        childRefreshLayout.setColorSchemeResources(R.color.color1_update_list, R.color.color2_update_list,
                R.color.color3_update_list, R.color.color4_update_list);
        childRefreshLayout.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() {
            @Override
            public void onRefresh() {
                childRefreshLayout.postDelayed(new Runnable() {
                    @Override
                    public void run() {
                        getChildDocuments(childUrl, false);
                    }
                }, 0);
            }
        });

        childList = (SwipeListView) view.findViewById(R.id.pull_refresh_list_child_works);
        childData = new ArrayList<>();

        // открытие дочернего документа
        childList.setSwipeListViewListener(new BaseSwipeListViewListener() {
            @Override
            public void onOpened(int position, boolean toRight) {
                // если у документа есть дочерние и если есть соединение с интернетом и если текущая плашка не раскрыта
                if (position != 0 && childData.get(position).getHasChildren().equals("true") &&
                        Utils.isOnline(getActivity(), person.getHost()) && !childData.get(position).isOpened()) {
                    headChildData.add(childData.get(position));
                    childProgressBar.setVisibility(View.VISIBLE);
                    childUrl = "rest/api/docflow/doc/child_documents?documentID=" +
                            childData.get(position).getDocumentID() + "&locale=" + MyApplication.getLang();
                    listPosition++;
                    urlToChildData.add(childUrl);
                    getChildDocuments(childUrl, true);
                }
                childList.closeOpenedItems();
            }

            @Override
            public void onDouble(int position) {
                if (childData != null && !childData.isEmpty()) {
                    childData.get(position).setOpened(!childData.get(position).isOpened());
                    childAdapter.notifyDataSetChanged();
                }
            }

            @Override
            public void scaleBegin(int position) {
                if (childData != null && !childData.isEmpty()) {
                    childList.setSwipeMode(SwipeListView.SWIPE_MODE_NONE);
                    childRefreshLayout.setEnabled(false);
                }
            }

            @Override
            public void scaleEnd(int position) {
                if (childData != null && !childData.isEmpty()) {
                    childData.get(position).setOpened(!childData.get(position).isOpened());
                    childAdapter.notifyDataSetChanged();
                    childList.setSwipeMode(SwipeListView.SWIPE_MODE_LEFT);
                    childRefreshLayout.setEnabled(true);
                }
            }

            @Override
            public void onLong(int position) {
                if (childData != null && !childData.isEmpty()) {
                    showDialog(position);
                }
            }

            @Override
            public void onSingle(int position) {
                if (childData != null && !childData.isEmpty()) {
                    // говорим что просмотрели изменения
                    ActionUtils.markDocumentSeen(childData.get(position).getDocumentID(), person);
                    // и открываем документ
                    ActionUtils.openDocument(childData.get(position).getDocumentID(), getActivity(), fragment, person, type);
                }
            }

            @Override
            public void onClosed(int position, boolean fromRight) {
                childRefreshLayout.setEnabled(true);
            }

            @Override
            public void onListChanged() {
            }

            @Override
            public void onMove(int position, float x) {
            }

            @Override
            public void onStartOpen(int position, int action, boolean right) {
                childRefreshLayout.setEnabled(false);
            }

            @Override
            public void onStartClose(int position, boolean right) {
            }

            @Override
            public void onClickBackView(int position) {
            }

            @Override
            public void onDismiss(int[] reverseSortedPositions) {
            }
        });
        return view;
    }

    /**
     * Метод аналогичен методу getDocumentList, только загружает дочерние документы
     *
     * @param url - ссылка до дочерних документов
     */
    private void getChildDocuments(String url, final boolean showProgress) {
        // тип адаптера передаем при загрузки дочерних
        if (type.equals(DocumentConst.ALL)) {
            if (tablet) {
                childAdapter = new AdapterDocumentsAllTablet(getActivity().getApplicationContext(), childData,
                        true, R.layout.main_activity, filterType);
            } else {
                childAdapter = new AdapterDocumentsAll(getActivity().getApplicationContext(), childData,
                        true, R.layout.main_activity, filterType, person);
            }
        } else if (type.equals(DocumentConst.JOURNAL)) {
            if (tablet) {
                childAdapter = new AdapterDocumentsJournalTablet(getActivity().getApplicationContext(), childData,
                        true, R.layout.main_activity, person);
            } else {
                childAdapter = new AdapterDocumentsJournal(getActivity().getApplicationContext(), childData,
                        true, R.layout.main_activity, person);
            }
        }
        childList.setAdapter(childAdapter);
        new SendGetRequest(url, person) {
            @Override
            protected void onPreExecute() {
                if (showProgress) {
                    childProgressBar.setVisibility(View.VISIBLE);
                }
                super.onPreExecute();
            }

            @Override
            protected void onPostExecute(String result) {
                childProgressBar.setVisibility(View.GONE);
                if (result == null) {
                    childData.clear();
                    refreshChildDocuments();
                    AppMsg.makeText(getActivity(), getString(R.string.error_request), AppMsg.STYLE_ALERT).show();
                    return;
                }
                DocumentItem[] documents;
                try {
                    documents = RestClient.getGson().fromJson(result, DocumentItem[].class);
                } catch (JsonSyntaxException exc) {
                    documents = null;
                }
                if (documents == null) {
                    return;
                }
                if (documents.length != 0) {
                    childData.clear();
                    childData.add(headChildData.get(listPosition - 1));
                    Collections.addAll(childData, documents);
                } else {
                    // если дочерние вдруг кончились - закрываем боковую навигацию, и грузим заного список основных документов
                    childData.clear();
                    listPosition = 0;
                    childDataSlidingMenu.toggle();
                    getDocuments(currentUrl, true, true, false);
                }
                refreshChildDocuments();
                super.onPostExecute(result);
            }
        }.execute();
    }

    /**
     * Метод срабатывает при натажии на кнопку "Back"
     */
    private void backPressed() {
        if (listPosition == 1) {
            headChildData.remove(listPosition - 1);
            listPosition = 0;
            childDataSlidingMenu.toggle();
        } else if (listPosition >= 2) {
            headChildData.remove(listPosition - 1);
            childProgressBar.setVisibility(View.VISIBLE);
            getChildDocuments(urlToChildData.get(listPosition - 2), true);
            listPosition--;
        } else {
            SharedPreferences.Editor editor = settings.edit();
            editor.putBoolean(Const.BACK_PRESSED_SYNC, false);
            editor.apply();
            getActivity().finish();
        }
    }

    /**
     * Начало инициализации компонентов
     */
    private void initComponents() {
        init();
        initMainList();
        initChildWorksSlidingMenu();
    }

    /**
     * Инициализация полей
     */
    private void init() {
        settings = getActivity().getSharedPreferences(SettingsConst.DEFAULT_NAME_SETTINGS, Context.MODE_PRIVATE);
        person = (Person) getArguments().getSerializable(ActivityConst.PERSON);
        currentUrl = person.getHost() + "rest/api/docflow/doc/documents?pageNumber=" + pageNumber + "&locale=" + MyApplication.getLang();
    }

    /**
     * Обновление списка документов
     */
    private void refreshMainDocuments() {
        mainAdapter.notifyDataSetChanged();
        mainRefreshLayout.setRefreshing(false);
    }

    /**
     * Обновление списка дочерних документов
     */
    private void refreshChildDocuments() {
        childAdapter.notifyDataSetChanged();
        childRefreshLayout.setRefreshing(false);
    }

    /**
     * Планшет либо обычный смартфон
     *
     * @return - true/false
     */
    boolean isLarge() {
        return (getResources().getConfiguration().screenLayout &
                Configuration.SCREENLAYOUT_SIZE_MASK) >= Configuration.SCREENLAYOUT_SIZE_LARGE;
    }

    /**
     * Метод вызывается при долгом нажатии на плашку документа (вызов контекстного меню)
     *
     * @param position - позиция выделенного документа в списке
     */
    private void showDialog(final int position) {
        AlertDialog.Builder dialog = new AlertDialog.Builder(getActivity());
        dialog.setTitle(getActivity().getResources().getString(R.string.edit_document));
        // пункты контекстного меню
        List<String> items = getDialogItems(position, (listPosition == 0 ? mainData : childData));
        dialog.setItems(items.toArray(new String[items.size()]), new DialogInterface.OnClickListener() {
            @Override
            public void onClick(DialogInterface dialog, final int pos) {
                dialogItemEvent(position, pos, (listPosition == 0 ? mainData : childData),
                        (listPosition == 0 ? mainAdapter : childAdapter));
            }
        });
        dialog.setCancelable(true);
        if (!items.isEmpty()) {
            dialog.show();
        }
    }

    /**
     * Метод отображает диалог действительно ли пользователь хочет удалить/скрыть документ
     *
     * @param position позиция выделенного документа в списке
     */
    private void hideDocumentDialog(final int position, final List<DocumentItem> list) {
        AlertDialog.Builder ad = new AlertDialog.Builder(getActivity());
        ad.setTitle(getActivity().getResources().getString(R.string.edit_document));
        if (listPosition == 0) {
            ad.setMessage((mainData.get(position).getHidden().equals("true") ?
                    getResources().getString(R.string.return_document_question) :
                    getResources().getString(R.string.hide_document_question)));
        } else {
            ad.setMessage((childData.get(position).getHidden().equals("true") ?
                    getResources().getString(R.string.return_document_question) :
                    getResources().getString(R.string.hide_document_question)));
        }
        ad.setPositiveButton(getString(R.string.yes), new DialogInterface.OnClickListener() {
            public void onClick(DialogInterface dialog, int arg1) {
                // тап по пункту
                hideDocument(list.get(position).getDocumentID(), list.get(position).getHidden().equals("true"));
            }
        });
        ad.setNegativeButton(getString(R.string.no), null);
        ad.setCancelable(true);
        ad.show();
    }

    /**
     * Метод вызывается по тапу на пункт контекстного меню
     *
     * @param position позиция выделенного документа в списке
     * @param pos      позиция пункта контестного меню
     * @param list     список документов, для которого получаются пункты
     */
    private void dialogItemEvent(int position, int pos, List<DocumentItem> list, ArrayAdapter<DocumentItem> adapter) {
        // если текущий пункт первый
        if (pos == 0) {
            // на планшетной версии нет возможности развернуть плашку, значит пункт может быть только один - "Скрыть"
            if (!tablet) {
                list.get(position).setOpened(!list.get(position).isOpened());
                adapter.notifyDataSetChanged();
            } else {
                hideDocumentDialog(position, list);
            }
        } else {
            hideDocumentDialog(position, list);
        }
    }

    /**
     * Метод возвращает пункты меню для диалога (вызывается лонг тапом на плашку документа)
     *
     * @param position позиция выделенного документа в списке
     * @param list     список документов, для которого получаются пункты
     * @return пункты для диалога
     */
    private List<String> getDialogItems(int position, List<DocumentItem> list) {
        List<String> items = new ArrayList<>();
        // если используется не планшет
        if (!tablet) {
            // если плашка уже развернута - пункт отображается как "Скрыть информацию", иначе - "Показать информацию"
            items.add((list.get(position).isOpened() ? getActivity().getString(R.string.hide_information) :
                    getActivity().getString(R.string.show_information)));
        }
        // если тип плашки "Все" - есть возможность скрыть/восстановить документ
        if (type.equals(DocumentConst.ALL) && list == mainData) {
            // если документ уже скрыт - пункт отображается как "Восстановить", иначе - скрыть
            items.add((list.get(position).getHidden().equals("true") ? getActivity().getString(R.string.document_return) :
                    getActivity().getString(R.string.document_hide)));
        }
        return items;
    }

    /**
     * Метод используется для скрытия документа
     *
     * @param documentID uuid документа
     */
    private void hideDocument(String documentID, boolean hide) {
        new SendGetRequest("rest/api/docflow/doc/hide?documentID=" + documentID + "&filterType=" +
                filterType + "&locale=" + MyApplication.getLang() + "&hidden=" + !hide, person) {
            @Override
            protected void onPostExecute(String result) {
                if (result == null) {
                    AppMsg.makeText(getActivity(), getString(R.string.error_request), AppMsg.STYLE_ALERT).show();
                    return;
                }
                ErrorCode errorCode;
                try {
                    errorCode = RestClient.getGson().fromJson(result, ErrorCode.class);
                } catch (Exception exc) {
                    AppMsg.makeText(getActivity(), getString(R.string.error_request), AppMsg.STYLE_ALERT).show();
                    return;
                }
                if (errorCode.getErrorCode().equals(Wrapper.NO_ERROR)) {
                    // обновление списка
                    if (listPosition == 0) {
                        getDocuments(currentUrl, true, true, false);
                    } else {
                        getChildDocuments(childUrl, true);
                    }
                } else {
                    AppMsg.makeText(getActivity(), errorCode.getErrorMessage(), AppMsg.STYLE_ALERT).show();
                }
                super.onPostExecute(result);
            }
        }.execute();
    }

    /**
     * Метод используется для удаления прогрессбара с экрана
     */
    public void hideProgressBar() {
        if (mainProgressBar == null) {
            return;
        }
        mainProgressBar.setVisibility(View.GONE);
    }

}