package org.snake.video;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Matrix;
import android.graphics.Paint;
import android.graphics.PaintFlagsDrawFilter;
import android.graphics.Rect;
import android.util.AttributeSet;
import android.util.Log;
import android.view.GestureDetector;
import android.view.MotionEvent;
import android.view.View;
import android.view.GestureDetector.OnGestureListener;
import android.widget.FrameLayout;
import android.widget.ImageView;
public class SnakeLayout extends FrameLayout {
private static final String LOG_TAG = "SnakeLayout";
private GestureDetector mGestureDetector;
/**
* 手势识别类
*/
private SnakeOnGestureListener mGestureListener;
/**
* 子视图集合
*/
private List<View> ViewHolder;
/**
* 表示选中的视图索引号
*/
private int selectImg;
/**
* 总子视图数
*/
private int totalViewNum;
private View mContentView;
private SnakeView ScrollView;
private Context mContext;
/**
* 状态枚举 READY:准备状态, ABOUT_TO_ANIMATE:启动动画状态, TRACKING:急停状态, ANIMATING:运行状态,
* ANIMATE_END:结束状态
*/
private enum State {
ABOUT_TO_ANIMATE, ANIMATING, ANIMATE_END, READY, TRACKING
};
/**
* 运行状态
*/
private State mState;
/**
* 开始启动的子视图索引
*/
private double aniStartPos;// Value = scrollNum + percent*direction;
/**
* 结束启动的子视图索引
*/
private double aniStopPos;// Value = scrollNum + percent*direction;
/**
* 开始启动的时间
*/
private Date aniStartTime;
/**
* 动画运行毫秒数
*/
private long aniTime = 1000;
/**
* 动画间隙时间
*/
private double aniSpeed = 500;
/**
* 暂时不知道
*/
private double aniDefG = 5;
/**
* 视图宽度
*/
private int mContentWidth = 0;
/**
* 视图高度
*/
private int mContentHeight = 0;
/**
* 点击的子视图索引号
*/
private int clickItem = -1;
/**
* 左移、右移标志
*/
private int direction = 0;
private int movDirection = 0;
private double percent = 0;
private int scrollNum = 0;
private PathScale myPathViews;
private List<Bitmap> BmpRecViews;
private OnSelectListener selectListener;
private OnClickListener clickListener;
private int currentIndex = 0;
/**
* 相片处理类
*/
Matrix mMatrix = new Matrix();
/**
* 轨迹圆信息
*/
private float[] arcInfo0 = new float[] { 229.12245f, 1105.1938f, 1105.2046f };
private float[] arcInfo1 = new float[] { 92.7498f, -3004.5198f, 3041.0974f };
private float[] arcInfo2 = new float[] { 420.3208f, -696.6356f, 960.4874f };
private float[] arcInfo3 = new float[] { 843.7643f, -1649.7491f, 1916.4272f };
private float[] arcInfo4 = new float[] { 710.5019f, -3083.5166f, 3120.117f };
private float[] arcInfo5 = new float[] { 570.63947f, 1106.748f, 1106.7744f };
private float[] arcInfo6 = new float[] { 384.15384f, -685.53845f,
948.55145f };
private float[] arcInfo7 = new float[] { -40.744934f, -1641.029f,
1907.2142f };
public SnakeLayout(Context context, AttributeSet attrs) {
super(context, attrs);
Log.d(LOG_TAG, "Init SnakeLayout");
mContext = context;
TypedArray a = context.obtainStyledAttributes(attrs,
R.styleable.SnakeLayout);
selectImg = a.getInteger(R.styleable.SnakeLayout_selectImg, -1);
a.recycle();
mGestureListener = new SnakeOnGestureListener();
mGestureDetector = new GestureDetector(mGestureListener);
mGestureDetector.setIsLongpressEnabled(false);
BmpRecViews = new ArrayList<Bitmap>();
myPathViews = new PathScale();
mState = State.READY;
}
public void Init() {
Log.d(LOG_TAG, "SnakeLayout.Init()");
for (int i = 0; i < totalViewNum; i++) {
ImageView v = (ImageView) ViewHolder.get(i);
v.setScaleType(ImageView.ScaleType.FIT_XY);
v.setImageBitmap(BmpRecViews.get((i + currentIndex)
% BmpRecViews.size()));
}
}
public void addBitmap(Bitmap b) {
if (b != null)
BmpRecViews.add(b);
}
public void addBitmap(Bitmap b, int position) {
if (b != null)
BmpRecViews.add(position, b);
}
public void addRec(int rec) {
Bitmap b = BitmapFactory.decodeResource(this
.getResources(), rec);
if (b != null)
BmpRecViews.add(b);
}
public void addRec(int rec, int position) {
Bitmap b = BitmapFactory.decodeResource(this.getResources(), rec);
if (b != null)
BmpRecViews.add(position, b);
}
private class PathScale {
private int totalNum;
List<Double> myLen;
List<Rect> myRect;
int recentScrollNum = 0;
double RecentPercent = 0;
public PathScale() {
totalNum = 0;
myLen = new ArrayList<Double>();
myRect = new ArrayList<Rect>();
}
public double getAverageLen() {
double len = 0;
if (totalNum < 2)
return len;
for (int i = 0; i < totalNum - 2; i++) {
len += myLen.get(i);
}
return len / (totalNum - 1);
}
public int size() {
return totalNum;
}
public void addPointView(int left, int top, int right, int bottom) {
totalNum++;
Log.d(LOG_TAG, "SnakeLayout.PathScale.addPointView()total num : "
+ totalNum);
Rect r = new Rect(left, top, right, bottom);
myRect.add(r);
if (totalNum > 1) {
Rect r0 = myRect.get(totalNum - 2);
int dx = r0.centerX() - r.centerX();
int dy = r0.centerY() - r.centerY();
double len = Math.sqrt(dx * dx + dy * dy);
myLen.add(len);
}
}
public int getRecentScrollNum() {
return recentScrollNum;
}
public double getPercent() {
return RecentPercent;
}
public void computeScroll(int clickNum, int dir, double len) {
double remain = len;
recentScrollNum = 0;
RecentPercent = 0;
if (dir == 1) {
for (int i = clickNum;; i++) {
if (i > totalNum - 2)
i = totalNum - 2;
if (i < 0)
i = 0;
double tmp = myLen.get(i);
if (remain >= tmp) {
recentScrollNum++;
remain -= tmp;
} else {
RecentPercent = remain / tmp;
break;
}
}
} else if (dir == -1) {
for (int i = clickNum;; i--) {
if (i - 1 > totalNum - 2)
i = totalNum - 1;
if (i - 1 < 0)
i = 1;
double tmp = myLen.get(i - 1);
if (remain >= tmp) {
recentScrollNum--;
remain -= tmp;
} else {
RecentPercent = remain / tmp;
break;
}
}
}
}
public Rect getMoveRect(int selectNum) {
if (direction == 1) {
int newIndex = selectNum + scrollNum;
if (newIndex >= totalNum - 1) {
Rect r0 = myRect.get(totalNum - 1);
Rect r1 = myRect.get(totalNum - 2);
int nx = (int) (r0.centerX() - (r1.centerX() - r0.centerX())
* percent);
int ny = (int) (r0.centerY() - (r1.centerY() - r0.centerY())
* percent);
int nw = (int) (r0.width() - (r1.width() - r0.width())
* percent);
int nh = (int) (r0.height() - (r1.height() - r0.height())
* percent);
return new Rect(nx - nw / 2, ny - nh / 2, nx + nw / 2, ny
+ nh / 2);
} else if (newIndex == -1) {
Rect r0 = myRect.get(0);
Rect r1 = myRect.get(1);
int nx = (int) (r0.centerX() - (r1.centerX() - r0.centerX())
* (1 - percent));
int ny = (int) (r0.centerY() - (r1.centerY() - r0.centerY())
* (1 - percent));
int nw = (int) (r0.width() - (r1.width() - r0.width())
* (1 - percent));
int nh = (int) (r0.height() - (r1.height() - r0.height())
* (1 - percent));
return new Rect(nx - nw / 2, ny - nh / 2, nx + nw / 2, ny
+ nh / 2);
} else if (newIndex > totalNum - 1 || newIndex < -1) {
return null;
} else {
Rect r0 = myRect.get(newIndex);
Rect