package com.example.todocloud.adapter;

import android.content.Context;
import android.content.Intent;
import android.support.v7.widget.AppCompatCheckBox;
import android.support.v7.widget.RecyclerView;
import android.util.SparseBooleanArray;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.TextView;

import com.example.todocloud.R;
import com.example.todocloud.app.AppController;
import com.example.todocloud.data.Todo;
import com.example.todocloud.datastorage.DbLoader;
import com.example.todocloud.service.AlarmService;

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

public class TodoAdapter extends RecyclerView.Adapter<TodoAdapter.MyViewHolder> {

  private List<Todo> todos;
  private SparseBooleanArray selectedTodos;
  private DbLoader dbLoader;

  public TodoAdapter(DbLoader dbLoader) {
    todos = new ArrayList<>();
    selectedTodos = new SparseBooleanArray();
    this.dbLoader = dbLoader;
  }

  public void updateDataSet(ArrayList<Todo> todosList) {
    this.todos.clear();
    this.todos.addAll(todosList);
  }

  @Override
  public MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
    View itemView = LayoutInflater.from(parent.getContext())
        .inflate(R.layout.todo_item, parent, false);

    return new MyViewHolder(itemView);
  }

  @Override
  public void onBindViewHolder(final MyViewHolder holder, int position) {
    final Todo todo = todos.get(position);

    holder.completed.setChecked(todo.getCompleted());
    holder.title.setText(todo.getTitle());
    holder.dueDate.setText(todo.getDueDate());
    holder.priority.setVisibility(todo.isPriority() ? View.VISIBLE : View.INVISIBLE);

    holder.itemView.setActivated(selectedTodos.get(position));
    holder.completed.setOnTouchListener(new View.OnTouchListener() {

      @Override
      public boolean onTouch(View v, MotionEvent event) {
        if (shouldHandleCheckBoxTouchEvent(event, holder)) {
          toggleCompleted(todo);
          updateTodo(todo);
          removeTodoFromAdapter(holder);
          handleReminderService(todo);
        }

        return true;
      }

    });
  }

  private void removeTodoFromAdapter(MyViewHolder holder) {
    int todoAdapterPosition = holder.getAdapterPosition();
    todos.remove(todoAdapterPosition);
    notifyItemRemoved(todoAdapterPosition);
  }

  private void toggleCompleted(Todo todo) {
    todo.setCompleted(!todo.getCompleted());
  }

  private void updateTodo(Todo todo) {
    todo.setDirty(true);
    dbLoader.updateTodo(todo);
  }

  private boolean shouldHandleCheckBoxTouchEvent(MotionEvent event, MyViewHolder holder) {
    // To reproduce "holder.getAdapterPosition() == -1", do the following: select 1 todo and
    // touch it's CheckBox.
    return !AppController.isActionMode()
        && event.getAction() == MotionEvent.ACTION_UP
        && holder.getAdapterPosition() != -1;
  }

  private void handleReminderService(Todo todo) {
    if (isCompleted(todo)) {
      cancelReminderService(todo);
    } else if (isSetReminder(todo)) {
      createReminderService(todo);
    }
  }

  private void cancelReminderService(Todo todo) {
    Context applicationContext = AppController.getAppContext();
    Intent reminderService = new Intent(applicationContext, AlarmService.class);
    reminderService.putExtra("todo", todo);
    reminderService.setAction(AlarmService.CANCEL);
    applicationContext.startService(reminderService);
  }

  private boolean isSetReminder(Todo todo) {
    return !todo.getReminderDateTime().equals("-1");
  }

  private void createReminderService(Todo todo) {
    Context applicationContext = AppController.getAppContext();
    Intent reminderService = new Intent(applicationContext, AlarmService.class);
    reminderService.putExtra("todo", todo);
    reminderService.setAction(AlarmService.CREATE);
    applicationContext.startService(reminderService);
  }

  private Boolean isCompleted(Todo todo) {
    return todo.getCompleted();
  }

  @Override
  public int getItemCount() {
    return todos.size();
  }

  public Todo getTodo(int position) {
    return todos.get(position);
  }

  public void toggleSelection(int position) {
    if (isNotSelected(position)) {
      selectedTodos.put(position, true);
    } else {
      selectedTodos.delete(position);
    }
    notifyItemChanged(position);
  }

  public void clearSelection() {
    selectedTodos.clear();
    notifyDataSetChanged();
  }

  public int getSelectedItemCount() {
    return selectedTodos.size();
  }

  public ArrayList<Todo> getSelectedTodos() {
    Todo selectedTodo;
    ArrayList<Todo> selectedTodos = new ArrayList<>(this.selectedTodos.size());
    for (int i = 0; i < this.selectedTodos.size(); i++) {
      int selectedTodoPosition = this.selectedTodos.keyAt(i);
      selectedTodo = getTodo(selectedTodoPosition);
      selectedTodos.add(selectedTodo);
    }
    return selectedTodos;
  }

  private boolean isNotSelected(int position) {
    return !selectedTodos.get(position);
  }

  public class MyViewHolder extends RecyclerView.ViewHolder {

    public AppCompatCheckBox completed;
    public TextView title;
    public TextView dueDate;
    public ImageView priority;

    public MyViewHolder(View itemView) {
      super(itemView);
      completed = (AppCompatCheckBox) itemView.findViewById(R.id.completed);
      title = (TextView) itemView.findViewById(R.id.title);
      dueDate = (TextView) itemView.findViewById(R.id.dueDate);
      priority = (ImageView) itemView.findViewById(R.id.priority);
    }

  }

}

@@ -2223,32 +2223,226 @@
 %7D%0A%0A    %7D);%0A  %7D%0A%0A
+  private void toggleCompleted(Todo todo) %7B%0A    todo.setCompleted(!todo.getCompleted());%0A  %7D%0A%0A  private void updateTodo(Todo todo) %7B%0A    todo.setDirty(true);%0A    dbLoader.updateTodo(todo);%0A  %7D%0A%0A
   private void r
@@ -2643,39 +2643,45 @@
 rivate void 
-toggleCompleted
+handleReminderService
 (Todo todo) 
@@ -2682,32 +2682,30 @@
 todo) %7B%0A    
-todo.set
+if (is
 Completed(!t
@@ -2706,131 +2706,125 @@
 ted(
-!
 todo
-.getCompleted());%0A  %7D%0A%0A  private void updateTodo(Todo 
+)) %7B%0A      cancelReminderService(
 todo)
- %7B
+;
 %0A    
-todo.setDirty(true);%0A    dbLoader.updateTodo
+%7D else if (isSetReminder(todo)) %7B%0A      createReminderService
 (todo);%0A
   %7D%0A
@@ -2811,32 +2811,38 @@
 rService(todo);%0A
+    %7D%0A
   %7D%0A%0A  private b
@@ -3192,206 +3192,8 @@
  %7D%0A%0A
-  private void handleReminderService(Todo todo) %7B%0A    if (isCompleted(todo)) %7B%0A      cancelReminderService(todo);%0A    %7D else if (isSetReminder(todo)) %7B%0A      createReminderService(todo);%0A    %7D%0A  %7D%0A%0A
   pr

Organize methods to be in a consistent sequence