/*
 *  Copyright (C) 2014 The AppCan Open Source Project.
 *
 *  This program is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU Lesser General Public License as published by
 *  the Free Software Foundation, either version 3 of the License, or
 *  (at your option) any later version.

 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU Lesser General Public License for more details.

 *  You should have received a copy of the GNU Lesser General Public License
 *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
 *
 */

package org.zywx.wbpalmstar.platform.myspace;

import org.zywx.wbpalmstar.base.ResoureFinder;
import org.zywx.wbpalmstar.engine.ESystemInfo;
import org.zywx.wbpalmstar.platform.myspace.GSenseView.OnBallFallIntoCallback;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.PixelFormat;
import android.graphics.drawable.Drawable;
import android.hardware.Sensor;
import android.hardware.SensorEvent;
import android.hardware.SensorEventListener;
import android.hardware.SensorManager;
import android.util.AttributeSet;
import android.util.DisplayMetrics;
import android.view.Gravity;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewConfiguration;
import android.view.WindowManager;

public class DragableView extends View implements SensorEventListener {
	public static final String TAG = "DragableView";
	private DisplayMetrics dm;
	private WindowManager windowManager;
	private WindowManager.LayoutParams params;
	private ResoureFinder finder;
	float currentX;
	float currentY;
	private SensorManager sensorManager;
	private Sensor sensor;
	private GSenseView gSenseView;
	private OnGSBallFallListener listener;
	private boolean isAddedSenseView = false;
	private int cpuMHZ;

	public DragableView(WindowManager windowManager, Context context) {
		super(context);
		this.windowManager = windowManager;
		init();
	}

	public DragableView(Context context, AttributeSet attrs) {
		super(context, attrs);
		init();
	}

	public void setGSBallFallListener(OnGSBallFallListener fallListener) {
		listener = fallListener;
	}

	public WindowManager.LayoutParams getLayoutParams() {
		return params;
	}

	private void init() {
		finder = ResoureFinder.getInstance(getContext());
		cpuMHZ = ESystemInfo.getIntence().cpuMHZ;
		sensorManager = (SensorManager) getContext().getSystemService(Context.SENSOR_SERVICE);
		sensor = sensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);
		gSenseView = new GSenseView(getContext());
		params = new WindowManager.LayoutParams();
		params.type = WindowManager.LayoutParams.TYPE_APPLICATION;
		params.flags = WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL | WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE;
		dm = getContext().getResources().getDisplayMetrics();
		Drawable drawable = finder.getDrawable("browser_right_hover");
		setBackgroundDrawable(drawable);
		params.height = drawable.getIntrinsicHeight();
		params.width = drawable.getIntrinsicWidth();
		params.alpha = 1.0f;
		params.format = PixelFormat.TRANSPARENT;
		params.gravity = Gravity.LEFT | Gravity.TOP;
		params.x = (int) (dm.widthPixels - 5 * dm.density - params.width);
		params.y = (int) (dm.heightPixels - 50 * dm.density - params.height);
		params.windowAnimations = finder.getStyleId("Anim_platform_myspace_fade");
	}

	float startX;
	float startY;
	boolean dragable = false;

	@Override
	protected void onWindowVisibilityChanged(int visibility) {
		super.onWindowVisibilityChanged(visibility);
		if (cpuMHZ > 800) {
			if (visibility == View.VISIBLE) {
				// sensorManager.registerListener(this, sensor,
				// SensorManager.SENSOR_DELAY_UI);
				setClickable(true);
			} else {
				// sensorManager.unregisterListener(this, sensor);
			}
		}
	}

	@Override
	protected void onDetachedFromWindow() {
		super.onDetachedFromWindow();
		if (gSenseView != null && isAddedSenseView) {
			windowManager.removeViewImmediate(gSenseView);
		}
	}

	@Override
	protected void onDraw(Canvas canvas) {
		super.onDraw(canvas);
	}

	@Override
	public boolean onTouchEvent(MotionEvent event) {
		// 触摸点相对于屏幕左上角坐标
		boolean isHandle = false;
		currentX = event.getRawX();
		currentY = event.getRawY();
		switch (event.getAction()) {
		case MotionEvent.ACTION_DOWN:
			startX = event.getX();
			startY = event.getY();
			break;
		case MotionEvent.ACTION_MOVE:
			if (!dragable) {
				final int touchSlop = ViewConfiguration.get(getContext()).getScaledTouchSlop();
				if (Math.abs(event.getX() - startX) > touchSlop || Math.abs(event.getY() - startY) > touchSlop) {
					dragable = true;
					updatePosition();
					isHandle = true;
				}
			}
			if (dragable) {
				updatePosition();
				isHandle = true;
			}
			break;
		case MotionEvent.ACTION_UP:
			if (dragable) {
				updatePosition();
				isHandle = true;
			}
			dragable = false;
			startX = startY = 0;
			break;
		}
		return isHandle ? isHandle : super.onTouchEvent(event);
	}

	// 更新浮动窗口位置参数
	private void updatePosition() {
		// View的当前位置
		params.x = (int) (currentX - startX);
		params.y = (int) (currentY - startY);
		windowManager.updateViewLayout(this, params);
	}

	private float x, y, z, last_x, last_y, last_z;
	private long lastUpdate;
	private static final int SHAKE_THRESHOLD = 2000;

	@Override
	public void onSensorChanged(SensorEvent event) {
		long curTime = System.currentTimeMillis();
		// 每100毫秒检测一次
		if ((curTime - lastUpdate) > 100) {
			long diffTime = (curTime - lastUpdate);
			lastUpdate = curTime;
			x = event.values[SensorManager.DATA_X];
			y = event.values[SensorManager.DATA_Y];
			z = event.values[SensorManager.DATA_Z];
			float speed = Math.abs(x + y + z - last_x - last_y - last_z) / diffTime * 10000;
			if (speed > SHAKE_THRESHOLD) {
				// 检测到摇晃后执行的代码
				setVisibility(View.GONE);
				setClickable(false);
				sensorManager.unregisterListener(this, sensor);
				if (!isAddedSenseView) {
					windowManager.addView(gSenseView, gSenseView.getLayoutParams());
					isAddedSenseView = true;
					gSenseView.startSense();
					gSenseView.addBallFallIntoCallback(new OnBallFallIntoCallback() {
						@Override
						public void onFallInto() {
							windowManager.removeViewImmediate(gSenseView);
							isAddedSenseView = false;
							if (listener != null) {
								listener.onGSBallFalled();
							}
						}
					});

				}

			}
			last_x = x;
			last_y = y;
			last_z = z;
		}
	}

	@Override
	public void onAccuracyChanged(Sensor sensor, int accuracy) {

	}

	public static interface OnGSBallFallListener {
		void onGSBallFalled();
	}
}
