package net.everythingandroid.smspopup.controls;
import java.util.ArrayList;
import net.everythingandroid.smspopup.BuildConfig;
import net.everythingandroid.smspopup.R;
import net.everythingandroid.smspopup.provider.SmsMmsMessage;
import net.everythingandroid.smspopup.util.Log;
import android.content.Context;
import android.support.v4.view.ViewPager;
import android.support.v4.view.ViewPager.OnPageChangeListener;
import android.util.AttributeSet;
import android.view.GestureDetector;
import android.view.GestureDetector.SimpleOnGestureListener;
import android.view.MotionEvent;
import android.view.animation.Animation;
import android.view.animation.Animation.AnimationListener;
import android.view.animation.AnimationUtils;
import com.viewpagerindicator.CirclePageIndicator;
public class SmsPopupPager extends ViewPager implements OnPageChangeListener {
private ArrayList<SmsMmsMessage> messages;
private int currentPage;
private MessageCountChanged messageCountChanged;
private Context mContext;
private CirclePageIndicator mPagerIndicator;
private volatile boolean removingMessage = false;
private GestureDetector mGestureDetector;
public static int STATUS_MESSAGES_REMAINING = 0;
public static int STATUS_NO_MESSAGES_REMAINING = 1;
public static int STATUS_REMOVING_MESSAGE = 2;
public SmsPopupPager(Context context) {
super(context);
init(context);
}
public SmsPopupPager(Context context, AttributeSet attrs) {
super(context, attrs);
init(context);
}
private void init(Context context) {
mContext = context;
messages = new ArrayList<SmsMmsMessage>(5);
currentPage = 0;
setOffscreenPageLimit(1);
setPageMargin((int) context.getResources().getDimension(R.dimen.smspopup_pager_margin));
setLongClickable(true);
}
public int getPageCount() {
return messages.size();
}
public void setGestureListener(SimpleOnGestureListener listener) {
mGestureDetector = new GestureDetector(mContext, listener);
}
/**
* Add a message and its view to the end of the list of messages.
*
* @param newMessage
* The message to add.
*/
public synchronized void addMessage(SmsMmsMessage newMessage) {
messages.add(newMessage);
UpdateMessageCount();
}
/**
* Add a list of new messages to the end of the current message list.
*
* @param newMessages
* The list of new messages to add.
*/
public synchronized void addMessages(ArrayList<SmsMmsMessage> newMessages) {
if (newMessages != null) {
messages.addAll(0, newMessages);
UpdateMessageCount();
}
}
/**
* Remove a specific message from the list, if there is only one message left then it will not
* be removed.
*
* @param numMessage
* @return One of STATUS_MESSAGES_REMAINING, STATUS_NO_MESSAGES_REMAINING or
* STATUS_REMOVING_MESSAGE
*/
public synchronized int removeMessage(final int numMessage) {
if (removingMessage) {
return STATUS_REMOVING_MESSAGE;
}
final int totalMessages = getPageCount();
if (totalMessages <= 1) {
return STATUS_NO_MESSAGES_REMAINING;
}
if (numMessage >= totalMessages || numMessage < 0) {
return STATUS_NO_MESSAGES_REMAINING;
}
Animation mAnimation = AnimationUtils.loadAnimation(mContext, R.anim.shrink_fade_out_center);
mAnimation.setAnimationListener(new AnimationListener() {
@Override
public void onAnimationStart(Animation animation) {
removingMessage = true;
}
@Override
public void onAnimationEnd(Animation animation) {
if (numMessage < currentPage && currentPage != (totalMessages - 1)) {
currentPage--;
}
messages.remove(numMessage);
getAdapter().notifyDataSetChanged();
UpdateMessageCount();
removingMessage = false;
}
@Override
public void onAnimationRepeat(Animation animation) {}
});
startAnimation(mAnimation);
return STATUS_MESSAGES_REMAINING;
}
/**
* Remove the currently active message, if there is only one message left then it will not be
* removed.
*
* @return One of STATUS_MESSAGES_REMAINING, STATUS_NO_MESSAGES_REMAINING or
* STATUS_REMOVING_MESSAGE
*/
public int removeActiveMessage() {
return removeMessage(currentPage);
}
/**
* Return the currently active message.
*
* @return The currently visible message.
*/
public synchronized SmsMmsMessage getActiveMessage() {
return messages.get(currentPage);
}
public synchronized int getActiveMessageNum() {
return currentPage;
}
public void setOnMessageCountChanged(MessageCountChanged m) {
messageCountChanged = m;
}
public static interface MessageCountChanged {
abstract void onChange(int current, int total);
}
private void UpdateMessageCount() {
if (mPagerIndicator != null) {
mPagerIndicator.invalidate();
}
if (messageCountChanged != null) {
messageCountChanged.onChange(currentPage, getPageCount());
}
}
public void showNext() {
if (currentPage < (getPageCount() - 1)) {
setCurrentItem(currentPage + 1);
}
if (BuildConfig.DEBUG)
Log.v("showNext() - " + currentPage + ", " + getActiveMessage().getContactName());
}
public void showPrevious() {
if (currentPage > 0) {
setCurrentItem(currentPage - 1);
}
if (BuildConfig.DEBUG)
Log.v("showPrevious() - " + currentPage + ", " + getActiveMessage().getContactName());
}
@Override
public void setCurrentItem(int num) {
super.setCurrentItem(num);
currentPage = num;
}
public void showLast() {
setCurrentItem(getPageCount() - 1);
}
@Override
public void onPageScrollStateChanged(int state) {}
@Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
super.onPageScrolled(position, positionOffset, positionOffsetPixels);
}
@Override
public void onPageSelected(int position) {
currentPage = position;
}
public void setIndicator(CirclePageIndicator pagerIndicator) {
if (pagerIndicator != null) {
mPagerIndicator = pagerIndicator;
mPagerIndicator.setOnPageChangeListener(this);
}
}
/**
* Check if the set of messages associated with this pager should send a notification.
*
* @return The message number that requires a notification or -1 if no notificaiton is needed.
*/
public SmsMmsMessage shouldNotify() {
SmsMmsMessage message;
for (int i = 0; i < messages.size(); i++) {
message = messages.get(i);
if (message.shouldNotify()) {
return message;
}
}
return null;
}
public ArrayList<SmsMmsMessage> getMessages() {
return messages;
}
public SmsMmsMessage getMessage(int i) {
return messages.get(i);
}
@Override
public boolean onInterceptTouchEvent(MotionEvent event) {
mGestureDetector.onTouchEvent(event);
return super.onInterceptTouchEvent(event);
}
@Override
public boolean onTouchEvent(MotionEvent event) {
mGestureDetector.onTouchEvent(event);
return super.onTouchEvent(event);
}
}