package gamelogic;
import gui.SimpleCustomView;
import util.ImageTransform;
import worldData.Entity;
import worldData.Updateable;
import worldData.Visitor;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.PorterDuff;
import android.graphics.PorterDuffXfermode;
import android.graphics.RectF;
import android.graphics.Xfermode;
import android.util.AttributeSet;
import android.util.Log;
import de.rwth.R;
public class GameElementView extends SimpleCustomView implements Entity {
private static final int DEFAULT_MAX_WIDTH_IN_DIP = 80;
private static final float DEFAULT_EDITOR_MAX_WIDTH_IN_DIP = 180;
private static final String LOG_TAG = "GameElementView";
private Paint paint;
private Paint loadingPaint;
private Paint loadingLinePaint;
float myLoadingAngle = 0;
private Bitmap myIcon;
private Bitmap mutable;
private Canvas stampCanvas;
private int myWidth;
private int myHeight;
private Xfermode myXfermode;
private RectF arcRect;
private int myMaxWidth;
// private String debug;
public GameElementView(Context context, int iconid) {
super(context);
init((int) dipToPixels(DEFAULT_MAX_WIDTH_IN_DIP),
loadBitmapFromId(context, iconid));
}
@Deprecated
public GameElementView(Context context, AttributeSet attrs) {
super(context, attrs);
init((int) dipToPixels(DEFAULT_EDITOR_MAX_WIDTH_IN_DIP),
loadBitmapFromId(context, R.drawable.hippopotamus64));
}
public void setIcon(Bitmap icon) {
myIcon = icon;
resizeIconToViewSize();
}
private void resizeIconToViewSize() {
if (myIcon != null) {
myIcon = ImageTransform.resizeBitmap(myIcon, myHeight, myWidth);
myIcon = ImageTransform.createBitmapWithRoundCorners(myIcon, 8f);
}
}
private void drawLoadingCircle(Canvas canvas, Paint paint) {
if (myLoadingAngle != 0 && myLoadingAngle != 360) {
// Draw the Minutes-Arc into that rectangle
canvas.drawArc(arcRect, -90, myLoadingAngle, true, paint);
}
}
private void init(int maxWidth, Bitmap icon) {
paint = new Paint();
myXfermode = new PorterDuffXfermode(PorterDuff.Mode.DST_IN);
loadingPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
loadingPaint.setColor(Color.RED);
loadingPaint.setAlpha(100);
loadingLinePaint = new Paint();
loadingLinePaint = new Paint(Paint.ANTI_ALIAS_FLAG);
loadingLinePaint.setColor(Color.BLACK);
loadingLinePaint.setStyle(Paint.Style.STROKE);
loadingLinePaint.setStrokeWidth(3);
myMaxWidth = maxWidth;
setSize(maxWidth, icon);
if (isInEditMode())
loadDemoValues();
setIcon(icon);
}
public void setSize(int newWidth, Bitmap icon) {
myWidth = newWidth;
if (myWidth > myMaxWidth)
myWidth = myMaxWidth;
if (icon != null) {
myHeight = (int) ((float) (icon.getHeight())
/ (float) (icon.getWidth()) * (float) (myWidth));
} else {
myHeight = myWidth;
}
Log.w(LOG_TAG, "New height=" + myHeight);
Log.w(LOG_TAG, "New width=" + myWidth);
if (myHeight <= 0 || myWidth <= 0) {
Log.e(LOG_TAG, "height or width were 0!");
Log.w(LOG_TAG, " > icon=" + icon);
Log.w(LOG_TAG, " > icon.getHeight()=" + icon.getHeight());
Log.w(LOG_TAG, " > icon.getWidth()=" + icon.getWidth());
Log.w(LOG_TAG, " > recommendedWidth=" + newWidth);
showDebugInfos();
}
float x = myWidth * 0.5f;
arcRect = new RectF(-x, -x, myWidth + x, myHeight + x);
mutable = Bitmap.createBitmap(myWidth, myHeight,
Bitmap.Config.ARGB_8888);
stampCanvas = new Canvas(mutable);
resizeIconToViewSize();
}
public void showDebugInfos() {
Log.w(LOG_TAG, " > myHeight=" + myHeight);
Log.w(LOG_TAG, " > myWidth=" + myWidth);
Log.w(LOG_TAG, " > myIcon=" + myIcon);
Log.w(LOG_TAG, " > myLoadingAngle=" + myLoadingAngle);
}
/**
* This method will only be called when the view is displayed in the eclipse
* xml layout editor
*/
private void loadDemoValues() {
setLoadingAngle(160);
}
public void setLoadingAngle(float myLoadingAngle) {
this.myLoadingAngle = myLoadingAngle;
this.postInvalidate();
}
@Override
public void onResizeEvent(int recommendedHeight, int recommendedWidth) {
int min = Math.min(recommendedHeight, recommendedHeight);
Log.i(LOG_TAG, "New recommended width=" + recommendedWidth);
Log.i(LOG_TAG, "New recommended heigth=" + recommendedHeight);
Log.d(LOG_TAG, "Choosen minimum=" + min);
setSize(min, myIcon);
setMeasuredDimension(myWidth, myHeight);
}
@Override
protected void onDraw(Canvas onDrawCanvas) {
// stampCanvas.drawARGB(0, 0, 0, 0);
stampCanvas.drawBitmap(myIcon, 0, 0, paint);
// Bitmap i2 = generateDebugImage2(getContext());
// canvas.drawBitmap(i2, 0, 0, paint);
drawLoadingCircle(stampCanvas, loadingPaint);
drawLoadingCircle(stampCanvas, loadingLinePaint);
paint.setXfermode(myXfermode);
stampCanvas.drawBitmap(myIcon, 0, 0, paint);
paint.setXfermode(null);
onDrawCanvas.drawBitmap(mutable, 0, 0, paint);
// if (debug != null) { // TODO remove this
// paint.setColor(Color.RED);
// canvas.drawText(debug, 0, myHalfSize, paint);
// }
}
// @Override
// public boolean onTouchEvent(MotionEvent event) {
// return onTouch(event.getX() - myHalfWidth, event.getY() - myHalfHeight);
// }
//
// private boolean onTouch(float x, float y) {
// double distFromCenter = Math.sqrt(x * x + y * y);
// distFromCenter *= myTouchScaleFactor;
// setLoadingAngle((float) (Math.random() * 359));
// postInvalidate();
// return true;
// }
@Override
public boolean update(float timeDelta, Updateable parent) {
if (parent instanceof GameAction) {
GameAction a = (GameAction) parent;
float prog = a.getCooldownProgress();
float max = a.getCooldownTime();
if (prog != Float.NaN && max != Float.NaN) {
if (prog + timeDelta < max) {
a.setCooldownProgress(prog + timeDelta);
this.setLoadingAngle((prog + timeDelta) / max * 360);
} else {
a.setCooldownProgress(max);
this.setLoadingAngle(360);
}
} else {
Log.e(LOG_TAG, "The parent action has not the required values");
this.setLoadingAngle(360);
}
}
/*
* TODO if view was removed from parent it can return false here!
*/
return true;
}
@Override
public Updateable getMyParent() {
Log.e(LOG_TAG, "Get parent called which is not "
+ "implemented for this component!");
return null;
}
@Override
public void setMyParent(Updateable parent) {
// can't have children so the parent does not have to be stored
Log.e(LOG_TAG, "Set parent called which is not "
+ "implemented for this component!");
}
@Override
public boolean accept(Visitor visitor) {
return false;
}
}