package com.sharkable.sharkengine;

import android.app.Activity;
import android.content.Context;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageManager;
import android.content.pm.PackageManager.NameNotFoundException;
import android.content.res.AssetManager;
import android.opengl.GLSurfaceView;
import android.os.Bundle;
import android.util.Log;
import android.view.MotionEvent;
import android.view.Window;
import android.view.WindowManager;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.microedition.khronos.egl.EGLConfig;
import javax.microedition.khronos.opengles.GL10;

import com.sharkable.sharkengine.modules.LocalStoreAndroid;

public class SharkengineActivity extends Activity {
  private GLSurfaceView mGLView;

  static {
      System.loadLibrary("sharkengine");
  }

  @Override
  protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    requestWindowFeature(Window.FEATURE_NO_TITLE);
    getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
                         WindowManager.LayoutParams.FLAG_FULLSCREEN);
    mGLView = new DemoGLSurfaceView(this);
    setContentView(mGLView);
  }
  
  @Override
  protected void onPause() {
    super.onPause();
    mGLView.onPause();
  }

  @Override
  protected void onResume() {
    super.onResume();
    mGLView.onResume();
  }
}

class DemoGLSurfaceView extends GLSurfaceView {
  private DemoRenderer mRenderer;
  private int mMeasuredWidth;

  public DemoGLSurfaceView(Context context) {
    super(context);
    mRenderer = new DemoRenderer(context);
    setRenderer(mRenderer);
  }

  @Override
  protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
     mMeasuredWidth = MeasureSpec.getSize(widthMeasureSpec);
     int measuredHeight = MeasureSpec.getSize(heightMeasureSpec);
     this.setMeasuredDimension(mMeasuredWidth, measuredHeight);
     int screenHeight = 640 * measuredHeight / mMeasuredWidth;
     getHolder().setFixedSize(640, screenHeight);
  }

  public boolean onTouchEvent(final MotionEvent event) {
    int action = event.getActionMasked();

    if (action == MotionEvent.ACTION_MOVE) {
      for (int i = 0; i < event.getPointerCount(); i++) {
        int id = event.getPointerId(i);
        double x = event.getX(i) * 640.0 / mMeasuredWidth;
        double y = event.getY(i) * 640.0 / mMeasuredWidth;
        nativeTouch(id, 2, x, y);
      }
    } else {
      int index = event.getActionIndex();
      int id = event.getPointerId(index);
      double x = event.getX(index) * 640.0 / mMeasuredWidth;
      double y = event.getY(index) * 640.0 / mMeasuredWidth;
      if (action == MotionEvent.ACTION_DOWN || action == MotionEvent.ACTION_POINTER_DOWN) {
        nativeTouch(id, 0, x, y);
      } else if (action == MotionEvent.ACTION_UP || action == MotionEvent.ACTION_POINTER_UP) {
        nativeTouch(id, 1, x, y);
      }
    }
    return true;
  }

  private native void nativeTouch(int touchId, int action, double x, double y);
  private native void nativePause();
}

class DemoRenderer implements GLSurfaceView.Renderer {
  private Context mContext;
  private boolean mDidInit = false;
  private LocalStoreAndroid mLocalStoreJava;

  public DemoRenderer(Context context) {
    mContext = context;
    mLocalStoreJava = new LocalStoreAndroid(context);
  }

  public void onSurfaceCreated(GL10 gl, EGLConfig config) {
  }

  public void onSurfaceChanged(GL10 gl, int w, int h) {
    assert !mDidInit;

    // return apk file path (or null on error)
    String apkFilePath = null;
    ApplicationInfo appInfo = null;
    PackageManager packMgmr = mContext.getPackageManager();
    try {
      appInfo = packMgmr.getApplicationInfo("com.sharkable.sharkengine", 0);
    } catch (NameNotFoundException e) {
      Log.e("Sharkable", "failed to find package");
      e.printStackTrace();
      throw new RuntimeException("Unable to locate assets, aborting...");
    }
    apkFilePath = appInfo.sourceDir;
    nativeInit(mLocalStoreJava, mContext.getAssets(), apkFilePath, w, h);
    mDidInit = true;
  }

  public void onDrawFrame(GL10 gl) {
    nativeRender();
  }

  private native void nativeInit(LocalStoreAndroid localStoreJava, AssetManager assetManager,
                                 String apkPath, int w, int h);
  private native void nativeRender();
  private native void nativeDone();
}

@@ -2097,24 +2097,57 @@
 nt event) %7B%0A
+    synchronized (mRenderer) %7B%0A  
     int acti
@@ -2173,24 +2173,26 @@
 nMasked();%0A%0A
+  
     if (acti
@@ -2230,16 +2230,18 @@
 %7B%0A      
+  
 for (int
@@ -2280,24 +2280,26 @@
 t(); i++) %7B%0A
+  
         int 
@@ -2330,24 +2330,26 @@
 i);%0A        
+  
 double x = e
@@ -2379,32 +2379,34 @@
 mMeasuredWidth;%0A
+  
         double y
@@ -2448,32 +2448,34 @@
 dWidth;%0A        
+ 
+ 
 nativeTouch(id, 
@@ -2486,26 +2486,30 @@
 , y);%0A      
-%7D%0A
+  %7D%0A  
     %7D else %7B
@@ -2511,24 +2511,26 @@
 lse %7B%0A      
+  
 int index = 
@@ -2549,24 +2549,26 @@
 ionIndex();%0A
+  
       int id
@@ -2599,24 +2599,26 @@
 dex);%0A      
+ 
+ 
 double x = e
@@ -2656,24 +2656,26 @@
 suredWidth;%0A
+  
       double
@@ -2725,24 +2725,26 @@
 idth;%0A      
+ 
+ 
 if (action =
@@ -2817,32 +2817,34 @@
 DOWN) %7B%0A        
+  
 nativeTouch(id, 
@@ -2849,24 +2849,26 @@
 , 0, x, y);%0A
+  
       %7D else
@@ -2950,32 +2950,34 @@
 R_UP) %7B%0A        
+  
 nativeTouch(id, 
@@ -2996,16 +2996,22 @@
     
+  
 %7D%0A    
+ 
+ 
 %7D%0A
+  
     
@@ -3019,24 +3019,30 @@
 eturn true;%0A
+    %7D%0A
   %7D%0A%0A  priva
@@ -4217,24 +4217,52 @@
 (GL10 gl) %7B%0A
+    synchronized (this) %7B%0A  
     nativeRe
@@ -4265,24 +4265,30 @@
 veRender();%0A
+    %7D%0A
   %7D%0A%0A  priva

Fix threading issues for touch.