package kz.arta.synergy.workflow.mobile.android.documents.route.activities;

import android.app.ActionBar;
import android.app.Activity;
import android.app.AlertDialog;
import android.app.DatePickerDialog;
import android.content.DialogInterface;
import android.content.Intent;
import android.os.Bundle;
import android.support.v4.app.FragmentActivity;
import android.text.Editable;
import android.text.TextWatcher;
import android.view.View;
import android.widget.Button;
import android.widget.DatePicker;
import android.widget.EditText;
import android.widget.TextView;
import android.widget.Toast;

import com.devspark.appmsg.AppMsg;

import java.util.ArrayList;
import java.util.Calendar;
import java.util.Collections;
import java.util.Date;
import java.util.HashSet;
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.components.DatePickerFragment;
import kz.arta.synergy.workflow.mobile.android.common.components.LengthEditText;
import kz.arta.synergy.workflow.mobile.android.common.components.WorkLoadEditText;
import kz.arta.synergy.workflow.mobile.android.common.models.Person;
import kz.arta.synergy.workflow.mobile.android.common.models.settings.CompletionFormItem;
import kz.arta.synergy.workflow.mobile.android.common.models.settings.ProcessItem;
import kz.arta.synergy.workflow.mobile.android.common.utils.DateUtils;
import kz.arta.synergy.workflow.mobile.android.common.utils.Fonts;
import kz.arta.synergy.workflow.mobile.android.common.utils.UserSerializable;
import kz.arta.synergy.workflow.mobile.android.common.utils.Utils;
import kz.arta.synergy.workflow.mobile.android.documents.route.RoutesConst;
import kz.arta.synergy.workflow.mobile.android.documents.route.models.RouteItemUser;
import kz.arta.synergy.workflow.mobile.android.documents.route.models.RouteListItem;
import kz.arta.synergy.workflow.mobile.android.users.activities.UserChooserMultiActivity;

/**
 * Created by neox on 24.07.15.
 * Добавление этапа
 */
public class AddRouteItemActivity extends FragmentActivity {

    /**
     * Выбор пользователей
     */
    private static final int USER_CHOOSER = 1;

    /**
     * Выбор машрута
     */
    private static final int ROUTE_LIST = 2;

    /**
     * Для добавления параллельного этапа
     */
    private static final int ADD_PARALLEL = 3;

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

    /**
     * Текущее активити
     */
    private Activity activity;

    /**
     * Редактируемый этап
     */
    private RouteItemUser routeItemUser;

    /**
     * Тип длительности
     *
     * @see RoutesConst#LENGTH_DAYS
     * @see RoutesConst#LENGTH_HOURS
     * @see RoutesConst#LENGTH_DATE
     */
    private String lengthType = RoutesConst.LENGTH_HOURS;

    /**
     * Идентификатор процесса
     *
     * @see RoutesConst.Processes
     */
    private String typeID;

    /**
     * Идентификаторы выбранных пользователей
     */
    private UserSerializable users;

    /**
     * Идентификатор формы завершения
     */
    private String formCompletionID;

    /**
     * Заголовки к компонентам
     */
    private Titles titles;

    /**
     * Компоненты
     */
    private Components components;

    /**
     * Значение возврата
     */
    private int returnNumber;

    /**
     * Номер этапа
     */
    private int number;

    /**
     * Код этапа
     */
    private String code;

    /**
     * Добавленные маршруты (заполняются после того, как пользователь выбрал какой-либо маршрут)
     */
    private List<RouteListItem> routes;

    /**
     * Идентификатор выбранного маршрута
     */
    private String routeID;

    /**
     * Коды этапов
     */
    private HashSet<String> codes;

    /**
     * Валидный ли введен код
     */
    private boolean validCode = true;

    /**
     * Добавить параллельный
     */
    private boolean addParallel;

    @Override
    protected void onCreate(Bundle savedInstanceState) {

        super.onCreate(savedInstanceState);
        setContentView(R.layout.add_route_item_activity);

        activity = this;

        ActionBar actionBar = getActionBar();
        if (actionBar != null) {
            actionBar.hide();
        }

        Intent intent = getIntent();
        person = (Person) intent.getSerializableExtra(ActivityConst.PERSON);
        routeItemUser = (RouteItemUser) intent.getSerializableExtra(RoutesConst.ROUTE_ITEM_USER);
        number = intent.getIntExtra(RoutesConst.ROUTE_ITEM_NUMBER, 0);
        code = intent.getStringExtra(RoutesConst.CODE);
        codes = (HashSet<String>) intent.getSerializableExtra(RoutesConst.CODES);
        addParallel = intent.getBooleanExtra(RoutesConst.ADD_PARALLEL, false);

        ((TextView) findViewById(R.id.add_route_item_activity_action_bar_title)).
                setText(getResources().getString((routeItemUser != null ? R.string.step : R.string.new_step)));

        titles = new Titles();
        components = new Components();

        initComponents();
        initButtons();
    }

    /**
     * Инициализация
     */
    private void initComponents() {

        if (person.getProcesses() == null || person.getProcesses()[0] == null) {
            return;
        }

        routes = new ArrayList<>();

        typeID = person.getProcesses()[0].getType();

        // номер этапа
        components.number.setText(String.valueOf(number));

        // тип
        components.type.setTypeface(Fonts.getMedium(activity));
        components.type.setText(person.getProcesses()[0].getName());
        components.type.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                showTypeDialog();
            }
        });

        // пользователи
        components.users.setTypeface(Fonts.getMedium(activity));
        components.users.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Intent intent = new Intent(activity, UserChooserMultiActivity.class);
                intent.putExtra(ActivityConst.PERSON, person);
                intent.putExtra(ActivityConst.SHOW_ALL, person.getSettings().getAllowAddWorkResponsibles());
                if (users != null && users.getUsersID() != null && !users.getUsersID().isEmpty()) {
                    intent.putExtra(ActivityConst.SELECTED, users.getUsersID().toArray(new String[users.getUsersID().size()]));
                }
                startActivityForResult(intent, USER_CHOOSER);
            }
        });

        // значение длительности (числовое поле)
        components.lengthValueNumber.setValue(person.getSettings().getDefaultLength().getDefault_work_length());

        // значение длительности (компонент выбора времени)
        components.lengthValueDate.setTypeface(Fonts.getMedium(activity));
        components.lengthValueDate.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                showDatePicker();
            }
        });

        // тип длительности
        components.lengthType.setTypeface(Fonts.getMedium(activity));
        components.lengthType.setText(getString(R.string.length_hours));
        components.lengthType.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                showLengthDialog();
            }
        });

        // значение нагрузки
        components.workLoadValue.setValue(String.valueOf(RoutesConst.DEFAULT_LENGTH));

        components.returnTextView.setTypeface(Fonts.getMedium(activity));
        components.returnTextView.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                showReturnDialog();
            }
        });

        // форма завершения
        components.completionForm.setTypeface(Fonts.getMedium(activity));
        components.completionForm.setText(getString(R.string.no));
        components.completionForm.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                showFormCompletionDialog();
            }
        });

        components.code.addTextChangedListener(new TextWatcher() {
            @Override
            public void beforeTextChanged(CharSequence s, int start, int count, int after) {
            }
            @Override
            public void onTextChanged(CharSequence s, int start, int before, int count) {
                if (code != null && code.equals(s.toString())) {
                    validCode = true;
                    return;
                }
                if (codes.contains(s.toString())) {
                    components.code.setBackgroundResource(R.drawable.edit_text_background_not_valid);
                    validCode = false;
                } else {
                    components.code.setBackgroundResource(R.drawable.edit_text_background);
                    validCode = true;
                }
            }
            @Override
            public void afterTextChanged(Editable s) {
            }
        });

        // код этапа
        components.code.setText((code != null ? code : ""));

        // если редактируется существующий пункт - заполняем экран данными
        if (routeItemUser != null) {
            // идентификатор процесса
            typeID = routeItemUser.getTypeID();
            // тип длительности
            lengthType = routeItemUser.getLengthType();
            // имя этапа
            components.name.setText(routeItemUser.getName());
            // идентификатор формы завершения
            formCompletionID = routeItemUser.getCompletionFormID();
            // тип нагрузки
            components.workLoadValue.setType(routeItemUser.getWorkLoadType());
            // значение нагрузки
            components.workLoadValue.setValue(routeItemUser.getWorkloadValue());
            // ответственный за этап
            components.users.setText(routeItemUser.getUserName());
            // имя процесса
            components.type.setText(Utils.getNameByTypeID(person, typeID));
            // тип длительности
            components.lengthType.setText(Utils.getNameByLengthType(routeItemUser.getLengthType(), activity));
            // значение длительности
            setLengthValue();
            // форма завершения
            components.completionForm.setText(Utils.getFormCompletion(routeItemUser.getCompletionFormID(), person, activity, false));
            // номер возврата
            components.returnTextView.setText(((routeItemUser.getReturnNumber().isEmpty() || routeItemUser.getReturnNumber().equals("0")) ? getResources().getString(R.string.no) : routeItemUser.getReturnNumber()));
            // пользователь
            if (routeItemUser.getUserID() != null) {
                users = new UserSerializable();
                users.setUsersID(Collections.singletonList(routeItemUser.getUserID()));
                users.setNames(Collections.singletonList(routeItemUser.getUserName()));
            }
            // если процесс маршрут
            if (routeItemUser.getTypeID().equals(RoutesConst.Processes.ROUTE)) {
                initRouteItem();
            }
        }

        checkComponents();
    }

    /**
     * Метод заполняет данными компоненты для типа "Маршрут"
     */
    private void initRouteItem() {
        RouteListItem routeItem = new RouteListItem();
        routeItem.setRouteID(routeItemUser.getRouteID());
        routeItem.setRouteName(routeItemUser.getRouteName());
        routes.add(routeItem);
        components.type.setText(routeItem.getRouteName());
        components.name.setText(routeItem.getRouteName());
        routeID = routeItem.getRouteID();
    }

    /**
     * Метод вызывается при нажатии на компонент "Возврат"
     */
    private void showReturnDialog() {
        if (typeID.equals(RoutesConst.Processes.AGREEMENT) || typeID.equals(RoutesConst.Processes.APPROVAL) ||
                typeID.equals(RoutesConst.Processes.BLOCKING_PROCESS) || typeID.equals(RoutesConst.Processes.REGISTRATION)) {
            List<String> items = new ArrayList<>();
            items.add(getResources().getString(R.string.no));
            for (int i = 0; i < number - 1; i++) {
                items.add(String.valueOf(i + 1));
            }
            final String[] itemsArray = new String[items.size()];
            items.toArray(itemsArray);
            AlertDialog.Builder dialog = new AlertDialog.Builder(activity);
            dialog.setTitle(getString(R.string.return_text));
            dialog.setItems(itemsArray, new DialogInterface.OnClickListener() {
                @Override
                public void onClick(DialogInterface dialog, int pos) {
                    returnNumber = pos;
                    components.returnTextView.setText(itemsArray[pos]);
                }
            });
            dialog.setCancelable(true);
            dialog.show();
        }
    }

    /**
     * Метод вызывается при редактировании пункта (выставляет нужное значение в компоненты связаные с длительностью)
     */
    private void setLengthValue() {
        if (routeItemUser.getLengthType().equals(RoutesConst.LENGTH_DATE)) {
            components.lengthValueDate.setText(DateUtils.parseData(routeItemUser.getLength(),
                    DateUtils.DEFAULT_EDIT_TEXT_DATE, DateUtils.DEFAULT_DATE_FORMAT));
        } else {
            components.lengthValueNumber.setValue(routeItemUser.getLength());
        }
    }

    /**
     * Инициализация кнопок
     */
    private void initButtons() {
        Button addParallelButton = (Button) findViewById(R.id.add_route_item_activity_button_add);
        addParallelButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                addParallelButtonPressed();
            }
        });
        Button saveButton = (Button) findViewById(R.id.add_route_item_activity_button_save);
        saveButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                if (valid()) {
                    Intent intent = new Intent();
                    intent.putExtra(ActivityConst.EDIT, (routeItemUser != null));
                    intent.putExtra(RoutesConst.ROUTE_ITEM_USER, getRouteItemUser());
                    intent.putExtra(RoutesConst.CODE, components.code.getText().toString());
                    if (users != null && users.getUsersID() != null && !users.getUsersID().isEmpty()) {
                        intent.putExtra(ActivityConst.SELECTED, users);
                    }
                    setResult(Activity.RESULT_OK, intent);
                    finish();
                    Toast.makeText(activity, getString(R.string.data_saved), Toast.LENGTH_LONG).show();
                }
            }
        });
        if (routeItemUser != null) {
            addParallelButton.setVisibility(View.VISIBLE);
        }
        if (addParallel) {
            addParallelButtonPressed();
        }
    }

    /**
     * Нажатие на кнопку "Добавить параллельный"
     */
    private void addParallelButtonPressed() {
        Intent intent = new Intent(activity, AddRouteItemActivity.class);
        intent.putExtra(ActivityConst.PERSON, person);
        intent.putExtra(RoutesConst.ROUTE_ITEM_NUMBER, number);
        intent.putExtra(RoutesConst.CODE, components.code.getText().toString());
        intent.putExtra(RoutesConst.CODES, codes);
        startActivityForResult(intent, ADD_PARALLEL);
    }

    /**
     * Метод вызывается перед нажатием на "Готово" - смотрит заполнены ли нужные компоненты
     */
    private boolean valid() {
        if (components.name.getText().toString().isEmpty()) {
            AppMsg.makeText(activity, getString(R.string.enter_name), AppMsg.STYLE_ALERT).show();
            return false;
        }
        if (users == null || users.getUsersID() == null) {
            if (typeID.equals(RoutesConst.Processes.ASSIGNMENT) || typeID.equals(RoutesConst.Processes.AGREEMENT) ||
                    typeID.equals(RoutesConst.Processes.APPROVAL) || typeID.equals(RoutesConst.Processes.ACQUAINTANCE) ||
                    typeID.equals(RoutesConst.Processes.RESOLUTION)) {
                AppMsg.makeText(activity, getString(R.string.enter_responsible), AppMsg.STYLE_ALERT).show();
                return false;
            }
        }
        if (!components.workLoadValue.isValid()) {
            if (typeID.equals(RoutesConst.Processes.ASSIGNMENT) || typeID.equals(RoutesConst.Processes.AGREEMENT) ||
                    typeID.equals(RoutesConst.Processes.APPROVAL) || typeID.equals(RoutesConst.Processes.ACQUAINTANCE) ||
                    typeID.equals(RoutesConst.Processes.RESOLUTION)) {
                AppMsg.makeText(activity, getString(R.string.enter_work_load), AppMsg.STYLE_ALERT).show();
                return false;
            }
        }
        if (!components.lengthValueNumber.isValid() && !lengthType.equals(RoutesConst.LENGTH_DATE)) {
            if (typeID.equals(RoutesConst.Processes.ASSIGNMENT) || typeID.equals(RoutesConst.Processes.AGREEMENT) ||
                    typeID.equals(RoutesConst.Processes.APPROVAL) || typeID.equals(RoutesConst.Processes.ACQUAINTANCE) ||
                    typeID.equals(RoutesConst.Processes.RESOLUTION) || typeID.equals(RoutesConst.Processes.REGISTRATION)) {
                AppMsg.makeText(activity, getString(R.string.enter_length), AppMsg.STYLE_ALERT).show();
                return false;
            }
        }
        if (!validCode) {
            AppMsg.makeText(activity, getString(R.string.code_already_exists), AppMsg.STYLE_ALERT).show();
            return false;
        }
        if (lengthType.equals(RoutesConst.LENGTH_DATE) && !validDate()) {
            AppMsg.makeText(activity, getString(R.string.incorrect_f_date), AppMsg.STYLE_ALERT).show();
            return false;
        }
        return true;
    }

    /**
     * Метод проверяет валидная ли введена дата завершения, она не должна быть меньше текущей
     */
    private boolean validDate() {
        Calendar cal1 = Calendar.getInstance();
        Calendar cal2 = Calendar.getInstance();
        cal1.setTime(new Date(System.currentTimeMillis()));
        cal2.setTime(new Date(Long.parseLong(DateUtils.getMillisecondsFromDateResolution(components.lengthValueDate.getText() + " " + "00:00"))));
        return cal2.after(cal1);
    }

    /**
     * Метод вызывается при нажатии на выбор типа процесса (отображает диалог)
     */
    private void showTypeDialog() {
        final List<ProcessItem> processes = Utils.getProcesses(person);
        final List<String> itemNames = new ArrayList<>();
        for (ProcessItem process : processes) {
            itemNames.add(process.getName());
        }
        for (RouteListItem route : routes) {
            itemNames.add(route.getRouteName());
        }
        final String[] itemsArray = new String[itemNames.size()];
        itemNames.toArray(itemsArray);
        AlertDialog.Builder dialog = new AlertDialog.Builder(activity);
        dialog.setTitle(getString(R.string.type_action));
        dialog.setItems(itemsArray, new DialogInterface.OnClickListener() {
            @Override
            public void onClick(DialogInterface dialog, int pos) {
                if (pos > processes.size() - 1) {
                    int p = pos - processes.size();
                    components.name.setText(routes.get(p).getRouteName());
                    components.type.setText(routes.get(p).getRouteName());
                    routeID = routes.get(p).getRouteID();
                    typeID = RoutesConst.Processes.ROUTE;
                } else {
                    if (processes.get(pos).getType().equals(RoutesConst.Processes.ROUTE)) {
                        openRouteListActivity();
                    } else {
                        typeID = processes.get(pos).getType();
                        components.type.setText(itemsArray[pos]);
                    }
                }
                checkComponents();
            }
        });
        dialog.setCancelable(true);
        dialog.show();
    }

    /**
     * Метод вызывается при нажатии на выбор типа длительности (отображает диалог)
     */
    private void showLengthDialog() {
        final String[] itemsArray = new String[]{
                getResources().getString(R.string.length_hours),
                getResources().getString(R.string.length_days),
                getResources().getString(R.string.length_date)
        };
        AlertDialog.Builder dialog = new AlertDialog.Builder(activity);
        dialog.setTitle(getString(R.string.length_finish_date));
        dialog.setItems(itemsArray, new DialogInterface.OnClickListener() {
            @Override
            public void onClick(DialogInterface dialog, int pos) {
                final double dayLength = Double.parseDouble(person.getSettings().getDayLength());
                final double length;
                if (components.lengthValueNumber.getValue().isEmpty()) {
                    length = 0;
                } else {
                    length = Double.parseDouble(components.lengthValueNumber.getValue());
                }
                components.lengthType.setText(itemsArray[pos]);
                switch (pos) {
                    case 0: {
                        tapLengthHours(length, dayLength);
                        break;
                    }
                    case 1: {
                        tapLengthDays(length, dayLength);
                        break;
                    }
                    case 2: {
                        tapLengthDate(length, dayLength);
                        break;
                    }
                }
            }
        });
        dialog.setCancelable(true);
        dialog.show();
    }

    /**
     * Тап по пункту диалога "Длительность (ч)"
     */
    private void tapLengthHours(double length, double dayLength) {
        components.lengthValueNumber.setVisibility(View.VISIBLE);
        components.lengthValueDate.setVisibility(View.GONE);
        if (lengthType.equals(RoutesConst.LENGTH_HOURS)) {
            return;
        } else if (lengthType.equals(RoutesConst.LENGTH_DAYS)) {
            components.lengthValueNumber.setValue(String.valueOf(length * dayLength));
        }
        lengthType = RoutesConst.LENGTH_HOURS;
    }

    /**
     * Тап по пункту диалога "Длительность (д)"
     */
    private void tapLengthDays(double length, double dayLength) {
        components.lengthValueNumber.setVisibility(View.VISIBLE);
        components.lengthValueDate.setVisibility(View.GONE);
        if (lengthType.equals(RoutesConst.LENGTH_DAYS)) {
            return;
        } else if (lengthType.equals(RoutesConst.LENGTH_HOURS)) {
            components.lengthValueNumber.setValue(String.valueOf(length / dayLength));
        }
        lengthType = RoutesConst.LENGTH_DAYS;
    }

    /**
     * Тап по пункту диалога "Дата завершения"
     */
    private void tapLengthDate(double length, double dayLength) {
        components.lengthValueNumber.setVisibility(View.GONE);
        components.lengthValueDate.setVisibility(View.VISIBLE);
        if (lengthType.equals(RoutesConst.LENGTH_DATE)) {
            return;
        }
        int d = 0;
        if (lengthType.equals(RoutesConst.LENGTH_HOURS)) {
            d = (int) (length / dayLength);
        } else if (lengthType.equals(RoutesConst.LENGTH_DAYS)) {
            d = (int) (length);
        }
        Calendar c = Calendar.getInstance();
        c.setTime(new Date());
        c.add(Calendar.DATE, d);
        components.lengthValueDate.setText(DateUtils.parseData(DateUtils.getDateFromMilliseconds(
                String.valueOf(c.getTimeInMillis())), DateUtils.DEFAULT_EDIT_TEXT_DATE, DateUtils.DEFAULT_DATE_FORMAT));
        lengthType = RoutesConst.LENGTH_DATE;
    }

    /**
     * Метод вызывается при нажатии на выбор формы завершения (отображает диалог)
     */
    private void showFormCompletionDialog() {
        final CompletionFormItem formItem = new CompletionFormItem();
        formItem.setName(getResources().getString(R.string.no));
        final List<CompletionFormItem> formItems = new ArrayList<>();
        formItems.add(formItem);
        List<String> itemNames = new ArrayList<>();
        itemNames.add(getResources().getString(R.string.no));
        for (CompletionFormItem item : person.getSettings().getWorkCompletionForms()) {
            formItems.add(item);
            itemNames.add(item.getName());
        }
        final String[] itemsArray = new String[itemNames.size()];
        itemNames.toArray(itemsArray);
        AlertDialog.Builder dialog = new AlertDialog.Builder(activity);
        dialog.setTitle(getString(R.string.form_completion));
        dialog.setItems(itemsArray, new DialogInterface.OnClickListener() {
            @Override
            public void onClick(DialogInterface dialog, int pos) {
                formCompletionID = formItems.get(pos).getId();
                components.completionForm.setText(formItems.get(pos).getName());
            }
        });
        dialog.setCancelable(true);
        dialog.show();
    }

    /**
     * Метод используется для отображения диалога выбора даты
     */
    private void showDatePicker() {
        DatePickerFragment date = new DatePickerFragment();
        Bundle args = new Bundle();
        args.putInt(DateUtils.YEAR, Integer.parseInt(DateUtils.parseData(components.lengthValueDate.getText().toString(),
                DatePickerFragment.YEAR, DateUtils.DEFAULT_EDIT_TEXT_DATE)));
        args.putInt(DateUtils.MONTH, Integer.parseInt(DateUtils.parseData(components.lengthValueDate.getText().toString(),
                DatePickerFragment.MONTH, DateUtils.DEFAULT_EDIT_TEXT_DATE)) - 1);
        args.putInt(DateUtils.DAY, Integer.parseInt(DateUtils.parseData(components.lengthValueDate.getText().toString(),
                DatePickerFragment.DAY, DateUtils.DEFAULT_EDIT_TEXT_DATE)));
        date.setArguments(args);
        date.setCallBack(new DatePickerDialog.OnDateSetListener() {
            @Override
            public void onDateSet(DatePicker datePicker, int year, int monthOfYear, int dayOfMonth) {
                components.lengthValueDate.setText(DateUtils.changePickerDialog(dayOfMonth) + " / " + DateUtils.changePickerDialog(monthOfYear + 1)
                        + " / " + String.valueOf(year));
            }
        });
        date.show(getSupportFragmentManager(), null);
    }

    /**
     * Метод возвращает текущиие этапы для отправки в предыдущее активити (вызывается при нажатии на кнопку "Готово")
     *
     * @return список этапов
     */
    private RouteItemUser getRouteItemUser() {
        RouteItemUser user = new RouteItemUser();
        // идентификатор процесса
        user.setTypeID(typeID);
        // имя этапа
        user.setName(components.name.getText().toString());
        // userID пока не заполняем
        user.setUserID("");
        // тип длительности
        user.setLengthType(lengthType);
        // тип нагрузки
        user.setWorkLoadType(components.workLoadValue.getType());
        // нагрузка
        user.setWorkloadValue(components.workLoadValue.getValue());
        // возврат
        user.setReturnNumber(String.valueOf(returnNumber));
        // длительность (в зависимости от текущего типа)
        if (lengthType.equals(RoutesConst.LENGTH_DATE)) {
            user.setLength(getDate());
        } else {
            user.setLength(components.lengthValueNumber.getValue());
        }
        // для процесса "Работа" заполняем форму завершения
        if (typeID.equals(RoutesConst.Processes.AGREEMENT)) {
            user.setCompletionFormID((formCompletionID != null ? formCompletionID : ""));
        }
        if (typeID.equals(RoutesConst.Processes.ROUTE) && routeID != null) {
            user.setRouteID(routeID);
            user.setRouteName(components.name.getText().toString());
        }
        return user;
    }

    /**
     * Метод возвращает дату для отправки на сервер из компонента, отображающий дату (
     */
    private String getDate() {
        return DateUtils.parseData(components.lengthValueDate.getText().toString(),
                DateUtils.DEFAULT_DATE_FORMAT, DateUtils.DEFAULT_EDIT_TEXT_DATE) + ":00";
    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        if (resultCode == RESULT_CANCELED) {
            return;
        }
        // выбор пользователя
        if (requestCode == USER_CHOOSER) {
            users = (UserSerializable) data.getSerializableExtra(ActivityConst.USERS_ID);
            components.users.setText(users.getNames().toString().replace("[", "").replace("]", ""));
            if (users.getUsersID().isEmpty()) {
                users = null;
            }
        } else if (requestCode == ROUTE_LIST) {
            RouteListItem route = (RouteListItem) data.getSerializableExtra(RoutesConst.ROUTE_LIST_ITEM);
            if (route == null) {
                return;
            }
            typeID = RoutesConst.Processes.ROUTE;
            routeID = route.getRouteID();
            components.name.setText(route.getRouteName());
            components.type.setText(route.getRouteName());
            routes.add(route);
            checkComponents();
        } else if (requestCode == ADD_PARALLEL) {
            // добавленные ответственные
            UserSerializable users = (UserSerializable) data.getSerializableExtra(ActivityConst.SELECTED);
            // этап маршрута
            RouteItemUser item = (RouteItemUser) data.getSerializableExtra(RoutesConst.ROUTE_ITEM_USER);
            // код
            String code = data.getStringExtra(RoutesConst.CODE);
            // посылаем интент в предыдущее активити
            Intent intent = new Intent();
            intent.putExtra(RoutesConst.ROUTE_ITEM_USER, item);
            intent.putExtra(ActivityConst.EDIT, true);
            intent.putExtra(RoutesConst.ADD_PARALLEL, true);
            intent.putExtra(RoutesConst.CODE, code);
            if (users != null && users.getUsersID() != null && !users.getUsersID().isEmpty()) {
                intent.putExtra(ActivityConst.SELECTED, users);
            }
            setResult(Activity.RESULT_OK, intent);
            finish();
        }
        super.onActivityResult(requestCode, resultCode, data);
    }

    /**
     * Метод отображает все компоненты на экране (которые изменяются в зависимости от типа)
     */
    private void showAllComponents() {
        components.users.setVisibility(View.VISIBLE);
        components.lengthType.setVisibility(View.VISIBLE);
        if (lengthType.equals(RoutesConst.LENGTH_DATE)) {
            components.lengthValueNumber.setVisibility(View.GONE);
            components.lengthValueDate.setVisibility(View.VISIBLE);
        } else {
            components.lengthValueNumber.setVisibility(View.VISIBLE);
            components.lengthValueDate.setVisibility(View.GONE);
        }
        components.workLoadValue.setVisibility(View.VISIBLE);
        components.returnTextView.setVisibility(View.VISIBLE);
        components.completionForm.setVisibility(View.VISIBLE);
        titles.titleUser.setVisibility(View.VISIBLE);
        titles.titleLength.setVisibility(View.VISIBLE);
        titles.titleWorkLoad.setVisibility(View.VISIBLE);
        titles.titleReturn.setVisibility(View.VISIBLE);
        titles.titleFormCompletion.setVisibility(View.VISIBLE);
    }

    /**
     * Метод открывает экран для выбора маршрута
     */
    private void openRouteListActivity() {
        Intent intent = new Intent(activity, RoutesListActivity.class);
        intent.putExtra(ActivityConst.PERSON, person);
        startActivityForResult(intent, ROUTE_LIST);
    }

    /**
     * Метод выставляет компоненты для текущего процесса
     */
    private void checkComponents() {
        showAllComponents();
        titles.titleUser.setText(getString(R.string.responsible));
        if (typeID.equals(RoutesConst.Processes.ASSIGNMENT)) {
            components.returnTextView.setVisibility(View.GONE);
            titles.titleReturn.setVisibility(View.GONE);
        } else if (typeID.equals(RoutesConst.Processes.AGREEMENT) || typeID.equals(RoutesConst.Processes.APPROVAL)) {
            components.completionForm.setVisibility(View.GONE);
            titles.titleFormCompletion.setVisibility(View.GONE);
        } else if (typeID.equals(RoutesConst.Processes.ACQUAINTANCE) || typeID.equals(RoutesConst.Processes.RESOLUTION)) {
            components.returnTextView.setVisibility(View.GONE);
            components.completionForm.setVisibility(View.GONE);
            titles.titleReturn.setVisibility(View.GONE);
            titles.titleFormCompletion.setVisibility(View.GONE);
        } else if (typeID.equals(RoutesConst.Processes.ROUTE)) {
            components.users.setVisibility(View.GONE);
            components.lengthType.setVisibility(View.GONE);
            components.lengthValueNumber.setVisibility(View.GONE);
            components.lengthValueDate.setVisibility(View.GONE);
            components.workLoadValue.setVisibility(View.GONE);
            components.returnTextView.setVisibility(View.GONE);
            components.completionForm.setVisibility(View.GONE);
            titles.titleUser.setVisibility(View.GONE);
            titles.titleLength.setVisibility(View.GONE);
            titles.titleWorkLoad.setVisibility(View.GONE);
            titles.titleReturn.setVisibility(View.GONE);
            titles.titleFormCompletion.setVisibility(View.GONE);
            components.users.setText("");
            users = null;
        } else if (typeID.equals(RoutesConst.Processes.SEND_DOCUMENT)) {
            components.lengthType.setVisibility(View.GONE);
            components.lengthValueNumber.setVisibility(View.GONE);
            components.lengthValueDate.setVisibility(View.GONE);
            components.workLoadValue.setVisibility(View.GONE);
            components.returnTextView.setVisibility(View.GONE);
            components.completionForm.setVisibility(View.GONE);
            titles.titleLength.setVisibility(View.GONE);
            titles.titleWorkLoad.setVisibility(View.GONE);
            titles.titleReturn.setVisibility(View.GONE);
            titles.titleFormCompletion.setVisibility(View.GONE);
            titles.titleUser.setText(getString(R.string.addressee));
        } else if (typeID.equals(RoutesConst.Processes.REGISTRATION)) {
            components.users.setVisibility(View.GONE);
            components.workLoadValue.setVisibility(View.GONE);
            components.completionForm.setVisibility(View.GONE);
            titles.titleUser.setVisibility(View.GONE);
            titles.titleWorkLoad.setVisibility(View.GONE);
            titles.titleFormCompletion.setVisibility(View.GONE);
            components.users.setText("");
            users = null;
        } else if (typeID.equals(RoutesConst.Processes.BLOCKING_PROCESS)) {
            components.users.setVisibility(View.GONE);
            components.lengthType.setVisibility(View.GONE);
            components.lengthValueNumber.setVisibility(View.GONE);
            components.lengthValueDate.setVisibility(View.GONE);
            components.workLoadValue.setVisibility(View.GONE);
            components.completionForm.setVisibility(View.GONE);
            titles.titleUser.setVisibility(View.GONE);
            titles.titleLength.setVisibility(View.GONE);
            titles.titleWorkLoad.setVisibility(View.GONE);
            titles.titleFormCompletion.setVisibility(View.GONE);
            components.users.setText("");
            users = null;
        }
    }

    /**
     * Заголовки к компонентам
     */
    private class Titles {

        /**
         * Пользователи
         */
        public TextView titleUser = (TextView) findViewById(R.id.add_route_item_activity_users_title);

        /**
         * Длительность
         */
        public TextView titleLength = (TextView) findViewById(R.id.add_route_item_activity_length_type_title);

        /**
         * Нагрузка
         */
        public TextView titleWorkLoad = (TextView) findViewById(R.id.add_route_item_activity_work_load_title);

        /**
         * Возврат
         */
        public TextView titleReturn = (TextView) findViewById(R.id.add_route_item_activity_return_title);

        /**
         * Форма завершения
         */
        public TextView titleFormCompletion = (TextView) findViewById(R.id.add_route_item_activity_form_completion_title);
    }

    /**
     * Компоненты
     */
    private class Components {

        public TextView number = (EditText) findViewById(R.id.add_route_item_activity_number);

        /**
         * Выбор типа
         */
        public TextView type = (TextView) findViewById(R.id.add_route_item_activity_type);

        /**
         * Имя Этапа
         */
        public TextView name = (TextView) findViewById(R.id.add_route_item_activity_name);

        /**
         * Пользователи
         */
        public TextView users = (TextView) findViewById(R.id.add_route_item_activity_users);

        /**
         * Тип длительности
         */
        public TextView lengthType = (TextView) findViewById(R.id.add_route_item_activity_length_type);

        /**
         * Значение длительности (числовое поле)
         */
        public LengthEditText lengthValueNumber = (LengthEditText) findViewById(R.id.add_route_item_activity_length_value);

        /**
         * Значение длительности (выбор даты)
         */
        public TextView lengthValueDate = (TextView) findViewById(R.id.add_route_item_activity_length_value_date);

        /**
         * Значение нагрузки
         */
        public WorkLoadEditText workLoadValue = (WorkLoadEditText) findViewById(R.id.add_route_item_activity_work_load_value);

        /**
         * Возврат
         */
        public TextView returnTextView = (TextView) findViewById(R.id.add_route_item_activity_return);

        /**
         * Форма завершения
         */
        public TextView completionForm = (TextView) findViewById(R.id.add_route_item_activity_form_completion);

        /**
         * Код
         */
        public EditText code = (EditText) findViewById(R.id.add_route_item_activity_code);
    }

}
