package de.stephanlindauer.criticalmaps.fragments;
import android.animation.Animator;
import android.animation.AnimatorInflater;
import android.animation.AnimatorListenerAdapter;
import android.animation.AnimatorSet;
import android.content.res.ColorStateList;
import android.graphics.PorterDuff;
import android.graphics.drawable.Drawable;
import android.os.Bundle;
import android.support.design.widget.FloatingActionButton;
import android.support.design.widget.TextInputLayout;
import android.support.v4.app.Fragment;
import android.support.v4.content.ContextCompat;
import android.support.v4.graphics.drawable.DrawableCompat;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.text.Editable;
import android.text.InputFilter;
import android.view.KeyEvent;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.view.inputmethod.EditorInfo;
import android.widget.EditText;
import android.widget.TextView;
import com.squareup.otto.Subscribe;
import org.ligi.axt.AXT;
import org.ligi.axt.simplifications.SimpleTextWatcher;
import java.util.ArrayList;
import javax.inject.Inject;
import butterknife.Bind;
import butterknife.ButterKnife;
import butterknife.OnClick;
import de.stephanlindauer.criticalmaps.App;
import de.stephanlindauer.criticalmaps.R;
import de.stephanlindauer.criticalmaps.adapter.ChatMessageAdapter;
import de.stephanlindauer.criticalmaps.events.NewLocationEvent;
import de.stephanlindauer.criticalmaps.events.NewServerResponseEvent;
import de.stephanlindauer.criticalmaps.interfaces.IChatMessage;
import de.stephanlindauer.criticalmaps.model.ChatModel;
import de.stephanlindauer.criticalmaps.model.OwnLocationModel;
import de.stephanlindauer.criticalmaps.provider.EventBusProvider;
import de.stephanlindauer.criticalmaps.vo.chat.OutgoingChatMessage;
public class ChatFragment extends Fragment {
//dependencies
@Inject
ChatModel chatModel;
@Inject
EventBusProvider eventService;
@Inject
OwnLocationModel ownLocationModel;
//view
@Bind(R.id.chat_recycler)
RecyclerView chatRecyclerView;
@Bind(R.id.text_input_layout)
TextInputLayout textInputLayout;
@Bind(R.id.chat_edit_message)
EditText editMessageTextField;
@Bind(R.id.chat_send_btn)
FloatingActionButton sendButton;
//misc
private boolean isScrolling = false;
private boolean isTextInputEnabled = true;
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
super.onCreateView(inflater, container, savedInstanceState);
App.components().inject(this);
View chatView = inflater.inflate(R.layout.fragment_chat, container, false);
ButterKnife.bind(this, chatView);
chatRecyclerView.setLayoutManager(new LinearLayoutManager(getContext()));
return chatView;
}
@Override
public void onActivityCreated(final Bundle savedState) {
super.onActivityCreated(savedState);
chatModelToAdapter();
textInputLayout.setCounterMaxLength(IChatMessage.MAX_LENGTH);
editMessageTextField.setFilters(new InputFilter[]{new InputFilter.LengthFilter(IChatMessage.MAX_LENGTH)});
Drawable wrappedDrawable = DrawableCompat.wrap(sendButton.getDrawable());
DrawableCompat.setTintMode(wrappedDrawable, PorterDuff.Mode.SRC_ATOP);
ColorStateList colorStateList = ContextCompat.getColorStateList(getActivity(),
R.color.chat_fab_drawable_states);
DrawableCompat.setTintList(wrappedDrawable, colorStateList);
sendButton.setImageDrawable(wrappedDrawable);
sendButton.setEnabled(false);
chatRecyclerView.setOnTouchListener(new View.OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
switch (event.getActionMasked()) {
case MotionEvent.ACTION_DOWN:
case MotionEvent.ACTION_MOVE:
isScrolling = true;
return false;
case MotionEvent.ACTION_CANCEL:
case MotionEvent.ACTION_UP:
isScrolling = false;
return false;
}
return false;
}
});
editMessageTextField.setOnEditorActionListener(new TextView.OnEditorActionListener() {
@Override
public boolean onEditorAction(TextView v, int actionId, KeyEvent event) {
if (actionId == EditorInfo.IME_ACTION_SEND) {
handleSendClicked();
return true;
}
return false;
}
});
editMessageTextField.addTextChangedListener(new SimpleTextWatcher() {
@Override
public void afterTextChanged(Editable s) {
setSendButtonEnabledWithAnimation(s.length() != 0);
}
});
if (ownLocationModel.ownLocation == null) {
setTextInputEnabled(false);
}
}
private void setSendButtonEnabledWithAnimation(final boolean enabled) {
if (sendButton.isEnabled() == enabled) {
return;
}
final AnimatorSet animatorSet = (AnimatorSet) AnimatorInflater.loadAnimator(getActivity(),
R.animator.chat_fab_state_change);
animatorSet.setTarget(sendButton);
// flip button state for color change after first half of the animation
final ArrayList<Animator> animations = animatorSet.getChildAnimations();
animations.get(0).addListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationEnd(Animator animation) {
sendButton.setEnabled(enabled);
}
});
animatorSet.start();
}
@OnClick(R.id.chat_send_btn)
void handleSendClicked() {
String message = editMessageTextField.getText().toString();
if (message.isEmpty()) {
return;
}
chatModel.setNewOutgoingMessage(new OutgoingChatMessage(message));
editMessageTextField.setText("");
chatModelToAdapter();
}
private void chatModelToAdapter() {
final ArrayList<IChatMessage> savedAndOutgoingMessages = chatModel.getSavedAndOutgoingMessages();
chatRecyclerView.setAdapter(new ChatMessageAdapter(savedAndOutgoingMessages));
if (!isScrolling) {
chatRecyclerView.scrollToPosition(savedAndOutgoingMessages.size() - 1);
}
}
@Override
public void onResume() {
super.onResume();
chatModelToAdapter();
eventService.register(this);
}
@Override
public void onPause() {
super.onPause();
eventService.unregister(this);
AXT.at(editMessageTextField).hideKeyBoard();
}
@Override
public void onDestroyView() {
super.onDestroyView();
ButterKnife.unbind(this);
}
@Subscribe
public void handleNewLocation(NewLocationEvent e) {
setTextInputEnabled(true);
}
@Subscribe
public void handleNewServerData(NewServerResponseEvent e) {
chatModelToAdapter();
}
private void setTextInputEnabled(final boolean enabled) {
if (!enabled) {
editMessageTextField.setEnabled(false);
textInputLayout.setHint(getString(R.string.map_searching_for_location));
isTextInputEnabled = false;
} else if (!isTextInputEnabled) {
editMessageTextField.setEnabled(true);
textInputLayout.setHint(getString(R.string.chat_text));
isTextInputEnabled = true;
}
}
}