gt: 				long curTime = System.currentTimeMillis();
context: /********************************************************************** 
   Android-Freeciv - Copyright (C) 2010 - C Vaughn
     This program is free software; you can redistribute it and/or modify
     it under the terms of the GNU General Public License as published by
     the Free Software Foundation; either version 2, 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 General Public License for more details.
  ***********************************************************************/
  
  package net.hackcasual.freeciv.views;
  
  import java.nio.ByteBuffer;
  import java.util.List;
  import java.util.concurrent.BlockingQueue;
  import java.util.concurrent.LinkedBlockingQueue;
  import java.util.concurrent.Semaphore;
  
  import net.hackcasual.freeciv.CityPresentUnitAdapter;
  import net.hackcasual.freeciv.Civ;
  import net.hackcasual.freeciv.DialogManager;
  import net.hackcasual.freeciv.NativeHarness;
  import net.hackcasual.freeciv.NativeHarness.AvailableCommand;
  import net.hackcasual.freeciv.Settings;
  
  import net.hackcasual.freeciv.R;
  import net.hackcasual.freeciv.R.id;
  import net.hackcasual.freeciv.R.layout;
  import net.hackcasual.freeciv.models.*;
  
  import android.app.Activity;
  import android.app.AlertDialog;
  import android.content.ComponentName;
  import android.content.Context;
  import android.content.DialogInterface;
  import android.content.Intent;
  import android.content.res.Configuration;
  import android.graphics.Bitmap;
  import android.graphics.Canvas;
  import android.graphics.Paint;
  import android.graphics.drawable.BitmapDrawable;
  import android.graphics.drawable.ScaleDrawable;
  import android.os.Bundle;
  import android.os.Handler;
  import android.os.Vibrator;
  import android.util.DisplayMetrics;
  import android.util.Log;
  import android.view.Display;
  import android.view.GestureDetector;
  import android.view.Menu;
  import android.view.MenuItem;
  import android.view.MotionEvent;
  import android.view.SubMenu;
  import android.view.TouchDelegate;
  import android.view.View;
  import android.view.ViewGroup;
  import android.view.Window;
  import android.view.WindowManager;
  import android.view.View.OnClickListener;
  import android.view.View.OnTouchListener;
  import android.widget.AdapterView;
  import android.widget.AdapterView.OnItemClickListener;
  import android.widget.AdapterView.OnItemSelectedListener;
  import android.widget.ImageView;
  import android.widget.LinearLayout;
  import android.widget.ListView;
  import android.widget.TextView;
  import android.widget.Toast;
  
  public class Freeciv extends NativeAwareActivity {
  	NativeHarness nh;
  	List<AvailableCommand> currentOptions;
  	DialogManager dm;
  	static Bitmap mapView;
  	boolean unitMenu = false;
  	long tsBuf[] = new long[10];
  	int tsi = -1, tsc = 0;
  	AlertDialog overviewDialog;
  	boolean isPaused;
  	int lastSavedTurn;
  	GestureDetector gestures;
  	MotionEvent lastLongPress, lastMoveAfterLongPress;
  	
  	 DisplayMetrics metrics;
  	 
  	 
  	 public Freeciv() {
  		 metrics = new DisplayMetrics();
  	 }
  	 
  
  	
  	final BlockingQueue<MotionEvent> touchQueue = new LinkedBlockingQueue<MotionEvent>();
  	
  	public static Bitmap getMapView() {
  		return mapView;
  	}
  		
  	/** Called when the activity is first created. */
      @Override
      public void onCreate(Bundle savedInstanceState) {
          super.onCreate(savedInstanceState);
          
          Settings.updateSettings(this);
          
  		getWindowManager().getDefaultDisplay().getMetrics(metrics);
  		requestWindowFeature(Window.FEATURE_NO_TITLE);
  		getWindow().addFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN);
          
      	setContentView(R.layout.main);
      	
          nh = ((Civ)(this.getApplication())).getNativeHarness();
  
          nh.getDialogManager().bindActivity(this);
          nh.setMainActivity(this);
        
          Display display = getWindowManager().getDefaultDisplay(); 
          int width = getMapWidth(display);
          int height = getMapHeight(display);;
          
          NativeHarness.init(width, height);
          
          mapView = Bitmap.createBitmap(width, height, Bitmap.Config.RGB_565);
          
          
          ((ImageView)findViewById(R.id.map_view)).setImageBitmap(mapView);
          ((ImageView)findViewById(R.id.map_view)).getDrawable().setFilterBitmap(false);
          
          final Freeciv me = this;
          
  
          
          /*(new Thread() {
          	public void run() {
          		MotionEvent toProcess = null;
          		while (true) {
          			try {
  	        			if (touchQueue.isEmpty()) {
  	        				toProcess = touchQueue.take();
  	        			} else {
  	        				while (!touchQueue.isEmpty()) {
  	        					toProcess = touchQueue.take();
  	        				}
  	        			}
  	        			
          			} catch (InterruptedException e) {
          				//Nothing
          			}
          			int unitCount = NativeHarness.touchEvent((int)toProcess.getX(), (int)toProcess.getY(), toProcess.getAction());
          			if (unitCount > 0) {
  	        			if (unitCount == 1) {
  	        				me.runOnUiThread(new Runnable() {
  								@Override
  								public void run() {
  			        				me.showUnitMenu();
  								}
  	        				});
  	        			} else {
  	        				final int x = (int)toProcess.getX();
  	        				final int y = (int)toProcess.getY();
  	        				me.runOnUiThread(new Runnable() {
  								@Override
  								public void run() {
  			        				me.showUnitSelection(x, y);
  								}
  	        				});	        				
  	        			}
          			}
          			
          		}
          	}
          }).start();*/
      }
      
      @Override
      public void onResume() {
      	super.onResume();
      	this.isPaused = false;
          
      	gestures = new GestureDetector (this, new MapViewGestureProcessor());
  
  
  
      	//nh.reloadMap();
      	//nh.updateDisplay();
      }
  
      @Override
      public void onPause() {
      	super.onPause();
      	Civ.saveGame(Civ.SaveType.FORCED);
      	this.isPaused = true;
      }    
      
      private void stopTrackingPushMove() {
  		lastLongPress = null;
  		lastMoveAfterLongPress = null;
      }
  
      private boolean isTrackingPushMove() {
  		return (lastLongPress != null && lastMoveAfterLongPress != null);
      }
  
      
      @Override
  	public boolean dispatchTouchEvent(MotionEvent event) {
      	if (event.getAction() == MotionEvent.ACTION_MOVE && lastLongPress != null) {
      		NativeHarness.showCursorAt((int)event.getX() / 2, (int)event.getY() / 2);
      		lastMoveAfterLongPress = event;
      		return true;
      	} else if (isTrackingPushMove() && event.getAction() == MotionEvent.ACTION_DOWN &&
      		Math.abs(event.getX() - lastMoveAfterLongPress.getX()) < 40 && Math.abs(event.getY() - lastMoveAfterLongPress.getY()) < 40) {
      		//Resume moving the selector
      		return gestures.onTouchEvent(event);
      	} else if (event.getAction() != MotionEvent.ACTION_UP){
      		stopTrackingPushMove();
      		NativeHarness.cancelAction();
      	}
      	
      	return gestures.onTouchEvent(event);
  	}
  	
  	public void showUnitMenu() {
  		unitMenu = true;
  		openOptionsMenu();
  		unitMenu = false;
  	}
  
  	public void showUnitSelection(int x, int y) {
  		AlertDialog.Builder builder = new AlertDialog.Builder(this);
  		
  		builder.setTitle("Choose Unit");
  		ListView units = new ListView(this);
  		units.setFocusable(true);
  		final CityPresentUnitAdapter adapter = new CityPresentUnitAdapter(this);
  		units.setAdapter(adapter);
  		//builder.setView(units);
  		
  		for (int i: NativeHarness.getUnitsOnTile(x, y)) {
  			adapter.add(NativeHarness.getUnitById(i));
  		}
  
  		builder.setView(units);
  		final AlertDialog shown = builder.create();		
  		units.setOnItemClickListener(new OnItemClickListener() {
  
  			@Override
  			public void onItemClick(AdapterView<?> arg0, View arg1, int pos,
  					long arg3) {
  				nh.focusOnUnit(adapter.getItem(pos).getUnitId());
  				shown.dismiss();
  				unitMenu = true;
  				openOptionsMenu();
  				unitMenu = false;
  				
  			}
  			
  		});
  
  		
  
  		shown.show();
  
  	}
  
  	public void updateMapview(final ByteBuffer image, final Semaphore renderLock) {
  		
  		/*if (this.isPaused) {
  			renderLock.release();
  			return;
  		}*/
  		
  		Log.i("Freeciv", String.format("Updating mapview on thread: %d", Thread.currentThread().getId()));
  		
  		this.runOnUiThread(new Runnable() {
  
  			@Override
  			public void run() {
  				Log.i("Freeciv", String.format("In UI thread %d", Thread.currentThread().getId()));
  				
  				image.rewind();
  				mapView.copyPixelsFromBuffer(image);
  				((ImageView)findViewById(R.id.map_view)).setImageBitmap(mapView);
  				((ImageView)findViewById(R.id.map_view)).getDrawable().setFilterBitmap(false);
  				//renderLock.release();
  				Log.i("Freeciv", "gui thread released lock");
  			}
  		
  		});
  	}
  	
  	void runExercise(final Activity that) {
  		Thread t = new Thread() {
  
  			@Override
  			public void run() {
  				try {
  					Thread.sleep(1000);
  				} catch (InterruptedException e) {
  					// TODO Auto-generated catch block
  					e.printStackTrace();
  				}
  				
  				Log.i("Freeciv", "Running exercise1");
  				
  