package com.fima.cardsui.objects;
import java.util.ArrayList;
import android.content.Context;
import android.text.TextUtils;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.RelativeLayout;
import android.widget.TextView;
import com.actionbarsherlock.R;
import com.fima.cardsui.StackAdapter;
import com.fima.cardsui.SwipeDismissTouchListener;
import com.fima.cardsui.SwipeDismissTouchListener.OnDismissCallback;
import com.fima.cardsui.Utils;
import com.nineoldandroids.animation.Animator;
import com.nineoldandroids.animation.Animator.AnimatorListener;
import com.nineoldandroids.animation.ObjectAnimator;
public class CardStack extends AbstractCard {
private static final float _12F = 12f;
private static final float _45F = 45f;
private static final String NINE_OLD_TRANSLATION_Y = "translationY";
private ArrayList<Card> cards;
private String title;
private StackAdapter mAdapter;
private int mPosition;
private Context mContext;
private CardStack mStack;
public CardStack() {
cards = new ArrayList<Card>();
mStack = this;
}
public ArrayList<Card> getCards() {
return cards;
}
public void add(Card newCard) {
cards.add(newCard);
}
@Override
public View getView(Context context) {
return getView(context, false);
}
@Override
public View getView(Context context, boolean swipable) {
mContext = context;
final View view = LayoutInflater.from(context).inflate(
R.layout.cui_item_stack, null);
final RelativeLayout container = (RelativeLayout) view
.findViewById(R.id.stackContainer);
final TextView title = (TextView) view.findViewById(R.id.stackTitle);
if (!TextUtils.isEmpty(this.title)) {
title.setText(this.title);
title.setVisibility(View.VISIBLE);
}
final int cardsArraySize = cards.size();
final int lastCardPosition = cardsArraySize - 1;
Card card;
View cardView;
for (int i = 0; i < cardsArraySize; i++) {
card = cards.get(i);
cardView = null;
RelativeLayout.LayoutParams lp = new RelativeLayout.LayoutParams(
RelativeLayout.LayoutParams.MATCH_PARENT,
RelativeLayout.LayoutParams.WRAP_CONTENT);
int topPx = 0;
if (lastCardPosition == i) {
// last card
cardView = card.getViewLast(context);
cardView.setOnClickListener(card.getClickListener());
} else {
if (0 == i) {
// first card
cardView = card.getViewFirst(context);
} else {
// any other card
cardView = card.getView(context);
}
cardView.setOnClickListener(getClickListener(this, container, i));
}
if (i > 0) {
float dp = (_45F * i) - _12F;
topPx = Utils.convertDpToPixelInt(context, dp);
}
lp.setMargins(0, topPx, 0, 0);
cardView.setLayoutParams(lp);
if (swipable){
cardView.setOnTouchListener(new SwipeDismissTouchListener(
cardView, card, new OnDismissCallback() {
@Override
public void onDismiss(View view, Object token) {
Card c = (Card) token;
// call onCardSwiped() listener
c.OnSwipeCard();
cards.remove(c);
mAdapter.setItems(mStack, getPosition());
// refresh();
mAdapter.notifyDataSetChanged();
}
}));
}
container.addView(cardView);
}
return view;
}
public Card remove(int index) {
return cards.remove(index);
}
public Card get(int i) {
return cards.get(i);
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
private OnClickListener getClickListener(final CardStack cardStack,
final RelativeLayout container, final int index) {
return new OnClickListener() {
@Override
public void onClick(View v) {
// init views array
View[] views = new View[container.getChildCount()];
for (int i = 0; i < views.length; i++) {
views[i] = container.getChildAt(i);
}
int last = views.length - 1;
if (index != last) {
if (index == 0) {
onClickFirstCard(cardStack, container, index, views);
} else if (index < last) {
onClickOtherCard(cardStack, container, index, views,
last);
}
}
}
public void onClickFirstCard(final CardStack cardStack,
final RelativeLayout frameLayout, final int index, View[] views) {
// run through all the cards
for (int i = 0; i < views.length; i++) {
ObjectAnimator anim = null;
if (i == 0) {
// the first goes all the way down
float downFactor = 0;
if (views.length > 2) {
downFactor = convertDpToPixel((_45F)
* (views.length - 1) - 1);
} else {
downFactor = convertDpToPixel(_45F);
}
anim = ObjectAnimator.ofFloat(views[i],
NINE_OLD_TRANSLATION_Y, 0, downFactor);
anim.addListener(getAnimationListener(cardStack,
frameLayout, index, views[index]));
} else if (i == 1) {
// the second goes up just a bit
float upFactor = convertDpToPixel(-17f);
anim = ObjectAnimator.ofFloat(views[i],
NINE_OLD_TRANSLATION_Y, 0, upFactor);
} else {
// the rest go up by one card
float upFactor = convertDpToPixel(-1 * _45F);
anim = ObjectAnimator.ofFloat(views[i],
NINE_OLD_TRANSLATION_Y, 0, upFactor);
}
if (anim != null)
anim.start();
}
}
public void onClickOtherCard(final CardStack cardStack,
final RelativeLayout frameLayout, final int index,
View[] views, int last) {
// if clicked card is in middle
for (int i = index; i <= last; i++) {
// run through the cards from the clicked position
// and on until the end
ObjectAnimator anim = null;
if (i == index) {
// the selected card goes all the way down
float downFactor = convertDpToPixel(_45F * (last - i)
+ _12F);
anim = ObjectAnimator.ofFloat(views[i],
NINE_OLD_TRANSLATION_Y, 0, downFactor);
anim.addListener(getAnimationListener(cardStack,
frameLayout, index, views[index]));
} else {
// the rest go up by one
float upFactor = convertDpToPixel(_45F * -1);
anim = ObjectAnimator.ofFloat(views[i],
NINE_OLD_TRANSLATION_Y, 0, upFactor);
}
if (anim != null)
anim.start();
}
}
};
}
protected float convertDpToPixel(float dp) {
return Utils.convertDpToPixel(mContext, dp);
}
private AnimatorListener getAnimationListener(final CardStack cardStack,
final RelativeLayout frameLayout, final int index,
final View clickedCard) {
return new AnimatorListener() {
@Override
public void onAnimationStart(Animator animation) {
if (index == 0) {
View newFirstCard = frameLayout.getChildAt(1);
handleFirstCard(newFirstCard);
// clickedCard.setBackgroundResource(com.fima.cardsui.R.drawable.);
// newFirstCard.setBackgroundResource(com.fima.cardsui.R.drawable.card_background);
// FrameLayout.LayoutParams lp = new
// FrameLayout.LayoutParams(FrameLayout.LayoutParams.MATCH_PARENT,
// FrameLayout.LayoutParams.WRAP_CONTENT);
//
// if (index > 0) {
// top = convertDpToPixelInt(8) + (convertDpToPixelInt(36f)
// * index);
// bottom = 24;
//
// }
//
// else if (0 == index) {
// top = 2 * convertDpToPixelInt(8) +
// convertDpToPixelInt(1);
// bottom = convertDpToPixelInt(12);
// }
//
// lp.setMargins(0, top, 0, bottom);
//
// clickedCard.setLayoutParams(lp);
// clickedCard.setPadding(0, convertDpToPixelInt(20), 0, 0);
} else {
clickedCard
.setBackgroundResource(R.drawable.cui_card_background);
}
frameLayout.removeView(clickedCard);
frameLayout.addView(clickedCard);
}
private void handleFirstCard(View newFirstCard) {
newFirstCard
.setBackgroundResource(R.drawable.cui_card_background);
RelativeLayout.LayoutParams lp = new RelativeLayout.LayoutParams(
RelativeLayout.LayoutParams.MATCH_PARENT,
RelativeLayout.LayoutParams.WRAP_CONTENT);
int top = 0;
int bottom = 0;
top = 2 * Utils.convertDpToPixelInt(mContext, 8)
+ Utils.convertDpToPixelInt(mContext, 1);
bottom = Utils.convertDpToPixelInt(mContext, 12);
lp.setMargins(0, top, 0, bottom);
newFirstCard.setLayoutParams(lp);
newFirstCard.setPadding(0,
Utils.convertDpToPixelInt(mContext, 8), 0, 0);
}
@Override
public void onAnimationRepeat(Animator animation) {
// TODO Auto-generated method stub
}
@Override
public void onAnimationEnd(Animator animation) {
Card card = cardStack.remove(index);
cardStack.add(card);
mAdapter.setItems(cardStack, cardStack.getPosition());
// refresh();
mAdapter.notifyDataSetChanged();
Log.v("CardsUI", "Notify Adapter");
}
@Override
public void onAnimationCancel(Animator animation) {
// TODO Auto-generated method stub
}
};
}
public void setAdapter(StackAdapter stackAdapter) {
mAdapter = stackAdapter;
}
public void setPosition(int position) {
mPosition = position;
}
public int getPosition() {
return mPosition;
}
}