/*
* Author: Miguel Angel Bravo (@MiguelAngelBrav)
* The Android Open Source Project Katbag is licensed under the General GPLv3.
*
*/
package cl.ipp.katbag.core;
import java.util.Random;
import android.content.Context;
import android.graphics.Rect;
import android.hardware.Sensor;
import android.hardware.SensorEvent;
import android.hardware.SensorEventListener;
import android.hardware.SensorManager;
import android.util.Log;
import android.view.MotionEvent;
import android.view.View;
import android.view.View.OnTouchListener;
import android.widget.ImageView;
import android.widget.RelativeLayout;
import cl.ipp.katbag.MainActivity;
public class KatbagDrawing extends ImageView implements OnTouchListener, SensorEventListener {
public ImageView v = null;
private int myWidth = 0, myHeight = 0, myMiddleWidth = 0, myMiddleHeight = 0;
private int leftIni = 0, topIni = 0, leftMax = 0, topMax = 0, leftMin = 0, topMin = 0, leftColl = 0, topColl = 0;
private int[] loc;
private boolean moveOnlyAxisX = false;
private boolean moveOnlyAxisY = false;
private boolean onTouch = false;
private int widthFather = 0, heightFather = 0, widthMiddleFather = 0, heightMiddleFather = 0;
private MainActivity mainActivity;
private static int left, top;
public SensorManager sensorManager;
public Sensor accelerometer;
protected enum HorizontalDirection {
LEFT, RIGHT
}
protected enum VerticalDirection {
UP, DOWN
}
protected HorizontalDirection myXDirection = HorizontalDirection.RIGHT;
protected VerticalDirection myYDirection = VerticalDirection.UP;
public Thread bounce = null;
public Thread randomly = null;
public boolean interruptBounce = false;
public boolean interruptRandomly = false;
public RelativeLayout playerView;
public KatbagDrawing(Context context) {
super(context);
v = this;
this.mainActivity = (MainActivity) context;
}
public void setSizeFather(int wf, int hf, int[] loc, RelativeLayout player) {
widthFather = wf;
heightFather = hf;
widthMiddleFather = (wf / 2);
heightMiddleFather = (hf / 2);
this.loc = loc;
playerView = player;
}
public void getMySize() {
Log.d("getMySize", "w:" + getMyWidth() + " h:" + getMyHeight());
}
public void setMySize(int w, int h) {
myWidth = w;
myHeight = h;
myMiddleWidth = (w / 2);
myMiddleHeight = (h / 2);
leftMax = widthFather - ((w / 4) * 3);
topMax = heightFather - ((h / 4) * 3);
leftMin = -(w / 4);
topMin = -(h / 4);
leftColl = (w / 4);
topColl = (h / 4);
}
public int getMyWidth() {
return myWidth;
}
public int getMyHeight() {
return myHeight;
}
public void moveSteps(final int nSteps) {
final int s;
if (nSteps != 0) {
s = 10 * nSteps;
int left = v.getLeft() + s;
if (left > leftMax)
left = leftMax;
if (left < leftMin)
left = leftMin;
RelativeLayout.LayoutParams lp = (RelativeLayout.LayoutParams) v.getLayoutParams();
lp.leftMargin = left;
v.setLayoutParams(lp);
Log.d("moveSteps", "s:" + s);
}
}
public void moveToXY(int left, int top) {
if (left > leftMax)
left = leftMax;
if (left < leftMin)
left = leftMin;
if (top > topMax)
top = topMax;
if (top < topMin)
top = topMin;
RelativeLayout.LayoutParams lp = (RelativeLayout.LayoutParams) v.getLayoutParams();
lp.leftMargin = left;
lp.topMargin = top;
v.setLayoutParams(lp);
}
public void moveOnlyAxisY() {
moveOnlyAxisY = true;
v.setOnTouchListener(this);
}
public void moveOnlyAxisX() {
moveOnlyAxisX = true;
v.setOnTouchListener(this);
}
public void moveToCenter() {
int left = widthMiddleFather - myMiddleWidth;
int top = heightMiddleFather - myMiddleHeight;
RelativeLayout.LayoutParams lp = (RelativeLayout.LayoutParams) v.getLayoutParams();
lp.leftMargin = left;
lp.topMargin = top;
v.setLayoutParams(lp);
}
public void moveWithAccelerometer() {
sensorManager = (SensorManager) mainActivity.context.getSystemService(Context.SENSOR_SERVICE);
accelerometer = sensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);
sensorManager.registerListener(this, accelerometer, SensorManager.SENSOR_DELAY_FASTEST);
}
public void changeXforN(int left) {
if (left > leftMax)
left = leftMax;
if (left < leftMin)
left = leftMin;
RelativeLayout.LayoutParams lp = (RelativeLayout.LayoutParams) v.getLayoutParams();
lp.leftMargin = left;
v.setLayoutParams(lp);
}
public void changeYforN(int top) {
if (top > topMax)
top = topMax;
if (top < topMin)
top = topMin;
RelativeLayout.LayoutParams lp = (RelativeLayout.LayoutParams) v.getLayoutParams();
lp.topMargin = top;
v.setLayoutParams(lp);
}
public void moveAutomatic() {
if (bounce == null) {
bounce = new Thread(new Runnable() {
@Override
public void run() {
while (!Thread.interrupted() && !interruptBounce) {
try {
Thread.sleep(10);
mainActivity.runOnUiThread(new Runnable() {
@Override
public void run() {
left = v.getLeft();
top = v.getTop();
if (left >= leftMax)
myXDirection = HorizontalDirection.LEFT;
else if (left <= leftMin)
myXDirection = HorizontalDirection.RIGHT;
if (top >= topMax)
myYDirection = VerticalDirection.UP;
else if (top <= topMin)
myYDirection = VerticalDirection.DOWN;
if (myXDirection == HorizontalDirection.RIGHT)
left += 5;
else
left -= 5;
if (myYDirection == VerticalDirection.DOWN)
top += 5;
else
top -= 5;
if (!onTouch) {
RelativeLayout.LayoutParams lp = (RelativeLayout.LayoutParams) v.getLayoutParams();
lp.leftMargin = left;
lp.topMargin = top;
v.setLayoutParams(lp);
}
}
});
} catch (InterruptedException e) {
Log.w("moveAutomatic", "InterruptedException !!");
}
}
}
});
bounce.start();
}
}
public void moveRandomly() {
if (randomly == null) {
randomly = new Thread(new Runnable() {
@Override
public void run() {
while (!Thread.interrupted() && !interruptRandomly) {
try {
Thread.sleep(500);
mainActivity.runOnUiThread(new Runnable() {
@Override
public void run() {
left = v.getLeft();
top = v.getTop();
Random lf = new Random();
Random rg = new Random();
left = lf.nextInt(leftMax - leftMin + 1) + leftMin;
top = rg.nextInt(topMax - topMin + 1) + topMin;
if (!onTouch) {
RelativeLayout.LayoutParams lp = (RelativeLayout.LayoutParams) v.getLayoutParams();
lp.leftMargin = left;
lp.topMargin = top;
v.setLayoutParams(lp);
}
}
});
} catch (InterruptedException e) {
Log.w("moveRandomly", "InterruptedException !!");
}
}
}
});
randomly.start();
}
}
public void cancelMotionWithAccelerometer() {
this.sensorManager.unregisterListener((SensorEventListener) this, accelerometer);
}
public void cancelMotionAutomatic() {
this.interruptBounce = true;
this.bounce.interrupt();
this.bounce = null;
}
public void cancelMotionRandomly() {
this.interruptRandomly = true;
this.randomly.interrupt();
this.randomly = null;
}
public void hide() {
v.setVisibility(View.GONE);
}
public void show() {
v.setVisibility(View.VISIBLE);
}
@Override
public boolean onTouch(View v, MotionEvent event) {
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
onTouch = true;
leftIni = (int) event.getRawX() - (loc[0] + v.getLeft());
topIni = (int) event.getRawY() - (loc[1] + v.getTop());
break;
case MotionEvent.ACTION_UP:
onTouch = false;
break;
case MotionEvent.ACTION_MOVE:
onTouch = true;
int left = (int) event.getRawX() - (loc[0] + leftIni);
int top = (int) event.getRawY() - (loc[1] + topIni);
if (left < leftMin)
left = leftMin;
if (top < topMin)
top = topMin;
if (left > leftMax)
left = leftMax;
if (top > topMax)
top = topMax;
if (moveOnlyAxisX && moveOnlyAxisY) {
} else {
if (moveOnlyAxisX)
top = v.getTop();
if (moveOnlyAxisY)
left = v.getLeft();
}
RelativeLayout.LayoutParams lp = (RelativeLayout.LayoutParams) v.getLayoutParams();
lp.leftMargin = left;
lp.topMargin = top;
v.setLayoutParams(lp);
super.invalidate();
break;
}
if (moveOnlyAxisX || moveOnlyAxisY)
return true;
else
return false;
}
@Override
public void onAccuracyChanged(Sensor sensor, int accuracy) {
// TODO Auto-generated method stub
}
@Override
public void onSensorChanged(SensorEvent event) {
synchronized (this) {
if (event.sensor.getType() == Sensor.TYPE_ACCELEROMETER) {
left = v.getLeft();
top = v.getTop();
if (MainActivity.TABLET) { // landscape
if (event.values[1] > 0) {
if (left <= leftMax)
left = left + (int) Math.pow(event.values[1], 2);
} else {
if (left >= leftMin)
left = left - (int) Math.pow(event.values[1], 2);
}
if (event.values[0] > 0) {
if (top <= topMax)
top = top + (int) Math.pow(event.values[0], 2);
} else {
if (top >= topMin)
top = top - (int) Math.pow(event.values[0], 2);
}
} else { // portrait
if (event.values[0] < 0) {
if (left <= leftMax)
left = left + (int) Math.pow(event.values[0], 2);
} else {
if (left >= leftMin)
left = left - (int) Math.pow(event.values[0], 2);
}
if (event.values[1] > 0) {
if (top <= topMax)
top = top + (int) Math.pow(event.values[1], 2);
} else {
if (top >= topMin)
top = top - (int) Math.pow(event.values[1], 2);
}
}
if (!onTouch) {
RelativeLayout.LayoutParams lp = (RelativeLayout.LayoutParams) v.getLayoutParams();
lp.leftMargin = left;
lp.topMargin = top;
v.setLayoutParams(lp);
super.invalidate();
}
}
}
}
public int collisionDetection() {
Rect other = new Rect();
Rect iAm = new Rect();
int left = 0, top = 0, right = 0, bottom = 0;
left = (v.getLeft() - leftColl);
top = (v.getTop() - topColl);
right = (left + (getMyWidth() - leftColl));
bottom = (top + (getMyHeight() - topColl));
iAm.set(left, top, right, bottom);
int idDrw = -1;
for (int i = 0; i < playerView.getChildCount(); i++) {
KatbagDrawing drw = (KatbagDrawing) playerView.getChildAt(i);
if (drw.getId() != getId()) {
left = (drw.getLeft() - drw.leftColl);
top = (drw.getTop() - drw.topColl);
right = (left + (drw.getMyWidth() - drw.leftColl));
bottom = (top + (drw.getMyHeight() - drw.topColl));
other.set(left, top, right, bottom);
if (iAm.intersect(other))
idDrw = drw.getId();
}
}
Log.d("collisionDetection", "idDrw:" + idDrw);
return idDrw;
}
}