package com.hellodev.lightme.view;
import android.content.Context;
import android.graphics.PixelFormat;
import android.os.CountDownTimer;
import android.os.Vibrator;
import android.util.Log;
import android.view.GestureDetector;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.View;
import android.view.WindowManager;
import android.view.GestureDetector.OnGestureListener;
import android.view.WindowManager.LayoutParams;
import android.widget.TextView;
import com.hellodev.lightme.FlashApp;
import com.hellodev.lightme.FlashController;
import com.hellodev.lightme.FlashController.OnFlashLevelChangedListener;
import com.hellodev.lightme.R;
import com.hellodev.lightme.util.MDisplayHelper;
import com.hellodev.lightme.util.MathHelper;
import java.lang.reflect.Field;
public abstract class BasePanelManager implements OnFlashLevelChangedListener{
private final static String TAG = "BasePanelManager";
protected int SCREEN_WIDTH, SCREEN_HEIGHT, STATUS_BAR_HEIGHT;
protected int CLEAR_PANEL_VIEW_HEIGHT;
protected int PANEL_VIEW_WIDTH;
protected int PANEL_VIEW_HEIGHT;
protected int PANEL_PRESSED_INCREMENT;
protected int LEVEL_DISTANCE = 20;
protected Context mContext;
protected WindowManager wm;
protected WindowManager.LayoutParams mPanelParams, mClearPanelParams;
protected View mPanelView;
protected TextView mClearPanelView;
protected Vibrator mVibrator;
protected MDisplayHelper mDisplayHelper;
protected boolean isPanelShown = false;
protected boolean isClearPanelShown = false;
protected boolean isClearPanelFocused = false;
protected int mCurrentLevel = FlashController.LEVEL_OFF;
protected float mInitialX, mInitialY;
protected float mDownX, mDownY;
protected boolean mIsLongPressing;
protected GestureDetector mPanelGestureDetector;
protected FlashController flashController;
protected GuideViewManager guideViewMgr;
protected BasePanelManager() {
mContext = FlashApp.getContext();
mVibrator = (Vibrator) mContext
.getSystemService(Context.VIBRATOR_SERVICE);
wm = (WindowManager) mContext.getSystemService(Context.WINDOW_SERVICE);
mDisplayHelper = new MDisplayHelper();
PANEL_PRESSED_INCREMENT = mDisplayHelper.dpiToPx(6);
CLEAR_PANEL_VIEW_HEIGHT = mDisplayHelper.dpiToPx(32);
STATUS_BAR_HEIGHT = getStatusBarHeight();
SCREEN_WIDTH = wm.getDefaultDisplay().getWidth();
SCREEN_HEIGHT = wm.getDefaultDisplay().getHeight() - STATUS_BAR_HEIGHT;
mPanelParams = new WindowManager.LayoutParams();
mPanelParams.type = WindowManager.LayoutParams.TYPE_PHONE;
mPanelParams.format = PixelFormat.RGBA_8888;
mPanelParams.flags = LayoutParams.FLAG_NOT_TOUCH_MODAL
| LayoutParams.FLAG_NOT_FOCUSABLE;
mPanelParams.gravity = getPanelLayoutGravity();
mPanelParams.windowAnimations = R.style.panel_anim;
mClearPanelView = (TextView) LayoutInflater.from(mContext).inflate(
R.layout.layout_clear_panel, null);
mClearPanelParams = new WindowManager.LayoutParams();
mClearPanelParams.type = WindowManager.LayoutParams.TYPE_PHONE;
mClearPanelParams.format = PixelFormat.RGBA_8888;
mClearPanelParams.flags = LayoutParams.FLAG_NOT_TOUCH_MODAL
| LayoutParams.FLAG_NOT_FOCUSABLE;
mClearPanelParams.height = CLEAR_PANEL_VIEW_HEIGHT;
mClearPanelParams.x = 0;
mClearPanelParams.y = SCREEN_HEIGHT;
mClearPanelParams.windowAnimations = R.style.clear_panel_anim;
mPanelGestureDetector = new GestureDetector(mContext,
mPanelGestureListener);
flashController = FlashController.getInstance();
}
@Override
public void onFlashLevelChanged(int currentLevel) {
setFlashLevel(currentLevel);
}
public boolean isPanelShown() {
// 只是用来标记Panel是否隐藏了
return isPanelShown;
}
protected void toggleClearPanelFocusChanged(float panelBottom) {
float clearPanelTop = SCREEN_HEIGHT - CLEAR_PANEL_VIEW_HEIGHT;
if (isClearPanelFocused && panelBottom < clearPanelTop) {
mClearPanelView.setBackgroundResource(R.color.clear_panel_normal);
isClearPanelFocused = false;
} else if (!isClearPanelFocused && panelBottom >= clearPanelTop) {
mClearPanelView.setBackgroundResource(R.color.clear_panel_focus);
isClearPanelFocused = true;
}
}
protected void showClearPanel() {
if (!isClearPanelShown) {
wm.addView(mClearPanelView, mClearPanelParams);
isClearPanelShown = true;
}
}
protected void closeClearPanel() {
if (isClearPanelShown) {
wm.removeView(mClearPanelView);
isClearPanelShown = false;
isClearPanelFocused = false;
}
}
protected void onLongPressStateBegin() {
mVibrator.vibrate(100);
mPanelParams.width = PANEL_VIEW_WIDTH + PANEL_PRESSED_INCREMENT;
mPanelParams.height = PANEL_VIEW_HEIGHT + PANEL_PRESSED_INCREMENT;
updatePanel();
showClearPanel();
}
protected void onLongPressStateEnd() {
mPanelParams.width = PANEL_VIEW_WIDTH;
mPanelParams.height = PANEL_VIEW_HEIGHT;
updatePanel();
mIsLongPressing = false;
closeClearPanel();
}
/**
*
* 与其他的move方法互斥
*
*/
protected void smoothMoveToLeft() {
final int currentX = mPanelParams.x;
new CountDownTimer(500, 5) {
@Override
public void onTick(long millisUntilFinished) {
long step = (500 - millisUntilFinished) / 5;
updatePanel((int) MathHelper.bounceValue(step, currentX),
mPanelParams.y);
}
@Override
public void onFinish() {
updatePanel(0, mPanelParams.y);
}
}.start();
}
/**
*
* 与其他的move方法互斥
*
*/
protected void smoothMoveToRight() {
final int endX = SCREEN_WIDTH - PANEL_VIEW_WIDTH;
final int distanceX = endX - mPanelParams.x;
new CountDownTimer(500, 5) {
@Override
public void onTick(long millisUntilFinished) {
long step = (500 - millisUntilFinished) / 5;
updatePanel(
endX - (int) MathHelper.bounceValue(step, distanceX),
mPanelParams.y);
}
@Override
public void onFinish() {
updatePanel(SCREEN_WIDTH - PANEL_VIEW_WIDTH,
mPanelParams.y);
}
}.start();
}
/**
*
* 与其他的move方法互斥
*
*/
protected void smoothMoveTo(final int dstX, final int dstY) {
final int currentX = mPanelParams.x;
final int currentY = mPanelParams.y;
final int distanceX = (int) Math.abs(currentX - dstX);
final int distanceY = (int) Math.abs(currentY - dstY);
new CountDownTimer(500, 5) {
@Override
public void onTick(long millisUntilFinished) {
long step = (500 - millisUntilFinished) / 5;
int x = 0;
int y = 0;
if (currentX >= dstX) {
x = dstX + (int) MathHelper.bounceValue(step, distanceX);
} else {
x = dstX - (int) MathHelper.bounceValue(step, distanceX);
}
if (currentY >= dstY) {
y = dstY + (int) MathHelper.bounceValue(step, distanceY);
} else {
y = dstY - (int) MathHelper.bounceValue(step, distanceY);
}
updatePanel(x, y);
}
@Override
public void onFinish() {
updatePanel(dstX, dstY);
}
}.start();
}
/**
*
* 与其他的move方法互斥
*
*/
protected void moveTo(float dstX, float dstY) {
updatePanel((int) dstX, (int) dstY);
}
protected void changeFlashLightWithMove(float startY, float endY) {
float distanceY = endY - startY;
if (distanceY > LEVEL_DISTANCE) {
flashController.turnFlashDown();
} else if (distanceY < -LEVEL_DISTANCE) {
flashController.turnFlashUp();
}
}
// 这个是需要的,但是其他的关联操作呢,主要是smoothMove的线程和其他的线程的矛盾
protected synchronized void updatePanel() {
if (isPanelShown)
wm.updateViewLayout(mPanelView, mPanelParams);
}
protected synchronized void updatePanel(int x, int y) {
mPanelParams.x = x;
mPanelParams.y = y;
if (isPanelShown)
wm.updateViewLayout(mPanelView, mPanelParams);
}
protected synchronized void addPanel(int x, int y) {
mPanelParams.x = x;
mPanelParams.y = y;
wm.addView(mPanelView, mPanelParams);
isPanelShown = true;
}
protected synchronized void removeWindow() {
wm.removeView(mPanelView);
isPanelShown = false;
}
/*
* 在对应service关闭的时候,有没有更高效的方式不用这么逐层传递
*/
public void closePanel() {
hidePanel();
onDestroy();
}
protected void onDestroy() {
flashController = null;
}
private OnGestureListener mPanelGestureListener = new OnGestureListener() {
@Override
public boolean onDown(MotionEvent e) {
return true;
}
@Override
public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX,
float velocityY) {
return false;
}
@Override
public void onLongPress(MotionEvent e) {
mIsLongPressing = true;
onLongPressStateBegin();
}
@Override
public boolean onScroll(MotionEvent e1, MotionEvent e2,
float distanceX, float distanceY) {
return false;
}
@Override
public void onShowPress(MotionEvent e) {
}
@Override
public boolean onSingleTapUp(MotionEvent e) {
setFlashLevel(flashController.toggleFlash());
//关闭引导页
// closeGuideView();
return true;
}
};
protected void closeGuideView() {
if(guideViewMgr != null) {
guideViewMgr.close();
guideViewMgr = null;
}
}
private int getStatusBarHeight() {
int statusBarHeight = 0;
try {
Class<?> c = Class.forName("com.android.internal.R$dimen");
Object o = c.newInstance();
Field field = c.getField("status_bar_height");
int x = (Integer) field.get(o);
statusBarHeight = mContext.getResources().getDimensionPixelSize(x);
} catch (Exception e) {
e.printStackTrace();
}
return statusBarHeight;
}
protected abstract int getPanelWidth();
protected abstract int getPanelHeight();
protected abstract int getPanelLayoutGravity();
protected abstract void showPanel();
protected abstract void hidePanel();
protected abstract void setFlashLevel(int currentLevel);
}